예제 #1
0
        public override void OutADeconstructorDecl(ADeconstructorDecl node)
        {
            AStructDecl parentStruct = Util.GetAncestor <AStructDecl>(node);

            if (parentStruct != null)
            {
                if (data.StructDeconstructor.ContainsKey(parentStruct) && data.StructDeconstructor[parentStruct] != node)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(),
                                                         "You can only define one deconstructor in a " +
                                                         Util.GetTypeName(parentStruct) + ".", false,
                                                         new[]
                    {
                        new ErrorCollection.Error(
                            data.StructDeconstructor[parentStruct].GetName(),
                            "Other deconstructor")
                    }));
                }

                data.StructDeconstructor[parentStruct] = node;
                if (parentStruct.GetName().Text != node.GetName().Text)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile,
                                                         "Deconstructors must have same name as the enclosing struct."));
                }
            }
            base.OutADeconstructorDecl(node);
        }
예제 #2
0
            public override void CaseADeconstructorDecl(ADeconstructorDecl node)
            {
                End  = Start = TextPoint.FromCompilerCoords(node.GetName().Line, node.GetName().Pos);
                Name = node.GetName().Text;

                base.CaseADeconstructorDecl(node);
            }
예제 #3
0
        public override void OutADeconstructorDecl(ADeconstructorDecl node)
        {
            AStructDecl parentStruct = Util.GetAncestor <AStructDecl>(node);

            if (parentStruct != null)
            {
                if (data.StructDeconstructor.ContainsKey(parentStruct) && data.StructDeconstructor[parentStruct] != node)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(),
                                                         LocRM.GetString("ErrorText13") +
                                                         Util.GetTypeName(parentStruct) + ".", false,
                                                         new[]
                    {
                        new ErrorCollection.Error(
                            data.StructDeconstructor[parentStruct].GetName(),
                            LocRM.GetString("ErrorText15"))
                    }));
                }

                data.StructDeconstructor[parentStruct] = node;
                if (parentStruct.GetName().Text != node.GetName().Text)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile,
                                                         LocRM.GetString("ErrorText16")));
                }
            }
            base.OutADeconstructorDecl(node);
        }
예제 #4
0
        public MethodDescription(ADeconstructorDecl method)
        {
            Parser parser = new Parser(method);


            Start      = parser.Start;
            End        = parser.End;
            ReturnType = "void";
            Name       = parser.Name;
            Formals    = parser.Formals;
            Locals     = parser.Locals;
            if (method.Parent() != null)
            {
                method.Parent().RemoveChild(method);
            }
            while (method.GetFormals().Count > 0)
            {
                Decl.GetFormals().Add(method.GetFormals()[0]);
            }
            Visibility = method.GetVisibilityModifier();
            Position   = TextPoint.FromCompilerCoords(method.GetName());
        }
            public override void CaseADeconstructorDecl(ADeconstructorDecl node)
            {
                MethodDescription method = new MethodDescription(node);

                Deconstructors.Add(method);
            }
        /*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);
        }