public override void OutADeconstructorDecl(ADeconstructorDecl node) { //If void return is missing, insert it. AABlock block = (AABlock)node.GetBlock(); bool insertReturn = false; while (true) { if (block.GetStatements().Count == 0) { insertReturn = true; break; } PStm lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1]; if (lastStm is AVoidReturnStm) break; if (lastStm is ABlockStm) { block = (AABlock)((ABlockStm)block.GetStatements()[block.GetStatements().Count - 1]).GetBlock(); continue; } insertReturn = true; break; } if (insertReturn) { block.GetStatements().Add(new AVoidReturnStm(new TReturn("return", block.GetToken().Line, block.GetToken().Pos))); } //Must be no parameters if (node.GetFormals().Count > 0) { errors.Add(new ErrorCollection.Error(node.GetName(), LocRM.GetString("ErrorText193"))); } if (node.GetVisibilityModifier() is AProtectedVisibilityModifier && Util.HasAncestor<AEnrichmentDecl>(node)) { errors.Add(new ErrorCollection.Error(node.GetName(), LocRM.GetString("ErrorText194"))); } base.OutADeconstructorDecl(node); }
public override void CaseADeconstructorDecl(ADeconstructorDecl node) { InADeconstructorDecl(node); if (node.GetBlock() != null) { node.GetBlock().Apply(this); } { Object[] temp = new Object[node.GetFormals().Count]; node.GetFormals().CopyTo(temp, 0); for (int i = temp.Length - 1; i >= 0; i--) { ((PLocalDecl)temp[i]).Apply(this); } } if (node.GetName() != null) { node.GetName().Apply(this); } if (node.GetVisibilityModifier() != null) { node.GetVisibilityModifier().Apply(this); } OutADeconstructorDecl(node); }
/*private class IsThisOnLeftSide : DepthFirstAdapter { private PType type; private SharedData data; public bool IsAssignedTo; private List<AMethodDecl> investigatedMethods = new List<AMethodDecl>(); public IsThisOnLeftSide(PType type, SharedData data) { this.type = type; this.data = data; } //Check assignments, method invocations and nonstatic method invocations. public override void CaseAMethodDecl(AMethodDecl node) { investigatedMethods.Add(node); } public override void CaseAThisLvalue(AThisLvalue node) { if (IsAssignedTo) return; Node iParent = GetClosestNodeOfType(node, typeof (AAssignmentExp), typeof (ASimpleInvokeExp), typeof (ANonstaticInvokeExp), typeof (AAsyncInvokeStm), typeof (ASyncInvokeExp), typeof(AArrayLvalue), typeof(APointerLvalue), typeof(APropertyLvalue), typeof(AStructLvalue)); if (iParent == null) return; if (iParent is AAssignmentExp) { AAssignmentExp aParent = (AAssignmentExp) iParent; if (Util.IsAncestor(node, aParent.GetLvalue())) { IsAssignedTo = true; } return; } if (iParent is ASimpleInvokeExp) { ASimpleInvokeExp aParent = (ASimpleInvokeExp) iParent; AMethodDecl method = data.SimpleMethodLinks[aParent]; if (investigatedMethods.Contains(method)) return; if (Util.IsAncestor(node, aParent.GetLvalue())) { IsAssignedTo = true; } return; } } private Node GetClosestNodeOfType(Node node, params Type[] types) { if (node == null) return null; if (types.Contains(node.GetType())) return node; return GetClosestNodeOfType(node.Parent(), types); } }*/ public override void CaseADeconstructorDecl(ADeconstructorDecl node) { AStructDecl str = Util.GetAncestor<AStructDecl>(node); AEnrichmentDecl enrichment = Util.GetAncestor<AEnrichmentDecl>(node); AMethodDecl replacer = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new AVoidType(new TVoid("void")), node.GetName(), new ArrayList(), node.GetBlock()); replacer.GetName().Text += "_Deconstructor"; //Move the method outside the struct AASourceFile file = Util.GetAncestor<AASourceFile>(node); if (str != null) str.RemoveChild(node.Parent()); /*else enrichment.RemoveChild(node);*/ int i = file.GetDecl().IndexOf(str ?? (PDecl)enrichment); file.GetDecl().Insert(i/* + 1*/, replacer); //Add the struct as a parameter PType type; if (str != null) { ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; type = structType; } else { type = Util.MakeClone(enrichment.GetType(), finalTrans.data); } finalTrans.data.DeconstructorMap[node] = replacer; AALocalDecl structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), type), new TIdentifier("currentStruct", replacer.GetName().Line, replacer.GetName().Pos), null); replacer.GetFormals().Add(structFormal); finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, replacer)); //Call base deconstructor before each return if (str != null && str.GetBase() != null) { AStructDecl baseStruct = data.StructTypeLinks[(ANamedType) str.GetBase()]; if (data.StructDeconstructor.ContainsKey(baseStruct)) { baseStruct.Apply(this); replacer.Apply(new CallDeconstructors(baseStruct, structFormal, data)); /*AMethodDecl baseDeconstructor = data.DeconstructorMap[data.StructDeconstructor[baseStruct]]; ALocalLvalue structFormalRef = new ALocalLvalue(new TIdentifier("currentStruct")); ALvalueExp structFormalRefExp = new ALvalueExp(structFormalRef); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("baseDeconstructor"), new ArrayList() {structFormalRefExp}); AABlock block = (AABlock) replacer.GetBlock(); block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), invoke)); data.LocalLinks[structFormalRef] = structFormal; data.SimpleMethodLinks[invoke] = baseDeconstructor; data.LvalueTypes[structFormalRef] = data.ExpTypes[structFormalRefExp] = structFormal.GetType(); data.ExpTypes[invoke] = baseDeconstructor.GetReturnType();*/ } } this.structFormal = structFormal; base.CaseAMethodDecl(replacer); }