public override void CaseAMethodDecl(AMethodDecl node)
        {
            if (node.GetInline() == null)
            {
                return;
            }

            //Variables marked as out can be made into ref
            foreach (AALocalDecl formal in node.GetFormals())
            {
                if (formal.GetOut() != null)
                {
                    formal.SetRef(new TRef("ref"));
                    formal.SetOut(null);
                }
            }
            assignedToLocals.Clear();
            base.CaseAMethodDecl(node);

            foreach (AALocalDecl formal in node.GetFormals())
            {
                if (!assignedToLocals.Contains(formal))
                {
                    formal.SetRef(new TRef("ref"));
                }
            }
        }
示例#2
0
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            Write("\n");
            if (node.GetStatic() != null)
            {
                Write("static ");
            }
            if (node.GetNative() != null)
            {
                Write("native ");
            }
            node.GetReturnType().Apply(this);
            Write(" " + node.GetName().Text + "(");
            bool first = true;

            foreach (AALocalDecl formal in node.GetFormals())
            {
                if (!first)
                {
                    Write(", ");
                }
                formal.Apply(this);
                first = false;
            }
            if (node.GetBlock() != null)
            {
                Write(")\n");
                node.GetBlock().Apply(this);
            }
            else
            {
                Write(");\n\n");
            }
        }
 public override void CaseALocalLvalue(ALocalLvalue node)
 {
     if (Util.HasAncestor <AMethodDecl>(node) &&                                         //Is in a method
         data.LocalLinks[node].Parent() == Util.GetAncestor <AMethodDecl>(node))         //Is a link to a formal in that method
     {
         if (Util.HasAncestor <AAssignmentExp>(node) &&                                  //Is in an assignement
             Util.IsAncestor(node, Util.GetAncestor <AAssignmentExp>(node).GetLvalue())) //Is left side of the assignment
         {
             AssignedFormals.Add(data.LocalLinks[node]);
         }
         else if (Util.HasAncestor <ASimpleInvokeExp>(node))
         {
             ASimpleInvokeExp invoke = Util.GetAncestor <ASimpleInvokeExp>(node);
             AMethodDecl      method = data.SimpleMethodLinks[invoke];
             for (int i = 0; i < invoke.GetArgs().Count; i++)
             {
                 AALocalDecl formal = (AALocalDecl)method.GetFormals()[i];
                 if ((formal.GetRef() != null || formal.GetOut() != null) && Util.IsAncestor(node, (Node)invoke.GetArgs()[i]))
                 {
                     AssignedFormals.Add(data.LocalLinks[node]);
                     return;
                 }
             }
         }
     }
 }
示例#4
0
        public override void CaseASimpleInvokeExp(ASimpleInvokeExp node)
        {
            AMethodDecl target = data.SimpleMethodLinks[node];

            for (int i = 0; i < node.GetArgs().Count; i++)
            {
                PExp arg = (PExp)node.GetArgs()[i];
                currentLocal = null;
                arg.Apply(this);
                if (currentLocal != null && target.GetFormals().Cast <AALocalDecl>().ToList()[i].GetRef() != null)
                {
                    ALocalLvalue local = currentLocal;
                    target.Apply(this);
                    if (target.GetFormals().Cast <AALocalDecl>().ToList()[i].GetRef() != null)
                    {
                        AALocalDecl decl = data.LocalLinks[local];
                        NeededRefs[Util.GetAncestor <AMethodDecl>(node)].Add(decl);
                    }
                }
            }
        }
示例#5
0
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            if (node.GetNative() == null && node.GetBlock() == null)
            {
                return;
            }
            if (node.GetStatic() != null)
            {
                return;
            }

            string inputStr = "native " + TypeToString(node.GetReturnType()) + " " + node.GetName().Text +
                              "(";
            bool first = true;

            foreach (AALocalDecl formal in node.GetFormals())
            {
                if (!first)
                {
                    inputStr += ", ";
                }
                inputStr += TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                first     = false;
            }
            inputStr += ");";

            writer.WriteLine(inputStr);

            AStructDecl        str = Util.GetAncestor <AStructDecl>(node);
            List <AMethodDecl> methodList;

            if (str != null)
            {
                methodList = StructMethods[str];
            }
            else
            {
                methodList = Methods;
            }
            string sig = Util.GetMethodSignature(node);

            if (methodList.Any(otherMethod => Util.GetMethodSignature(otherMethod) == sig))
            {
                return;
            }

            methodList.Add(node);
            node.SetBlock(null);
            node.Parent().RemoveChild(node);
        }
示例#6
0
        public override void CaseAOperatorDecl(AOperatorDecl node)
        {
            AMethodDecl replacer = new AMethodDecl(node.GetVisibilityModifier(), null, node.GetStatic(), null, null,
                                                   null, node.GetReturnType(),
                                                   new TIdentifier(""), new ArrayList(),
                                                   node.GetBlock());

            while (node.GetFormals().Count > 0)
            {
                replacer.GetFormals().Add(node.GetFormals()[0]);
            }

            node.ReplaceBy(replacer);
            replacer.Apply(this);
        }
示例#7
0
        public static string ToString(AMethodDecl methodDecl)
        {
            string str = TypeToString(methodDecl.GetReturnType()) + " " + methodDecl.GetName().Text + "(";

            foreach (AALocalDecl formal in methodDecl.GetFormals())
            {
                if (str.EndsWith("("))
                {
                    str += TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                }
                else
                {
                    str += ", " + TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                }
            }
            str += ")";
            return(str);
        }
        /// <summary>
        /// Crawls the StarCraft 2 MPQs to grab the *.galaxy files inside. These files are parsed for (native) functions and constants.
        /// </summary>
        /// <returns>The functions and constants of StarCraft 2 in form of a LibraryData</returns>
        LibraryData loadLibraries()
        {
            // parse the files for functions and constants
            CrawlAndParseMpqs();

            // convert the functions and constants to a LibraryData format
            LibraryData lib = new LibraryData();

            // create the methods with from crawled info
            foreach (ParsedFunction function in functions)
            {
                AMethodDecl method = new AMethodDecl();
                if (function.IsNative)
                {
                    method.SetNative(new TNative("native"));
                }
                method.SetName(new TIdentifier(function.Name));
                method.SetReturnType(new ANamedType(new TIdentifier(function.ReturnType), null));

                // add function parameter
                foreach (var parameter in function.Parameters)
                {
                    method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                            new ANamedType(new TIdentifier(parameter.Item1), null),
                                                            new TIdentifier(parameter.Item2), null));
                }

                lib.Methods.Add(method);
            }

            // create the constants from the crawled info
            foreach (ParsedConstant constant in constants)
            {
                AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const"),
                                                  new ANamedType(new TIdentifier(constant.Type), null),
                                                  new TIdentifier(constant.Name), new AStringConstExp(new TStringLiteral(constant.Value)));
                lib.Fields.Add(field);
            }

            functions.Clear();
            constants.Clear();

            return(lib);
        }
示例#9
0
        public static string GetMethodSignature(AMethodDecl method)
        {
            StringBuilder str = new StringBuilder(method.GetName().Text);

            str.Append("(");
            bool first = true;

            foreach (AALocalDecl localDecl in method.GetFormals())
            {
                if (!first)
                {
                    str.Append(",");
                }
                str.Append(Util.TypeToStringBuilder(localDecl.GetType()));
                first = false;
            }
            str.Append(")");
            return(str.ToString());
        }
示例#10
0
 public override void CaseAMethodDecl(AMethodDecl node)
 {
     if (parsedMethods.Contains(node) || methodChain.Contains(node))
     {
         return;
     }
     methodChain.Add(node);
     NeededRefs.Add(node, new List <AALocalDecl>());
     base.CaseAMethodDecl(node);
     methodChain.Remove(node);
     parsedMethods.Add(node);
     foreach (AALocalDecl formal in node.GetFormals())
     {
         if (formal.GetRef() != null && !NeededRefs[node].Contains(formal) && !Util.IsBulkCopy(formal.GetType()))
         {
             formal.SetRef(null);
         }
     }
 }
示例#11
0
 public override void CaseAMethodDecl(AMethodDecl node)
 {
     if (node.GetName().Text == "InitMap" && node.GetFormals().Count == 0)
     {
         if (finalTrans.multipleMainEntries)
         {
             multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor <AASourceFile>(node.GetName()), "Candidate"));
         }
         else if (finalTrans.mainEntry != null)
         {
             multipleEntryCandidates.Add(new ErrorCollection.Error(finalTrans.mainEntry.GetName(), Util.GetAncestor <AASourceFile>(finalTrans.mainEntry.GetName()), "Candidate"));
             multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor <AASourceFile>(node.GetName()), "Candidate"));
             //finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node), "Found multiple candidates for a main entry", true));
             finalTrans.multipleMainEntries = true;
             finalTrans.mainEntry           = null;
         }
         else
         {
             finalTrans.mainEntry = node;
         }
     }
     base.CaseAMethodDecl(node);
 }
示例#12
0
        public MethodDescription(AConstructorDecl method, string type)
        {
            Parser parser = new Parser(method);


            Start      = parser.Start;
            End        = parser.End;
            ReturnType = type;
            Name       = parser.Name;
            Formals    = parser.Formals;
            Locals     = parser.Locals;
            if (method.Parent() != null)
            {
                method.Parent().RemoveChild(method);
            }
            Decl = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new ANamedType(new TIdentifier(type), null),
                                   new TIdentifier(""), new ArrayList(), method.GetBlock());
            while (method.GetFormals().Count > 0)
            {
                Decl.GetFormals().Add(method.GetFormals()[0]);
            }
            Visibility = method.GetVisibilityModifier();
            Position   = TextPoint.FromCompilerCoords(method.GetName());
        }
示例#13
0
            /*
             * Apply before Transform method decls, and remove dead code
             *
             * Convert properties to methods
             */



            public static void Parse(FinalTransformations finalTrans)
            {
                OldEnrichmentParents.Clear();
                OldStructParents.Clear();
                SharedData data = finalTrans.data;

                foreach (APropertyDecl property in data.Properties.Select(p => p.Decl))
                {
                    AASourceFile parent = (AASourceFile)property.Parent();
                    if (property.GetGetter() != null)
                    {
                        AMethodDecl getter = new AMethodDecl(new APublicVisibilityModifier(), null,
                                                             property.GetStatic() == null
                                                                 ? null
                                                                 : (TStatic)property.GetStatic().Clone(), null, null, null,
                                                             Util.MakeClone(property.GetType(), data),
                                                             new TIdentifier("Get" + property.GetName().Text, property.GetName().Line, 0),
                                                             new ArrayList(), property.GetGetter());
                        data.Methods.Add(new SharedData.DeclItem <AMethodDecl>(parent, getter));
                        parent.GetDecl().Insert(parent.GetDecl().IndexOf(property), getter);
                        data.Getters[property] = getter;
                    }
                    if (property.GetSetter() != null)
                    {
                        AALocalDecl valueLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                 Util.MakeClone(property.GetType(), data),
                                                                 new TIdentifier("value"), null);
                        AMethodDecl setter = new AMethodDecl(new APublicVisibilityModifier(), null,
                                                             property.GetStatic() == null
                                                                 ? null
                                                                 : (TStatic)property.GetStatic().Clone(), null, null, null,
                                                             new AVoidType(new TVoid("void")),
                                                             new TIdentifier("Set" + property.GetName().Text, property.GetName().Line, 0),
                                                             new ArrayList()
                        {
                            valueLocal
                        }, property.GetSetter());
                        data.Methods.Add(new SharedData.DeclItem <AMethodDecl>(parent, setter));
                        parent.GetDecl().Insert(parent.GetDecl().IndexOf(property), setter);
                        setter.GetBlock().Apply(new FixValue(valueLocal, data));
                        data.Setters[property] = setter;
                    }
                    property.Parent().RemoveChild(property);
                }

                foreach (AStructDecl structDecl in data.Structs.Select(s => s.Decl))
                {
                    foreach (APropertyDecl property in data.StructProperties[structDecl])
                    {
                        //Due to enheritance, they might not be in same struct
                        if (structDecl != Util.GetAncestor <AStructDecl>(property))
                        {
                            continue;
                        }
                        OldStructParents[property] = structDecl;

                        if (property.GetGetter() != null)
                        {
                            AALocalDecl indexLocal = null;
                            string      methodName = "Get" + property.GetName().Text;
                            if (property.GetName().Text == "")
                            {
                                methodName = "GetThis";
                                indexLocal = data.ArrayPropertyLocals[property][0];
                            }

                            AMethodDecl getter = new AMethodDecl(new APublicVisibilityModifier(), null,
                                                                 property.GetStatic() == null
                                                                     ? null
                                                                     : (TStatic)property.GetStatic().Clone(), null, null, null,
                                                                 Util.MakeClone(property.GetType(), data),
                                                                 new TIdentifier(methodName, property.GetName().Line, 0),
                                                                 new ArrayList(), property.GetGetter());

                            if (indexLocal != null)
                            {
                                indexLocal.Parent().Parent().RemoveChild(indexLocal.Parent());
                                //data.Locals[(AABlock) getter.GetBlock()].Remove(indexLocal);
                                getter.GetFormals().Insert(0, indexLocal);
                            }

                            data.StructMethods[structDecl].Add(getter);
                            structDecl.GetLocals().Insert(structDecl.GetLocals().IndexOf(property.Parent()), new ADeclLocalDecl(getter));
                            data.Getters[property] = getter;
                        }
                        if (property.GetSetter() != null)
                        {
                            AALocalDecl indexLocal = null;
                            string      methodName = "Set" + property.GetName().Text;
                            if (property.GetName().Text == "")
                            {
                                methodName = "SetThis";
                                indexLocal = data.ArrayPropertyLocals[property][data.ArrayPropertyLocals[property].Length - 1];
                            }

                            AALocalDecl valueLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                     Util.MakeClone(property.GetType(), data),
                                                                     new TIdentifier("value"), null);
                            AMethodDecl setter = new AMethodDecl(new APublicVisibilityModifier(), null,
                                                                 property.GetStatic() == null
                                                                     ? null
                                                                     : (TStatic)property.GetStatic().Clone(), null, null, null,
                                                                 new AVoidType(new TVoid("void")),
                                                                 new TIdentifier(methodName, property.GetName().Line, 0),
                                                                 new ArrayList()
                            {
                                valueLocal
                            }, property.GetSetter());

                            if (indexLocal != null)
                            {
                                indexLocal.Parent().Parent().RemoveChild(indexLocal.Parent());
                                //data.Locals[(AABlock)setter.GetBlock()].Remove(indexLocal);
                                setter.GetFormals().Insert(0, indexLocal);
                            }

                            data.StructMethods[structDecl].Add(setter);
                            structDecl.GetLocals().Insert(structDecl.GetLocals().IndexOf(property.Parent()), new ADeclLocalDecl(setter));
                            setter.GetBlock().Apply(new FixValue(valueLocal, data));
                            data.Setters[property] = setter;
                        }
                        structDecl.RemoveChild(property.Parent());
                    }
                }

                foreach (AEnrichmentDecl enrichment in data.Enrichments)
                {
                    for (int i = 0; i < enrichment.GetDecl().Count; i++)
                    {
                        if (!(enrichment.GetDecl()[i] is APropertyDecl))
                        {
                            continue;
                        }


                        APropertyDecl property = (APropertyDecl)enrichment.GetDecl()[i];

                        OldEnrichmentParents[property] = enrichment;
                        if (property.GetGetter() != null)
                        {
                            AALocalDecl indexLocal = null;
                            string      methodName = "Get" + property.GetName().Text;
                            if (property.GetName().Text == "")
                            {
                                methodName = "GetThis";
                                indexLocal = data.ArrayPropertyLocals[property][0];
                            }

                            AMethodDecl getter = new AMethodDecl(new APublicVisibilityModifier(), null,
                                                                 property.GetStatic() == null
                                                                     ? null
                                                                     : (TStatic)property.GetStatic().Clone(), null, null, null,
                                                                 Util.MakeClone(property.GetType(), data),
                                                                 new TIdentifier(methodName, property.GetName().Line, 0),
                                                                 new ArrayList(), property.GetGetter());
                            if (indexLocal != null)
                            {
                                indexLocal.Parent().Parent().RemoveChild(indexLocal.Parent());
                                //data.Locals[(AABlock)getter.GetBlock()].Remove(indexLocal);
                                getter.GetFormals().Insert(0, indexLocal);
                            }

                            enrichment.GetDecl().Insert(enrichment.GetDecl().IndexOf(property), getter);
                            data.Getters[property] = getter;
                        }
                        if (property.GetSetter() != null)
                        {
                            AALocalDecl indexLocal = null;
                            string      methodName = "Set" + property.GetName().Text;
                            if (property.GetName().Text == "")
                            {
                                methodName = "SetThis";
                                indexLocal = data.ArrayPropertyLocals[property][data.ArrayPropertyLocals[property].Length - 1];
                            }

                            AALocalDecl valueLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                     Util.MakeClone(property.GetType(), data),
                                                                     new TIdentifier("value"), null);
                            AMethodDecl setter = new AMethodDecl(new APublicVisibilityModifier(), null,
                                                                 property.GetStatic() == null
                                                                     ? null
                                                                     : (TStatic)property.GetStatic().Clone(), null, null, null,
                                                                 new AVoidType(new TVoid("void")),
                                                                 new TIdentifier(methodName, property.GetName().Line, 0),
                                                                 new ArrayList()
                            {
                                valueLocal
                            }, property.GetSetter());
                            if (indexLocal != null)
                            {
                                indexLocal.Parent().Parent().RemoveChild(indexLocal.Parent());
                                data.Locals[(AABlock)setter.GetBlock()].Remove(indexLocal);
                                setter.GetFormals().Insert(0, indexLocal);
                            }

                            enrichment.GetDecl().Insert(enrichment.GetDecl().IndexOf(property), setter);
                            setter.GetBlock().Apply(new FixValue(valueLocal, data));
                            data.Setters[property] = setter;
                        }
                        enrichment.RemoveChild(property);
                    }
                }
            }
        /*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);
        }
        public static List <AABlock> Inline(ASimpleInvokeExp node, FinalTransformations finalTrans)
        {
            /*if (Util.GetAncestor<AMethodDecl>(node) != null && Util.GetAncestor<AMethodDecl>(node).GetName().Text == "UIChatFrame_LeaveChannel")
             *  node = node;*/

            SharedData data = finalTrans.data;
            //If this node is inside the condition of a while, replace it with a new local var,
            //make a clone before the while, one before each continue in the while, and one at the end of the while
            //(unless the end is a return or break)
            AABlock pBlock;

            if (Util.HasAncestor <AWhileStm>(node))
            {
                AWhileStm whileStm = Util.GetAncestor <AWhileStm>(node);
                if (Util.IsAncestor(node, whileStm.GetCondition()))
                {
                    List <ASimpleInvokeExp> toInline = new List <ASimpleInvokeExp>();
                    //Above while
                    AALocalDecl replaceVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                 Util.MakeClone(data.ExpTypes[node], data),
                                                                 new TIdentifier("whileVar"), null);
                    ALocalLvalue replaceVarRef    = new ALocalLvalue(new TIdentifier("whileVar"));
                    ALvalueExp   replaceVarRefExp = new ALvalueExp(replaceVarRef);
                    data.LocalLinks[replaceVarRef]  = replaceVarDecl;
                    data.ExpTypes[replaceVarRefExp] = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType();
                    node.ReplaceBy(replaceVarRefExp);
                    replaceVarDecl.SetInit(node);
                    pBlock = (AABlock)whileStm.Parent();
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(whileStm), new ALocalDeclStm(new TSemicolon(";"), replaceVarDecl));
                    toInline.Add(node);


                    //In the end of the while
                    PStm lastStm = whileStm.GetBody();
                    while (lastStm is ABlockStm)
                    {
                        AABlock block = (AABlock)((ABlockStm)lastStm).GetBlock();
                        if (block.GetStatements().Count == 0)
                        {
                            lastStm = null;
                            break;
                        }
                        lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1];
                    }
                    if (lastStm == null || !(lastStm is AValueReturnStm || lastStm is AVoidReturnStm || lastStm is ABreakStm))
                    {
                        lastStm = whileStm.GetBody();
                        AABlock block;
                        if (lastStm is ABlockStm)
                        {
                            block = (AABlock)((ABlockStm)lastStm).GetBlock();
                        }
                        else
                        {
                            block = new AABlock(new ArrayList(), new TRBrace("}"));
                            block.GetStatements().Add(lastStm);
                            whileStm.SetBody(new ABlockStm(new TLBrace("{"), block));
                        }

                        replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar"));
                        ASimpleInvokeExp clone = (ASimpleInvokeExp)Util.MakeClone(node, data);
                        toInline.Add(clone);
                        AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), replaceVarRef, clone);
                        data.LocalLinks[replaceVarRef] = replaceVarDecl;
                        data.ExpTypes[assignment]      = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType();
                        block.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment));
                    }

                    //After each continue
                    CloneBeforeContinue cloner = new CloneBeforeContinue(node, replaceVarDecl, data);
                    whileStm.GetBody().Apply(cloner);
                    toInline.AddRange(cloner.replacementExpressions);
                    List <AABlock> visitBlocks = new List <AABlock>();
                    foreach (ASimpleInvokeExp invoke in toInline)
                    {
                        visitBlocks.AddRange(Inline(invoke, finalTrans));
                    }
                    return(visitBlocks);
                }
            }



            AMethodDecl           decl = finalTrans.data.SimpleMethodLinks[node];
            FindAssignedToFormals assignedToFormalsFinder = new FindAssignedToFormals(finalTrans.data);

            decl.Apply(assignedToFormalsFinder);
            List <AALocalDecl> assignedToFormals = assignedToFormalsFinder.AssignedFormals;


            /*
             * inline int foo(int a)
             * {
             *      int b = 2;
             *      int c;
             *      ...
             *      while(...)
             *      {
             *          ...
             *          break;
             *          ...
             *          return c;
             *      }
             *      ...
             *      return 2;
             * }
             *
             * bar(foo(<arg for a>));
             * ->
             *
             * {
             *      bool inlineMethodReturned = false;
             *      int inlineReturner;
             *      int a = <arg for a>;
             *      while (!inlineMethodReturned)
             *      {
             *          int b = 2;
             *          int c;
             *          ...
             *          while(...)
             *          {
             *              ...
             *              break
             *              ...
             *              inlineReturner = c;
             *              inlineMethodReturned = true;
             *              break;
             *          }
             *          if (inlineMethodReturned)
             *          {
             *              break;
             *          }
             *          ...
             *          inlineReturner = 2;
             *          inlineMethodReturned = true;
             *          break;
             *          break;
             *      }
             *      bar(inlineReturner);
             * }
             *
             *
             */


            AABlock outerBlock = new AABlock();
            PExp    exp        = new ABooleanConstExp(new AFalseBool());

            finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null);
            AALocalDecl hasMethodReturnedVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null),
                                                               new TIdentifier("hasInlineReturned"), exp);

            finalTrans.data.GeneratedVariables.Add(hasMethodReturnedVar);
            PStm stm = new ALocalDeclStm(new TSemicolon(";"), hasMethodReturnedVar);

            outerBlock.GetStatements().Add(stm);

            AALocalDecl methodReturnerVar = null;

            if (!(decl.GetReturnType() is AVoidType))
            {
                methodReturnerVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(decl.GetReturnType(), finalTrans.data),
                                                    new TIdentifier("inlineReturner"), null);
                stm = new ALocalDeclStm(new TSemicolon(";"), methodReturnerVar);
                outerBlock.GetStatements().Add(stm);
            }

            AABlock afterBlock = new AABlock();

            //A dictionary from the formals of the inline method to a cloneable replacement lvalue
            Dictionary <AALocalDecl, PLvalue> Parameters    = new Dictionary <AALocalDecl, PLvalue>();
            Dictionary <AALocalDecl, PExp>    ParameterExps = new Dictionary <AALocalDecl, PExp>();

            for (int i = 0; i < decl.GetFormals().Count; i++)
            {
                AALocalDecl formal = (AALocalDecl)decl.GetFormals()[i];
                PExp        arg    = (PExp)node.GetArgs()[0];
                PLvalue     lvalue;
                //if ref, dont make a new var
                if (formal.GetRef() != null && arg is ALvalueExp)
                {
                    arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data));
                    arg.Parent().RemoveChild(arg);
                    lvalue = ((ALvalueExp)arg).GetLvalue();
                }
                else if (!assignedToFormals.Contains(formal) && Util.IsLocal(arg, finalTrans.data))
                {
                    lvalue = new ALocalLvalue(new TIdentifier("I hope I dont make it"));
                    finalTrans.data.LvalueTypes[lvalue] = formal.GetType();
                    finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = formal;
                    ParameterExps[formal] = arg;
                    arg.Parent().RemoveChild(arg);
                }
                else
                {
                    AAssignmentExp assExp = null;
                    if (formal.GetOut() != null)
                    {
                        //Dont initialize with arg, but assign arg after
                        arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data));
                        lvalue = ((ALvalueExp)arg).GetLvalue();
                        assExp = new AAssignmentExp(new TAssign("="), lvalue, null);
                        finalTrans.data.ExpTypes[assExp] = finalTrans.data.LvalueTypes[lvalue];
                        arg.Parent().RemoveChild(arg);
                        arg = null;
                    }
                    AALocalDecl parameter = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data),
                                                            new TIdentifier(formal.GetName().Text),
                                                            arg);
                    stm = new ALocalDeclStm(new TSemicolon(";"), parameter);
                    outerBlock.GetStatements().Add(stm);

                    lvalue = new ALocalLvalue(new TIdentifier(parameter.GetName().Text));
                    finalTrans.data.LvalueTypes[lvalue] = parameter.GetType();
                    finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = parameter;


                    if (formal.GetOut() != null)
                    {
                        //Dont initialize with arg, but assign arg after
                        ALvalueExp lvalueExp = new ALvalueExp(Util.MakeClone(lvalue, finalTrans.data));
                        finalTrans.data.ExpTypes[lvalueExp] = finalTrans.data.LvalueTypes[lvalue];
                        assExp.SetExp(lvalueExp);
                        afterBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assExp));
                    }
                }
                Parameters.Add(formal, lvalue);
            }

            AABlock innerBlock = (AABlock)decl.GetBlock().Clone();

            exp = new ABooleanConstExp(new ATrueBool());
            finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null);
            ABlockStm innerBlockStm = new ABlockStm(new TLBrace("{"), innerBlock);

            bool needWhile = CheckIfWhilesIsNeeded.IsWhileNeeded(decl.GetBlock());

            if (needWhile)
            {
                stm = new AWhileStm(new TLParen("("), exp, innerBlockStm);
            }
            else
            {
                stm = innerBlockStm;
            }
            outerBlock.GetStatements().Add(stm);

            outerBlock.GetStatements().Add(new ABlockStm(new TLBrace("{"), afterBlock));

            //Clone method contents to inner block.
            CloneMethod cloneFixer = new CloneMethod(finalTrans, Parameters, ParameterExps, innerBlockStm);

            decl.GetBlock().Apply(cloneFixer);
            foreach (KeyValuePair <PLvalue, PExp> pair in cloneFixer.ReplaceUsAfter)
            {
                PLvalue    lvalue       = pair.Key;
                PExp       replacement  = Util.MakeClone(pair.Value, finalTrans.data);
                ALvalueExp lvalueParent = (ALvalueExp)lvalue.Parent();
                lvalueParent.ReplaceBy(replacement);
            }
            innerBlockStm.Apply(new FixTypes(finalTrans.data));

            innerBlock.Apply(new FixReturnsAndWhiles(hasMethodReturnedVar, methodReturnerVar, finalTrans.data, needWhile));

            GetNonBlockStm stmFinder = new GetNonBlockStm(false);

            innerBlock.Apply(stmFinder);
            if (needWhile && (stmFinder.Stm == null || !(stmFinder.Stm is ABreakStm)))
            {
                innerBlock.GetStatements().Add(new ABreakStm(new TBreak("break")));
            }

            //Insert before current statement
            ABlockStm outerBlockStm = new ABlockStm(new TLBrace("{"), outerBlock);

            PStm pStm = Util.GetAncestor <PStm>(node);

            pBlock = (AABlock)pStm.Parent();

            pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), outerBlockStm);

            if (node.Parent() == pStm && pStm is AExpStm)
            {
                pBlock.RemoveChild(pStm);
            }
            else
            {
                PLvalue lvalue = new ALocalLvalue(new TIdentifier(methodReturnerVar.GetName().Text));
                finalTrans.data.LvalueTypes[lvalue] = methodReturnerVar.GetType();
                finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = methodReturnerVar;
                exp = new ALvalueExp(lvalue);
                finalTrans.data.ExpTypes[exp] = methodReturnerVar.GetType();

                node.ReplaceBy(exp);
            }
            return(new List <AABlock>()
            {
                outerBlock
            });
        }
        public override void CaseAConstructorDecl(AConstructorDecl 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 += "_Constructor";
            while (node.GetFormals().Count > 0)
            {
                replacer.GetFormals().Add(node.GetFormals()[0]);
            }

            //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.ConstructorMap[node] = replacer;
            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));

            //Add return stm
            replacer.SetReturnType(new APointerType(new TStar("*"), Util.MakeClone(type, data)));
            replacer.Apply(new TransformConstructorReturns(structFormal, data));

            //Insert call to base constructor););
            if (finalTrans.data.ConstructorBaseLinks.ContainsKey(node))
            {
                AMethodDecl      baseConstructor = finalTrans.data.ConstructorMap[finalTrans.data.ConstructorBaseLinks[node]];
                ASimpleInvokeExp invoke          = new ASimpleInvokeExp(new TIdentifier(baseConstructor.GetName().Text), new ArrayList());
                while (node.GetBaseArgs().Count > 0)
                {
                    invoke.GetArgs().Add(node.GetBaseArgs()[0]);
                }
                AThisLvalue thisLvalue1 = new AThisLvalue(new TThis("this"));
                ALvalueExp  thisExp1    = new ALvalueExp(thisLvalue1);
                invoke.GetArgs().Add(thisExp1);

                AThisLvalue thisLvalue2 = new AThisLvalue(new TThis("this"));

                AAssignmentExp assignExp = new AAssignmentExp(new TAssign("="), thisLvalue2, invoke);

                ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null);
                finalTrans.data.StructTypeLinks[structType] = str;

                finalTrans.data.LvalueTypes[thisLvalue1]         =
                    finalTrans.data.LvalueTypes[thisLvalue2]     =
                        finalTrans.data.ExpTypes[thisExp1]       =
                            finalTrans.data.ExpTypes[assignExp]  =
                                finalTrans.data.ExpTypes[invoke] = new APointerType(new TStar("*"), structType);

                //finalTrans.data.ExpTypes[invoke] = new AVoidType(new TVoid("void"));
                finalTrans.data.SimpleMethodLinks[invoke] = baseConstructor;

                ((AABlock)replacer.GetBlock()).GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), assignExp));

                //Inline if base and current are two different kinds of pointer types (int/string)
                AStructDecl      baseStruct = null;
                AConstructorDecl baseC      = finalTrans.data.ConstructorBaseLinks[node];
                foreach (KeyValuePair <AStructDecl, List <AConstructorDecl> > pair in finalTrans.data.StructConstructors)
                {
                    bool found = false;
                    foreach (AConstructorDecl decl in pair.Value)
                    {
                        if (baseC == decl)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (found)
                    {
                        baseStruct = pair.Key;
                        break;
                    }
                }
                if ((str.GetIntDim() == null) != (baseStruct.GetIntDim() == null))
                {
                    //For the inilining, change the type to the type of the caller
                    AALocalDecl lastFormal = baseConstructor.GetFormals().OfType <AALocalDecl>().Last();
                    lastFormal.SetRef(new TRef("ref"));
                    APointerType oldType = (APointerType)lastFormal.GetType();

                    structType = new ANamedType(new TIdentifier(str.GetName().Text), null);
                    finalTrans.data.StructTypeLinks[structType] = str;

                    APointerType newType = new APointerType(new TStar("*"), structType);
                    lastFormal.SetType(newType);

                    foreach (
                        ALocalLvalue lvalue in
                        data.LocalLinks.Where(pair => pair.Value == lastFormal).Select(pair => pair.Key))
                    {
                        data.LvalueTypes[lvalue] = newType;
                        if (lvalue.Parent() is ALvalueExp)
                        {
                            data.ExpTypes[(PExp)lvalue.Parent()] = newType;
                            if (lvalue.Parent().Parent() is APointerLvalue)
                            {
                                data.LvalueTypes[(PLvalue)lvalue.Parent().Parent()] = newType.GetType();
                            }
                        }
                    }

                    FixInlineMethods.Inline(invoke, finalTrans);
                    lastFormal.SetRef(null);
                    foreach (
                        ALocalLvalue lvalue in
                        data.LocalLinks.Where(pair => pair.Value == lastFormal).Select(pair => pair.Key))
                    {
                        data.LvalueTypes[lvalue] = oldType;
                        if (lvalue.Parent() is ALvalueExp)
                        {
                            data.ExpTypes[(PExp)lvalue.Parent()] = oldType;
                            if (lvalue.Parent().Parent() is APointerLvalue)
                            {
                                data.LvalueTypes[(PLvalue)lvalue.Parent().Parent()] = oldType.GetType();
                            }
                        }
                    }

                    lastFormal.SetType(oldType);
                }

                //Inline it instead, Since the pointer implementations might not be the same (int vs string)

                /*AMethodDecl baseConstructor = finalTrans.data.ConstructorMap[finalTrans.data.ConstructorBaseLinks[node]];
                 *
                 * AABlock localsBlock = new AABlock(new ArrayList(), new TRBrace("}"));
                 * ABlockStm cloneBlock = new ABlockStm(new TLBrace("{"), (PBlock) baseConstructor.GetBlock().Clone());
                 * Dictionary<AALocalDecl, PLvalue> localMap = new Dictionary<AALocalDecl, PLvalue>();
                 * for (int argNr = 0; argNr < baseConstructor.GetFormals().Count; argNr++)
                 * {
                 *  AALocalDecl formal = (AALocalDecl) baseConstructor.GetFormals()[i];
                 *  PExp arg;
                 *  if (i < baseConstructor.GetFormals().Count - 1)
                 *      arg = (PExp)node.GetBaseArgs()[i];
                 *  else
                 *  {
                 *      AThisLvalue thisLvalue = new AThisLvalue(new TThis("this"));
                 *      ALvalueExp thisExp = new ALvalueExp(thisLvalue);
                 *
                 *      ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null);
                 *      finalTrans.data.StructTypeLinks[structType] = str;
                 *
                 *      finalTrans.data.LvalueTypes[thisLvalue] =
                 *          finalTrans.data.ExpTypes[thisExp] = new APointerType(new TStar("*"), structType);
                 *
                 *      arg = thisExp;
                 *  }
                 *
                 *  if (formal.GetRef() != null || formal.GetOut() != null)
                 *  {
                 *      //Use same variable
                 *      localMap[formal] = ((ALvalueExp) arg).GetLvalue();
                 *  }
                 *  else
                 *  {
                 *      //Make a new variable
                 *      AALocalDecl newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                 *                                             Util.MakeClone(formal.GetType(), finalTrans.data),
                 *                                             new TIdentifier(formal.GetName().Text),
                 *                                             Util.MakeClone(arg, data));
                 *
                 *      ALocalLvalue newLocalRef = new ALocalLvalue(new TIdentifier(newLocal.GetName().Text));
                 *
                 *      localMap[formal] = newLocalRef;
                 *      data.LvalueTypes[newLocalRef] = newLocal.GetType();
                 *      data.LocalLinks[newLocalRef] = newLocal;
                 *
                 *      localsBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), newLocal));
                 *  }
                 *
                 * }
                 *
                 * CloneMethod cloner = new CloneMethod(finalTrans.data, localMap, cloneBlock);
                 * baseConstructor.GetBlock().Apply(cloner);
                 *
                 * ((AABlock)cloneBlock.GetBlock()).GetStatements().Insert(0, new ABlockStm(new TLBrace("{"), localsBlock));
                 * ((AABlock)node.GetBlock()).GetStatements().Insert(0, cloneBlock);*/
            }

            //Fix refferences to other struct stuff);
            base.CaseAMethodDecl(replacer);

            //Add functionality to refference the current struct in a constructor
            //Want to do it as a pointer type, since the constructer can only be called for pointer types
        }
示例#17
0
        private void MakeInitializerInvokes()
        {
            AABlock      block = (AABlock)mainEntry.GetBlock();
            AASourceFile file  = Util.GetAncestor <AASourceFile>(mainEntry);
            AMethodDecl  invokeMethod;

            /* Add
             * void Invoke(string methodName)
             * {
             *     trigger initTrigger = TriggerCreate(methodName);
             *     TriggerExecute(initTrigger, false, true);
             *     TriggerDestroy(initTrigger);
             * }
             */

            {
                //void Invoke(string methodName)
                AALocalDecl parameter = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                        new ANamedType(new TIdentifier("string"), null),
                                                        new TIdentifier("methodName"), null);
                AABlock methodBody = new AABlock();
                invokeMethod = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                               new AVoidType(new TVoid("void")), new TIdentifier("Invoke"),
                                               new ArrayList()
                {
                    parameter
                }, methodBody);

                //trigger initTrigger = TriggerCreate(methodName);
                ALocalLvalue parameterLvalue = new ALocalLvalue(new TIdentifier("methodName"));
                data.LocalLinks[parameterLvalue] = parameter;
                ALvalueExp parameterLvalueExp = new ALvalueExp(parameterLvalue);
                data.LvalueTypes[parameterLvalue]     =
                    data.ExpTypes[parameterLvalueExp] = parameter.GetType();
                ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("TriggerCreate"), new ArrayList()
                {
                    parameterLvalueExp
                });
                data.ExpTypes[invoke] = new ANamedType(new TIdentifier("trigger"), null);
                foreach (AMethodDecl methodDecl in data.Libraries.Methods)
                {
                    if (methodDecl.GetName().Text == "TriggerCreate")
                    {
                        data.SimpleMethodLinks[invoke] = methodDecl;
                        break;
                    }
                }
                AALocalDecl initTriggerDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                              new ANamedType(new TIdentifier("trigger"), null),
                                                              new TIdentifier("initTrigger"), invoke);
                methodBody.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), initTriggerDecl));

                //TriggerExecute(initTrigger, false, true);
                ALocalLvalue initTriggerLvalue = new ALocalLvalue(new TIdentifier("initTrigger"));
                data.LocalLinks[initTriggerLvalue] = initTriggerDecl;
                ALvalueExp initTriggerLvalueExp = new ALvalueExp(initTriggerLvalue);
                data.LvalueTypes[initTriggerLvalue]     =
                    data.ExpTypes[initTriggerLvalueExp] = initTriggerDecl.GetType();
                ABooleanConstExp falseBool = new ABooleanConstExp(new AFalseBool());
                ABooleanConstExp trueBool  = new ABooleanConstExp(new ATrueBool());
                data.ExpTypes[falseBool]    =
                    data.ExpTypes[trueBool] = new ANamedType(new TIdentifier("bool"), null);
                invoke = new ASimpleInvokeExp(new TIdentifier("TriggerExecute"), new ArrayList()
                {
                    initTriggerLvalueExp, falseBool, trueBool
                });
                data.ExpTypes[invoke] = new AVoidType(new TVoid("void"));
                foreach (AMethodDecl methodDecl in data.Libraries.Methods)
                {
                    if (methodDecl.GetName().Text == "TriggerExecute")
                    {
                        data.SimpleMethodLinks[invoke] = methodDecl;
                        break;
                    }
                }
                methodBody.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke));

                //TriggerDestroy(initTrigger);
                initTriggerLvalue = new ALocalLvalue(new TIdentifier("initTrigger"));
                data.LocalLinks[initTriggerLvalue] = initTriggerDecl;
                initTriggerLvalueExp = new ALvalueExp(initTriggerLvalue);
                data.LvalueTypes[initTriggerLvalue]     =
                    data.ExpTypes[initTriggerLvalueExp] = initTriggerDecl.GetType();
                invoke = new ASimpleInvokeExp(new TIdentifier("TriggerDestroy"), new ArrayList()
                {
                    initTriggerLvalueExp
                });
                data.ExpTypes[invoke] = new AVoidType(new TVoid("void"));
                foreach (AMethodDecl methodDecl in data.Libraries.Methods)
                {
                    if (methodDecl.GetName().Text == "TriggerDestroy")
                    {
                        data.SimpleMethodLinks[invoke] = methodDecl;
                        break;
                    }
                }
                methodBody.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke));

                file.GetDecl().Add(invokeMethod);
            }

            for (int i = data.InitializerMethods.Count - 1; i >= 0; i--)
            {
                AMethodDecl method = data.InitializerMethods[i];
                //Turn method into a trigger
                method.SetReturnType(new ANamedType(new TIdentifier("bool"), null));
                method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                        new ANamedType(new TIdentifier("bool"), null),
                                                        new TIdentifier("testConds"), null));
                method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                        new ANamedType(new TIdentifier("bool"), null),
                                                        new TIdentifier("runActions"), null));
                method.SetTrigger(new TTrigger("trigger"));
                ((AABlock)method.GetBlock()).GetStatements().Add(new AVoidReturnStm(new TReturn("return")));
                TriggerConvertReturn returnConverter = new TriggerConvertReturn(data);
                method.Apply(returnConverter);
                data.TriggerDeclarations[method] = new List <TStringLiteral>();


                //Add Invoke(<name>); to main entry
                TStringLiteral literal = new TStringLiteral(method.GetName().Text);
                data.TriggerDeclarations[method].Add(literal);
                AStringConstExp stringConst = new AStringConstExp(literal);
                data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null);
                ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("Invoke"), new ArrayList()
                {
                    stringConst
                });
                data.SimpleMethodLinks[invoke] = invokeMethod;
                data.ExpTypes[invoke]          = invokeMethod.GetReturnType();
                block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), invoke));



                //ASyncInvokeExp syncInvokeExp = new ASyncInvokeExp(new TSyncInvoke("Invoke"), new AAmbiguousNameLvalue(new ASimpleName(new TIdentifier(method.GetName().Text))), new ArrayList());
                //data.Invokes.Add(method, new List<InvokeStm>(){new InvokeStm(syncInvokeExp)});
                //data.ExpTypes[syncInvokeExp] = new AVoidType(new TVoid("void"));

                //block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), syncInvokeExp));
            }
            for (int i = data.InvokeOnIniti.Count - 1; i >= 0; i--)
            {
                AMethodDecl method = data.InvokeOnIniti[i];

                //Turn method into a trigger
                method.SetReturnType(new ANamedType(new TIdentifier("bool"), null));
                method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                        new ANamedType(new TIdentifier("bool"), null),
                                                        new TIdentifier("testConds"), null));
                method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                        new ANamedType(new TIdentifier("bool"), null),
                                                        new TIdentifier("runActions"), null));
                method.SetTrigger(new TTrigger("trigger"));
                ((AABlock)method.GetBlock()).GetStatements().Add(new AVoidReturnStm(new TReturn("return")));
                TriggerConvertReturn returnConverter = new TriggerConvertReturn(data);
                method.Apply(returnConverter);
                data.TriggerDeclarations[method] = new List <TStringLiteral>();


                //Add Invoke(<name>); to main entry
                TStringLiteral literal = new TStringLiteral(method.GetName().Text);
                data.TriggerDeclarations[method].Add(literal);
                AStringConstExp stringConst = new AStringConstExp(literal);
                data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null);
                ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("Invoke"), new ArrayList()
                {
                    stringConst
                });
                data.SimpleMethodLinks[invoke] = invokeMethod;
                data.ExpTypes[invoke]          = invokeMethod.GetReturnType();
                block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), invoke));


                /*
                 * ASyncInvokeExp syncInvokeExp = new ASyncInvokeExp(new TSyncInvoke("Invoke"),  new AAmbiguousNameLvalue(new ASimpleName(new TIdentifier(method.GetName().Text))), new ArrayList());
                 * data.Invokes.Add(method, new List<InvokeStm>() { new InvokeStm(syncInvokeExp) });
                 * data.ExpTypes[syncInvokeExp] = new AVoidType(new TVoid("void"));
                 *
                 * block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), syncInvokeExp));*/
            }
            for (int i = data.FieldsToInitInMapInit.Count - 1; i >= 0; i--)
            {
                AFieldDecl field = data.FieldsToInitInMapInit[i];
                if (field.GetInit() == null)
                {
                    continue;
                }

                AFieldLvalue   lvalue     = new AFieldLvalue(new TIdentifier(field.GetName().Text));
                AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, field.GetInit());

                data.ExpTypes[assignment]    =
                    data.LvalueTypes[lvalue] = field.GetType();
                data.FieldLinks[lvalue]      = field;

                block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), assignment));
            }
            block.RemoveChild(mainEntryFieldInitBlock);
            block.GetStatements().Insert(0, mainEntryFieldInitBlock);
        }
        public override void CaseASimpleInvokeExp(ASimpleInvokeExp node)
        {
            AMethodDecl decl = finalTrans.data.SimpleMethodLinks[node];

            if (structMethods.Contains(decl))
            {     //The target is a struct method that has been moved out
                if (node.GetArgs().Count < decl.GetFormals().Count&& Util.HasAncestor <AStructDecl>(node))
                { //If this is the case, we Must be inside the same struct as the target. - Not with enheritance
                    ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName"));
                    ALvalueExp   exp   = new ALvalueExp(local);
                    finalTrans.data.LvalueTypes[local] =
                        finalTrans.data.ExpTypes[exp]  = structFormal.GetType();
                    finalTrans.data.LocalLinks[local]  = structFormal;

                    //If we're calling from class to struct, we must depointer it
                    AStructDecl currentStruct =
                        finalTrans.data.StructMethods.First(
                            pair => pair.Value.Contains(Util.GetAncestor <AMethodDecl>(node))).Key;
                    AStructDecl baseStruct =
                        finalTrans.data.StructMethods.First(
                            pair => pair.Value.Contains(decl)).Key;
                    if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class
                    {
                        APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp);
                        exp = new ALvalueExp(pointerLvalue);

                        finalTrans.data.LvalueTypes[pointerLvalue] =
                            finalTrans.data.ExpTypes[exp]          = ((APointerType)structFormal.GetType()).GetType();
                    }

                    node.GetArgs().Add(exp);
                }
            }
            else if (Util.GetAncestor <AStructDecl>(decl) != null && OldParentStruct.ContainsKey(Util.GetAncestor <AMethodDecl>(node)))
            {     //The target is a struct method that hasn't been moved out
                if (Util.GetAncestor <AStructDecl>(decl) == OldParentStruct[Util.GetAncestor <AMethodDecl>(node)] && decl.GetStatic() == null)
                { //We have an internal struct call. Expect to have one too many args
                    if (node.GetArgs().Count == decl.GetFormals().Count)
                    {
                        ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName"));
                        ALvalueExp   exp   = new ALvalueExp(local);
                        finalTrans.data.LvalueTypes[local] =
                            finalTrans.data.ExpTypes[exp]  = structFormal.GetType();
                        finalTrans.data.LocalLinks[local]  = structFormal;

                        //If we're calling from class to struct, we must depointer it
                        AStructDecl currentStruct =
                            finalTrans.data.StructMethods.First(
                                pair => pair.Value.Contains(Util.GetAncestor <AMethodDecl>(node))).Key;
                        AStructDecl baseStruct =
                            finalTrans.data.StructMethods.First(
                                pair => pair.Value.Contains(decl)).Key;
                        if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class
                        {
                            APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp);
                            exp = new ALvalueExp(pointerLvalue);

                            finalTrans.data.LvalueTypes[pointerLvalue] =
                                finalTrans.data.ExpTypes[exp]          = ((APointerType)structFormal.GetType()).GetType();
                        }

                        node.GetArgs().Add(exp);
                    }
                }
            }
            base.CaseASimpleInvokeExp(node);
        }
示例#19
0
        public static void Apply(AAProgram ast, FinalTransformations finalTrans)
        {
            //Build list of file dependacies
            Phase1 phase1 = new Phase1(finalTrans);

            ast.Apply(phase1);
            var dependancies = phase1.dependancies;

            if (dependancies.Keys.Count == 0)
            {
                return;
            }
            AASourceFile root = Util.GetAncestor <AASourceFile>(finalTrans.mainEntry) ??
                                dependancies.Keys.FirstOrDefault(file => !file.GetName().Text.Contains("\\")) ??
                                dependancies.Keys.First(file => true);

            //Remove files unreachable from root
            //On second thought, dont. there might be static refferences the other way which needs to be included

            /*{
             *  List<AASourceFile> reachable = GetReachable(root, dependancies);
             *  AASourceFile[] keys = new AASourceFile[dependancies.Count];
             *  dependancies.Keys.CopyTo(keys, 0);
             *  foreach (AASourceFile key in keys)
             *  {
             *      if (!reachable.Contains(key))
             *          dependancies.Remove(key);
             *  }
             * }*/


            //Push common depancies up

            /*
             * root -> (item1 -> (item3), item2 -> (item4 -> (item3)))
             *
             * root -> (item3, item1, item2 -> (item4))
             */

            //Add unreachable to the root
            while (true)
            {
                List <AASourceFile> reachable = new List <AASourceFile>();
                GetReachable(root, dependancies, ref reachable);
                if (reachable.Count == dependancies.Count + (reachable.Contains(null) ? 1 : 0))
                {
                    break;
                }
                AASourceFile[] keys = new AASourceFile[dependancies.Count];
                dependancies.Keys.CopyTo(keys, 0);
                foreach (AASourceFile key in keys)
                {
                    if (!reachable.Contains(key))
                    {
                        AASourceFile k = key;
                        //See if you can find another unreachable file which need this file
                        Dictionary <AASourceFile, int> decendantCounts = new Dictionary <AASourceFile, int>();
                        decendantCounts.Add(k, CountDecendants(k, dependancies, new List <AASourceFile>()));
                        while (true)
                        {
                            AASourceFile file = null;
                            foreach (KeyValuePair <AASourceFile, List <AASourceFile> > dependancy in dependancies)
                            {
                                if (decendantCounts.ContainsKey(dependancy.Key))
                                {
                                    continue;
                                }
                                if (!dependancy.Value.Contains(k))
                                {
                                    continue;
                                }
                                file = dependancy.Key;
                                break;
                            }

                            //AASourceFile file = dependancies.FirstOrDefault(item => item.Value.Contains(k)).Key;
                            if (file == null)
                            {
                                break;
                            }
                            decendantCounts.Add(file, CountDecendants(file, dependancies, new List <AASourceFile>()));
                            k = file;
                        }
                        foreach (KeyValuePair <AASourceFile, int> decendantItem in decendantCounts)
                        {
                            if (decendantItem.Value > decendantCounts[k])
                            {
                                k = decendantItem.Key;
                            }
                        }

                        dependancies[root].Add(k);
                        break;
                    }
                }
            }
            //It is moved down here because cycles are not removed in unreachable
            RemoveCycles(root, dependancies, new List <AASourceFile> {
                root
            });


            //Convert to tree to make it easier
            List <Item> allItems        = new List <Item>();
            IncludeItem rootIncludeItem = MakeTree(root, dependancies, allItems, null);

            bool[] removed = new bool[allItems.Count];
            for (int i = 0; i < removed.Length; i++)
            {
                removed[i] = false;
            }
            int removedCount = 0;

            //Ensure that each include is only included one place
            for (int i = 0; i < allItems.Count; i++)
            {
                if (removed[i])
                {
                    continue;
                }

                IncludeItem item1 = (IncludeItem)allItems[i];
                for (int j = i + 1; j < allItems.Count; j++)
                {
                    if (removed[j])
                    {
                        continue;
                    }
                    IncludeItem item2 = (IncludeItem)allItems[j];

                    if (item1.Current == item2.Current)
                    {
                        List <Item> path1 = item1.Path;
                        List <Item> path2 = item2.Path;



                        for (int k = 0; k < Math.Min(path1.Count, path2.Count); k++)
                        {
                            if (path1[k] != path2[k])
                            {
                                int insertAt = Math.Min(path1[k - 1].Children.IndexOf(path1[k]),
                                                        path2[k - 1].Children.IndexOf(path2[k]));


                                item1.Parent.Children.Remove(item1);
                                LinkedList <IncludeItem> toRemove = new LinkedList <IncludeItem>();
                                toRemove.AddLast(item2);
                                while (toRemove.Count > 0)
                                {
                                    IncludeItem item = toRemove.First.Value;
                                    toRemove.RemoveFirst();
                                    item.Parent.Children.Remove(item);
                                    //allItems.Remove(item);
                                    removedCount++;
                                    removed[item.ListIndex] = true;
                                    foreach (IncludeItem child in item.Children)
                                    {
                                        toRemove.AddLast(child);
                                    }
                                }
                                //j--;



                                path1[k - 1].Children.Insert(insertAt, item1);
                                item1.Parent = path1[k - 1];



                                break;
                            }
                        }
                    }
                }
            }

            List <Item> newAllItems = new List <Item>(allItems.Count - removedCount);

            for (int i = 0; i < allItems.Count; i++)
            {
                if (!removed[i])
                {
                    newAllItems.Add(allItems[i]);
                }
            }
            allItems = newAllItems;

            //Move the null node to nr [0]
            foreach (IncludeItem item in allItems)
            {
                if (item.Current == null)
                {
                    int  itemIndex = item.Parent.Children.IndexOf(item);
                    Item item0     = item.Parent.Children[0];
                    item.Parent.Children[0]         = item;
                    item.Parent.Children[itemIndex] = item0;
                    break;
                }
            }

            //Insert method decls and move structs & fields up as needed
            ast.Apply(new Phase2(finalTrans, allItems));

            //Insert the headers in the files

            if (Options.Compiler.OneOutputFile)
            {
                //for (int i = 0; i < allItems.Count; i++)
                int i = 0;
                while (allItems.Count > 0)
                {
                    if (allItems[i] is IncludeItem)
                    {
                        IncludeItem includeItem = (IncludeItem)allItems[i];
                        //Dont want the standard lib
                        if (includeItem.Current == null)
                        {
                            i++;
                            continue;
                        }
                        //If it has children with children, then pick another first
                        if (includeItem.Children.Any(child => child.Children.Count > 0))
                        {
                            i++;
                            continue;
                        }
                        if (includeItem.Children.Count == 0)
                        {
                            if (includeItem.Parent == null)
                            {
                                break;
                            }
                            i++;
                            continue;
                        }
                        i = 0;
                        //Put all children into this
                        while (includeItem.Children.Count > 0)
                        {
                            int childNr = includeItem.Children.Count - 1;
                            allItems.Remove(includeItem.Children[childNr]);
                            if (includeItem.Children[childNr] is FieldItem)
                            {
                                FieldItem aItem = (FieldItem)includeItem.Children[childNr];
                                Node      node  = aItem.FieldDecl;
                                node.Parent().RemoveChild(node);
                                includeItem.Current.GetDecl().Insert(0, node);
                            }
                            else if (includeItem.Children[childNr] is StructItem)
                            {
                                StructItem aItem = (StructItem)includeItem.Children[childNr];
                                Node       node  = aItem.StructDecl;
                                node.Parent().RemoveChild(node);
                                includeItem.Current.GetDecl().Insert(0, node);
                            }
                            else if (includeItem.Children[childNr] is MethodDeclItem)
                            {
                                MethodDeclItem aItem = (MethodDeclItem)includeItem.Children[childNr];
                                AMethodDecl    aNode = new AMethodDecl();
                                if (aItem.RealDecl.GetStatic() != null)
                                {
                                    aNode.SetStatic(new TStatic("static"));
                                }
                                aNode.SetReturnType(Util.MakeClone(aItem.RealDecl.GetReturnType(), finalTrans.data));
                                aNode.SetName(new TIdentifier(aItem.RealDecl.GetName().Text));
                                foreach (AALocalDecl formal in aItem.RealDecl.GetFormals())
                                {
                                    AALocalDecl clone = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), null);
                                    aNode.GetFormals().Add(clone);
                                }
                                includeItem.Current.GetDecl().Insert(0, aNode);
                            }
                            else if (includeItem.Children[childNr] is IncludeItem)
                            {
                                IncludeItem aChild = (IncludeItem)includeItem.Children[childNr];
                                if (aChild.Current == null)
                                {
                                    AIncludeDecl node = new AIncludeDecl(new TInclude("include"),
                                                                         new TStringLiteral("\"TriggerLibs/NativeLib\""));
                                    includeItem.Current.GetDecl().Insert(0, node);
                                }
                                else
                                {
                                    PDecl[] decls = new PDecl[aChild.Current.GetDecl().Count];
                                    aChild.Current.GetDecl().CopyTo(decls, 0);
                                    for (int k = decls.Length - 1; k >= 0; k--)
                                    {
                                        includeItem.Current.GetDecl().Insert(0, decls[k]);
                                    }
                                    aChild.Current.Parent().RemoveChild(aChild.Current);
                                    //i = -1;
                                }
                            }
                            includeItem.Children.RemoveAt(childNr);
                        }
                    }
                }
            }
            else
            {
                foreach (IncludeItem includeItem in allItems.OfType <IncludeItem>())
                {
                    for (int i = includeItem.Children.Count - 1; i >= 0; i--)
                    {
                        Node node;
                        if (includeItem.Children[i] is IncludeItem)
                        {
                            IncludeItem aItem = (IncludeItem)includeItem.Children[i];
                            node = new AIncludeDecl(new TInclude("include"),
                                                    new TStringLiteral("\"" + (aItem.Current == null ? "TriggerLibs/NativeLib" : aItem.Current.GetName().Text.Replace("\\", "/")) + "\""));
                            if (aItem.Current == null && finalTrans.mainEntry != null)
                            {
                                //Search for user defined initlib
                                bool foundInvoke = false;
                                foreach (ASimpleInvokeExp invokeExp in finalTrans.data.SimpleMethodLinks.Keys)
                                {
                                    if (invokeExp.GetName().Text == "libNtve_InitLib" && invokeExp.GetArgs().Count == 0)
                                    {
                                        /*finalTrans.errors.Add(new ErrorCollection.Error(invokeExp.GetName(),
                                         *                                              Util.GetAncestor<AASourceFile>(
                                         *                                                  invokeExp),
                                         *                                              "You are invoking libNtve_InitLib() yourself somewhere. It will not be auto inserted.",
                                         *                                              true));*/
                                        foundInvoke = true;
                                        break;
                                    }
                                }

                                if (!foundInvoke)
                                {
                                    //Init the lib
                                    ASimpleInvokeExp initExp = new ASimpleInvokeExp();
                                    initExp.SetName(new TIdentifier("libNtve_InitLib"));
                                    finalTrans.data.ExpTypes[initExp] = new AVoidType(new TVoid("void"));
                                    foreach (AMethodDecl method in finalTrans.data.Libraries.Methods)
                                    {
                                        if (method.GetName().Text == "libNtve_InitLib" && method.GetFormals().Count == 0)
                                        {
                                            finalTrans.data.SimpleMethodLinks[initExp] = method;
                                        }
                                    }
                                    AABlock block = (AABlock)finalTrans.mainEntry.GetBlock();
                                    block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), initExp));
                                }
                            }
                        }
                        else if (includeItem.Children[i] is FieldItem)
                        {
                            FieldItem aItem = (FieldItem)includeItem.Children[i];
                            node = aItem.FieldDecl;
                            node.Parent().RemoveChild(node);
                        }
                        else if (includeItem.Children[i] is StructItem)
                        {
                            StructItem aItem = (StructItem)includeItem.Children[i];
                            node = aItem.StructDecl;
                            node.Parent().RemoveChild(node);
                        }
                        else if (includeItem.Children[i] is MethodDeclItem)
                        {
                            MethodDeclItem aItem = (MethodDeclItem)includeItem.Children[i];
                            AMethodDecl    aNode = new AMethodDecl();
                            if (aItem.RealDecl.GetStatic() != null)
                            {
                                aNode.SetStatic(new TStatic("static"));
                            }
                            aNode.SetReturnType(Util.MakeClone(aItem.RealDecl.GetReturnType(), finalTrans.data));
                            aNode.SetName(new TIdentifier(aItem.RealDecl.GetName().Text));
                            foreach (AALocalDecl formal in aItem.RealDecl.GetFormals())
                            {
                                AALocalDecl clone = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), null);
                                aNode.GetFormals().Add(clone);
                            }
                            node = aNode;
                        }
                        else
                        {
                            throw new Exception("FixIncludes.Apply: Unexpected item type");
                        }

                        includeItem.Current.GetDecl().Insert(0, node);
                    }
                }
            }
        }
        //private List<ErrorCollection.Error> multipleEntryCandidates = new List<ErrorCollection.Error>();
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            //Done in a previous iteration

            /*if (node.GetName().Text == "InitMap" && node.GetFormals().Count == 0)
             * {
             *  if (finalTrans.multipleMainEntries)
             *  {
             *      multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate"));
             *  }
             *  else if (finalTrans.mainEntry != null)
             *  {
             *      multipleEntryCandidates.Add(new ErrorCollection.Error(finalTrans.mainEntry.GetName(), Util.GetAncestor<AASourceFile>(finalTrans.mainEntry.GetName()), "Candidate"));
             *      multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate"));
             *      //finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node), "Found multiple candidates for a main entry", true));
             *      finalTrans.multipleMainEntries = true;
             *      finalTrans.mainEntry = null;
             *  }
             *  else
             *      finalTrans.mainEntry = node;
             * }*/

            AStructDecl str = Util.GetAncestor <AStructDecl>(node);

            if (str != null)
            {
                if (node.GetStatic() == null)
                {
                    structMethods.Add(node);
                }
                //Move the method outside the struct
                str.RemoveChild(node.Parent());
                AASourceFile file = (AASourceFile)str.Parent();
                int          i    = file.GetDecl().IndexOf(str);
                file.GetDecl().Insert(i /* + 1*/, node);
                node.GetName().Text = GetUniqueStructMethodName(str.GetName().Text + "_" + node.GetName().Text);

                if (node.GetStatic() == null)
                {
                    //Add the struct as a parameter
                    PType structType = new ANamedType(new TIdentifier(str.GetName().Text), null);
                    finalTrans.data.StructTypeLinks[(ANamedType)structType] = str;
                    if (str.GetClassToken() != null)
                    {
                        structType = new APointerType(new TStar("*"), structType);
                    }
                    structFormal = new AALocalDecl(new APublicVisibilityModifier(), null,
                                                   str.GetClassToken() == null ? new TRef("ref") : null, null, null,
                                                   structType,
                                                   new TIdentifier("currentStruct", node.GetName().Line,
                                                                   node.GetName().Pos), null);
                    node.GetFormals().Add(structFormal);
                    data.Locals[(AABlock)node.GetBlock()].Add(structFormal);
                }
                else
                {
                    node.SetStatic(null);
                }
                finalTrans.data.Methods.Add(new SharedData.DeclItem <AMethodDecl>(file, node));
                if (node.GetStatic() == null)
                {
                    OldParentStruct[node] = str;
                }
                //Fix refferences to other struct stuff);
                base.CaseAMethodDecl(node);
                //Will visit later, since it's added after the struct
                //base.CaseAMethodDecl(node);
                //if (str.GetLocals().Count == 0)
                //    str.Parent().RemoveChild(str);
                return;
            }
            AEnrichmentDecl enrichment = Util.GetAncestor <AEnrichmentDecl>(node);

            if (enrichment != null)
            {
                if (node.GetStatic() == null)
                {
                    structMethods.Add(node);
                }
                //Move the method outside the struct
                enrichment.RemoveChild(node);
                AASourceFile file = (AASourceFile)enrichment.Parent();
                int          i    = file.GetDecl().IndexOf(enrichment);
                file.GetDecl().Insert(i /* + 1*/, node);
                node.GetName().Text = GetUniqueStructMethodName(Util.TypeToIdentifierString(enrichment.GetType()) + "_" + node.GetName().Text);

                if (node.GetStatic() == null)
                {
                    //Add the struct as a parameter
                    PType structType = Util.MakeClone(enrichment.GetType(), finalTrans.data);
                    structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, new TRef("ref"), null, null,
                                                   structType,
                                                   new TIdentifier("currentEnrichment", node.GetName().Line,
                                                                   node.GetName().Pos), null);
                    node.GetFormals().Add(structFormal);
                }
                finalTrans.data.Methods.Add(new SharedData.DeclItem <AMethodDecl>(file, node));
                //Fix refferences to other struct stuff);
                base.CaseAMethodDecl(node);
                //Will visit later, since it's added after the struct
                //base.CaseAMethodDecl(node);
                //if (str.GetLocals().Count == 0)
                //    str.Parent().RemoveChild(str);
                return;
            }
            //Build a list of overloads
            List <AMethodDecl> overloads     = new List <AMethodDecl>();
            List <string>      prefixMatches = new List <string>();

            foreach (SharedData.DeclItem <AMethodDecl> declItem in finalTrans.data.Methods)
            {
                if (!Util.IsSameNamespace(declItem.Decl, node))
                {
                    continue;
                }
                if (declItem.Decl.GetName().Text == node.GetName().Text)
                {
                    overloads.Add(declItem.Decl);
                }
                if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O"))
                {
                    prefixMatches.Add(declItem.Decl.GetName().Text);
                }
            }



            foreach (AMethodDecl method in finalTrans.data.Libraries.Methods)
            {
                if (method.GetBlock() != null || method.GetNative() != null)
                {
                    if (method.GetName().Text == node.GetName().Text)
                    {
                        overloads.Add(method);
                    }
                    if (method.GetName().Text.StartsWith(node.GetName().Text + "O"))
                    {
                        prefixMatches.Add(method.GetName().Text);
                    }
                }
            }

            //Add fields
            foreach (SharedData.DeclItem <AFieldDecl> declItem in finalTrans.data.Fields)
            {
                if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O"))
                {
                    prefixMatches.Add(declItem.Decl.GetName().Text);
                }
            }

            foreach (AFieldDecl field in finalTrans.data.Libraries.Fields)
            {
                if (field.GetName().Text.StartsWith(node.GetName().Text + "O"))
                {
                    prefixMatches.Add(field.GetName().Text);
                }
            }

            //Dont want to hit another method by appending O#
            string postfix = "";

            while (true)
            {
                postfix += "O";
                if (prefixMatches.Any(text => text.StartsWith(node.GetName().Text + postfix)))
                {
                    continue;
                }
                break;
            }

            if (overloads.Count > 1)
            {
                int i = 0;
                foreach (AMethodDecl method in overloads)
                {
                    if (node == finalTrans.mainEntry || (node.GetTrigger() != null && finalTrans.data.HasUnknownTrigger))
                    {
                        continue;
                    }
                    i++;
                    method.GetName().Text += postfix + i;
                }
            }

            if (node != finalTrans.mainEntry && (node.GetTrigger() == null || !finalTrans.data.HasUnknownTrigger))
            {
                node.GetName().Text = namespacePrefix + node.GetName().Text;
            }


            base.CaseAMethodDecl(node);
        }