public override void CaseANewExp(ANewExp node) { InANewExp(node); { Object[] temp = new Object[node.GetArgs().Count]; node.GetArgs().CopyTo(temp, 0); for (int i = temp.Length - 1; i >= 0; i--) { ((PExp)temp[i]).Apply(this); } } if (node.GetType() != null) { node.GetType().Apply(this); } if (node.GetToken() != null) { node.GetToken().Apply(this); } OutANewExp(node); }
public override void OutANewExp(ANewExp node) { /*if (node.GetType() is AArrayTempType) data.ExpTypes[node] = node.GetType(); else*/ data.ExpTypes[node] = new APointerType(new TStar("*"), Util.MakeClone(node.GetType(), data)); List<AEnrichmentDecl> enrichments = new List<AEnrichmentDecl>(); List<IList> visibleDecls = Util.GetVisibleDecls(node, true); foreach (IList declList in visibleDecls) { foreach (PDecl decl in declList) { if (decl is AEnrichmentDecl) { AEnrichmentDecl enrichment = (AEnrichmentDecl) decl; if (!Util.TypesEqual(node.GetType(), enrichment.GetType(), data)) continue; enrichments.Add(enrichment); } } } if (enrichments.Count > 0 || node.GetType() is ANamedType) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); ANamedType type = (ANamedType) node.GetType(); if (enrichments.Count > 0 || data.StructTypeLinks.ContainsKey(type)) { //Find matching constructor //Token token; List<AConstructorDecl> candidates = new List<AConstructorDecl>(); if (enrichments.Count == 0) { AStructDecl str = data.StructTypeLinks[type]; if (data.Enums.ContainsKey(str)) { errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText138"), false, new ErrorCollection.Error(str.GetName(), LocRM.GetString("ErrorText139")))); } //token = str.GetName(); subErrors.Add(new ErrorCollection.Error(str.GetName(), LocRM.GetString("ErrorText48") + Util.GetTypeName(str))); foreach (AConstructorDecl constructorDecl in data.StructConstructors[str]) { //Visiblity if (constructorDecl.GetVisibilityModifier() is APrivateVisibilityModifier && Util.GetAncestor<AStructDecl>(constructorDecl) != Util.GetAncestor<AStructDecl>(node)) continue; if (constructorDecl.GetVisibilityModifier() is AProtectedVisibilityModifier && (!Util.HasAncestor<AStructDecl>(node) || !Util.Extends(Util.GetAncestor<AStructDecl>(constructorDecl), Util.GetAncestor<AStructDecl>(node), data))) continue; if (constructorDecl.GetFormals().Count == node.GetArgs().Count) { //Check that parameters are assignable bool add = true; for (int i = 0; i < node.GetArgs().Count; i++) { PType argType = data.ExpTypes[(PExp)node.GetArgs()[i]]; AALocalDecl formal = (AALocalDecl)constructorDecl.GetFormals()[i]; PType formalType = formal.GetType(); if (formal.GetOut() != null && !Assignable(formalType, argType) || formal.GetRef() != null && !(Assignable(argType, formalType) && Assignable(formalType, argType)) || formal.GetOut() == null && formal.GetRef() == null && !Assignable(argType, formalType)) { add = false; break; } } if (add) candidates.Add(constructorDecl); } } } else { //token = null; foreach (AEnrichmentDecl enrich in enrichments) { //token = enrich.GetToken(); subErrors.Add(new ErrorCollection.Error(enrich.GetToken(), LocRM.GetString("ErrorText77"))); foreach (AConstructorDecl constructorDecl in enrich.GetDecl().OfType<AConstructorDecl>()) { //Visiblity if (constructorDecl.GetVisibilityModifier() is APrivateVisibilityModifier && Util.GetAncestor<AEnrichmentDecl>(constructorDecl) != Util.GetAncestor<AEnrichmentDecl>(node)) continue; if (constructorDecl.GetFormals().Count == node.GetArgs().Count) { //Check that parameters are assignable bool add = true; for (int i = 0; i < node.GetArgs().Count; i++) { PType argType = data.ExpTypes[(PExp) node.GetArgs()[i]]; AALocalDecl formal = (AALocalDecl) constructorDecl.GetFormals()[i]; PType formalType = formal.GetType(); if (formal.GetOut() != null && !Assignable(formalType, argType) || formal.GetRef() != null && !(Assignable(argType, formalType) && Assignable(formalType, argType)) || formal.GetOut() == null && formal.GetRef() == null && !Assignable(argType, formalType)) { add = false; break; } } if (add) candidates.Add(constructorDecl); } } } } if (candidates.Count == 0) { if (node.GetArgs().Count == 0 && enrichments.Count > 0) return; string msg = LocRM.GetString("ErrorText140"); foreach (PExp arg in node.GetArgs()) { if (msg.EndsWith("(")) msg += Util.TypeToString(data.ExpTypes[arg]); else msg += ", " + Util.TypeToString(data.ExpTypes[arg]); } msg += ")"; errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, msg, false, subErrors.ToArray()), true); return; } if (candidates.Count > 1) { subErrors = new List<ErrorCollection.Error>(); int i = 0; foreach (AConstructorDecl candidate in candidates) { i++; subErrors.Add(new ErrorCollection.Error(candidate.GetName(), LocRM.GetString("ErrorText141") + i)); } errors.Add( new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText142"), false, subErrors.ToArray()), true); return; } PStm pStm = Util.GetAncestor<PStm>(node); if (pStm == null) { if (Util.HasAncestor<AFieldDecl>(node)) { data.FieldsToInitInMapInit.Add(Util.GetAncestor<AFieldDecl>(node)); } else if (Util.HasAncestor<AStructDecl>(node)) { //Ignore - will be fixed } else errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText143"))); } data.ConstructorLinks.Add(node, candidates[0]); //For each formal marked as ref or out, the argument must be a variable for (int i = 0; i < node.GetArgs().Count; i++) { AALocalDecl formal = (AALocalDecl)candidates[0].GetFormals()[i]; if (formal.GetRef() != null || formal.GetOut() != null) { PExp exp = (PExp)node.GetArgs()[i]; while (true) { PLvalue lvalue; if (exp is ALvalueExp) { lvalue = ((ALvalueExp)exp).GetLvalue(); } else if (exp is AAssignmentExp) { lvalue = ((AAssignmentExp)exp).GetLvalue(); } else { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText130"))); break; } if (lvalue is ALocalLvalue || lvalue is AFieldLvalue || lvalue is AStructFieldLvalue) break; if (lvalue is AStructLvalue) { exp = ((AStructLvalue)lvalue).GetReceiver(); continue; } if (lvalue is AArrayLvalue) { exp = ((AArrayLvalue)lvalue).GetBase(); continue; } throw new Exception("Unexpected lvalue"); } } } return; } } //else if (node.GetArgs().Count > 0) { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText144"))); } }