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"));
            }
        }
 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);
     }
 }
        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());
        }
 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()), LocRM.GetString("ErrorText63")));
         }
         else if (finalTrans.mainEntry != null)
         {
             multipleEntryCandidates.Add(new ErrorCollection.Error(finalTrans.mainEntry.GetName(), Util.GetAncestor<AASourceFile>(finalTrans.mainEntry.GetName()), LocRM.GetString("ErrorText63")));
             multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), LocRM.GetString("ErrorText63")));
             //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);
 }
        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);
        }
        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 override void CaseAMethodDecl(AMethodDecl node)
 {
     InAMethodDecl(node);
     if (node.GetBlock() != null)
     {
         node.GetBlock().Apply(this);
     }
     {
         Object[] temp = new Object[node.GetFormals().Count];
         node.GetFormals().CopyTo(temp, 0);
         for (int i = temp.Length - 1; i >= 0; i--)
         {
             ((PLocalDecl)temp[i]).Apply(this);
         }
     }
     if (node.GetName() != null)
     {
         node.GetName().Apply(this);
     }
     if (node.GetReturnType() != null)
     {
         node.GetReturnType().Apply(this);
     }
     if (node.GetDelegate() != null)
     {
         node.GetDelegate().Apply(this);
     }
     if (node.GetInline() != null)
     {
         node.GetInline().Apply(this);
     }
     if (node.GetNative() != null)
     {
         node.GetNative().Apply(this);
     }
     if (node.GetStatic() != null)
     {
         node.GetStatic().Apply(this);
     }
     if (node.GetTrigger() != null)
     {
         node.GetTrigger().Apply(this);
     }
     if (node.GetVisibilityModifier() != null)
     {
         node.GetVisibilityModifier().Apply(this);
     }
     OutAMethodDecl(node);
 }
예제 #8
0
        public override void CaseAOperatorDecl(AOperatorDecl node)
        {
            if (node.GetFormals().Count != 2)
                errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText182")));
            Token token = null;
            if (node.GetOperator() is APlusBinop)
                token = ((APlusBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AMinusBinop)
                token = ((AMinusBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is ADivideBinop)
                token = ((ADivideBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is ATimesBinop)
                token = ((ATimesBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AModuloBinop)
                token = ((AModuloBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AEqBinop)
                token = ((AEqBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is ANeBinop)
                token = ((ANeBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is ALtBinop)
                token = ((ALtBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is ALeBinop)
                token = ((ALeBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AGtBinop)
                token = ((AGtBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AGeBinop)
                token = ((AGeBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AGtBinop)
                token = ((AGtBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AAndBinop)
                token = ((AAndBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AOrBinop)
                token = ((AOrBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is AXorBinop)
                token = ((AXorBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is ALBitShiftBinop)
                token = ((ALBitShiftBinop)node.GetOperator()).GetToken();
            else if (node.GetOperator() is ARBitShiftBinop)
                token = ((ARBitShiftBinop)node.GetOperator()).GetToken();

            AMethodDecl replacer = new AMethodDecl(node.GetVisibilityModifier(), null, node.GetStatic(), null, null,
                                                   null, node.GetReturnType(),
                                                   new TIdentifier(token.Text, token.Line, token.Pos), new ArrayList(),
                                                   node.GetBlock());
            while (node.GetFormals().Count > 0)
                replacer.GetFormals().Add(node.GetFormals()[0]);

            node.ReplaceBy(replacer);
            replacer.Apply(this);
        }
        private void CheckInvoke(ASimpleInvokeExp node, AMethodDecl target)
        {
            if (target.GetInline() != null)
            {
                AMethodDecl pMethod = Util.GetAncestor<AMethodDecl>(node);
                AConstructorDecl pConstructor = Util.GetAncestor<AConstructorDecl>(node);
                ADeconstructorDecl pDeconstructor = Util.GetAncestor<ADeconstructorDecl>(node);
                if (pMethod == null && !Util.HasAncestor<AConstructorDecl>(node) &&
                    !Util.HasAncestor<ADeconstructorDecl>(node) && !Util.HasAncestor<APropertyDecl>(node))
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText131")));
                }
                else if (pMethod != null && !InlineMethodCalls[pMethod].Contains(target))
                    InlineMethodCalls[pMethod].Add(target);
            }

            //For each formal marked as ref or out, the argument must be a non-const variable
            for (int i = 0; i < node.GetArgs().Count; i++)
            {
                AALocalDecl formal = (AALocalDecl)target.GetFormals()[i];
                if (formal.GetRef() != null || formal.GetOut() != null)
                {
                    PExp exp = (PExp)node.GetArgs()[i];
                    while (true)
                    {
                        PLvalue lvalue;
                        if (exp is ALvalueExp)
                        {
                            lvalue = ((ALvalueExp)exp).GetLvalue();
                        }
                        else if (exp is AAssignmentExp)
                        {
                            lvalue = ((AAssignmentExp)exp).GetLvalue();
                        }
                        else
                        {
                            errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText130")));
                            break;
                        }
                        if (lvalue is ALocalLvalue)
                        {
                            if (data.LocalLinks[(ALocalLvalue)lvalue].GetConst() != null)
                                errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText132")));
                            break;
                        }
                        if (lvalue is AFieldLvalue)
                        {
                            if (data.FieldLinks[(AFieldLvalue)lvalue].GetConst() != null)
                                errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText132")));
                            break;
                        }
                        if (lvalue is AStructFieldLvalue)
                        {
                            if (data.StructMethodFieldLinks[(AStructFieldLvalue)lvalue].GetConst() != null)
                                errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText132")));
                            break;
                        }
                        if (lvalue is AThisLvalue)
                            break;
                        if (lvalue is AStructLvalue)
                        {
                            exp = ((AStructLvalue)lvalue).GetReceiver();
                            continue;
                        }
                        if (lvalue is AArrayLvalue)
                        {
                            exp = ((AArrayLvalue)lvalue).GetBase();
                            continue;
                        }
                        if (lvalue is APointerLvalue)
                        {
                            exp = ((APointerLvalue)lvalue).GetBase();
                            continue;
                        }
                        throw new Exception("Unexpected lvalue");
                    }
                }
            }
        }
        public override void OutAMethodDecl(AMethodDecl node)
        {
            if (node.GetTrigger() != null)
            {
                bool validSignature = IsBoolType(node.GetReturnType());
                validSignature &= node.GetFormals().Count == 2;
                foreach (AALocalDecl formal in node.GetFormals())
                {
                    validSignature &= IsBoolType(formal.GetType());
                    validSignature &= formal.GetRef() == null && formal.GetOut() == null;
                }
                if (!validSignature)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile,
                                                         LocRM.GetString("ErrorText156")));
                }
            }

            //Check that all code paths return a value
            if (!(node.GetReturnType() is AVoidType))
            {
                CheckReturns returnChecker = new CheckReturns();
                node.GetBlock().Apply(returnChecker);
                if (!returnChecker.Returned)
                {
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText157")));
                }
            }

            //If the return type or the type of any formals is a private struct, and the method is a public context, give an error
            {
                AStructDecl pStruct = Util.GetAncestor<AStructDecl>(node);
                //Is public context
                if (pStruct == null && node.GetVisibilityModifier() is APublicVisibilityModifier ||
                    pStruct != null && pStruct.GetVisibilityModifier() is APublicVisibilityModifier && !(node.GetVisibilityModifier() is APrivateVisibilityModifier))
                {
                    PType type = node.GetReturnType();
                    int i = 0;
                    FindPrivateTypes finder = new FindPrivateTypes(data);
                    while (true)
                    {
                        type.Apply(finder);

                        if (i == node.GetFormals().Count)
                            break;
                        AALocalDecl formal = (AALocalDecl) node.GetFormals()[i];
                        type = formal.GetType();
                        i++;
                    }

                    if (finder.PrivateTypes.Count > 0)
                    {
                        List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                        List<PDecl> usedDecls = new List<PDecl>();
                        foreach (ANamedType namedType in finder.PrivateTypes)
                        {
                            if (data.StructTypeLinks.ContainsKey(namedType))
                            {
                                AStructDecl decl = data.StructTypeLinks[namedType];
                                if (usedDecls.Contains(decl))
                                    continue;
                                usedDecls.Add(decl);
                                subErrors.Add(new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText64")));
                            }
                            else if (data.DelegateTypeLinks.ContainsKey(namedType))
                            {
                                AMethodDecl decl = data.DelegateTypeLinks[namedType];
                                if (usedDecls.Contains(decl))
                                    continue;
                                usedDecls.Add(decl);
                                subErrors.Add(new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText154")));
                            }
                        }

                        errors.Add(new ErrorCollection.Error(node.GetName(), LocRM.GetString("ErrorText155"), false, subErrors.ToArray()));
                    }
                }
            }

            base.OutAMethodDecl(node);
        }
 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 CaseAMethodDecl(AMethodDecl node)
        {
            if (firstMethodCall)
                StatementRemover.Parse(node);
            firstMethodCall = false;

            before.Clear();
            after.Clear();
            uses.Clear();
            intersectingLocals.Clear();
            definedLocals.Clear();
            renamedLocals.Clear();
            assigns.Clear();
            changes = false;

            //Make uses
            setUses = true;
            base.CaseAMethodDecl(node);
            setUses = false;

            //Build a list of what's visible
            do
            {
                changes = false;
                base.CaseAMethodDecl(node);
            } while (changes);

            setSpans = true;
            base.CaseAMethodDecl(node);
            setSpans = false;

            //Join locals of same type, unless they are both parameters or they are listed as intersecting
            for (int i = 0; i < definedLocals.Count; i++)
            {
                for (int j = i + 1; j < definedLocals.Count; j++)
                {
                    AALocalDecl decl1 = definedLocals[i];
                    AALocalDecl decl2 = definedLocals[j];

                    if (Util.TypeToString(decl1.GetType()) == Util.TypeToString(decl2.GetType()) &&
                        !intersectingLocals.Contains(new Pair(decl1, decl2)))
                    {
                        if (Util.GetAncestor<AABlock>(decl1) == null &&
                            Util.GetAncestor<AABlock>(decl2) == null)
                            continue;

                        AALocalDecl replacement = decl1;
                        AALocalDecl replaced = decl2;

                        //Dont replace the parameter
                        if (Util.GetAncestor<AABlock>(replaced) == null)
                        {
                            replacement = decl2;
                            replaced = decl1;
                            i--;
                        }
                        j--;

                        renamedLocals.Add(replaced, replacement);
                        definedLocals.Remove(replaced);
                        foreach (Pair pair in intersectingLocals)
                        {
                            if (pair.Local1 == replaced)
                                pair.Local1 = replacement;
                            if (pair.Local2 == replaced)
                                pair.Local2 = replacement;
                        }

                        //Assign defaults
                        if (replaced.GetInit() == null)
                        {
                            ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(replaced.GetName().Text));
                            finalTrans.data.LocalLinks[lvalue] = replaced;
                            finalTrans.data.LvalueTypes[lvalue] = replaced.GetType();
                            List<PStm> statements = AssignDefault(lvalue);
                            PStm pStm = Util.GetAncestor<PStm>(replaced);
                            AABlock pBlock = (AABlock) pStm.Parent();
                            foreach (PStm statement in statements)
                            {
                                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), statement);
                            }
                            pBlock.RemoveChild(pStm);
                        }
                        else
                        {
                            //Make an assignment expression instead
                            ALocalDeclStm declStm = (ALocalDeclStm)replaced.Parent();
                            ALocalLvalue lvalue = new ALocalLvalue((TIdentifier)replaced.GetName().Clone());
                            finalTrans.data.LvalueTypes[lvalue] = replaced.GetType();
                            AAssignmentExp exp = new AAssignmentExp(new TAssign("=", lvalue.GetName().Line, lvalue.GetName().Pos), lvalue, replaced.GetInit());
                            AExpStm expStm = new AExpStm(declStm.GetToken(), exp);
                            declStm.ReplaceBy(expStm);
                            finalTrans.data.LvalueTypes[lvalue] = replacement.GetType();
                            finalTrans.data.ExpTypes[exp] = replacement.GetType();
                            finalTrans.data.LocalLinks[lvalue] = replacement;
                        }
                    }
                }
            }

            //Unique names
            List<string> names = new List<string>();
            //Avoid clash with methods/fields/structs
            names.AddRange(finalTrans.data.Methods.Select(declItem => declItem.Decl.GetName().Text));
            names.AddRange(finalTrans.data.Fields.Select(declItem => declItem.Decl.GetName().Text));
            names.AddRange(finalTrans.data.Structs.Select(declItem => declItem.Decl.GetName().Text));
            foreach (AALocalDecl local in definedLocals)
            {
                string name = local.GetName().Text;
                int version = 1;
                while (names.Contains(name))
                {
                    version++;
                    name = local.GetName().Text + version;
                }
                local.GetName().Text = name;
                names.Add(name);
            }

            //Move defined locals to the start of the method
            foreach (AALocalDecl formal in node.GetFormals())
            {
                definedLocals.Remove(formal);
            }
            AABlock block = (AABlock)node.GetBlock();
            for (int i = 0; i < block.GetStatements().Count; i++)
            {
                ALocalDeclStm stm;
                if (block.GetStatements()[i] is ALocalDeclStm)
                {
                    stm = (ALocalDeclStm)block.GetStatements()[i];
                    definedLocals.Remove((AALocalDecl)stm.GetLocalDecl());
                    continue;
                }
                //Add the rest at i
                if (definedLocals.Count == 0)
                    break;
                AALocalDecl decl = definedLocals[0];
                definedLocals.RemoveAt(0);

                if (decl.GetInit() == null)
                {
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(decl.GetName().Text));
                    finalTrans.data.LocalLinks[lvalue] = decl;
                    finalTrans.data.LvalueTypes[lvalue] = decl.GetType();
                    List<PStm> statements = AssignDefault(lvalue);
                    PStm pStm = Util.GetAncestor<PStm>(decl);
                    AABlock pBlock = (AABlock) pStm.Parent();
                    foreach (PStm statement in statements)
                    {
                        pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), statement);
                    }
                    pBlock.RemoveChild(pStm);
                }
                else
                {
                    //Make an assignment expression before moving
                    stm = (ALocalDeclStm)decl.Parent();
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(decl.GetName().Text));
                    finalTrans.data.LvalueTypes[lvalue] = decl.GetType();
                    AAssignmentExp exp = new AAssignmentExp(new TAssign("="), lvalue, decl.GetInit());
                    AExpStm expStm = new AExpStm(new TSemicolon(";"), exp);
                    stm.ReplaceBy(expStm);
                    finalTrans.data.LvalueTypes[lvalue] = decl.GetType();
                    finalTrans.data.ExpTypes[exp] = decl.GetType();
                    finalTrans.data.LocalLinks[lvalue] = decl;
                }

                stm = new ALocalDeclStm(new TSemicolon(";"), decl);
                block.GetStatements().Insert(i, stm);
            }

            fixRefferences = true;
            base.CaseAMethodDecl(node);
            fixRefferences = false;

            //If we have an assignment to a local where the stored result is never used, remove the assignment

            //Since we changed some statements, rebuild stuff
            before.Clear();
            after.Clear();
            uses.Clear();
            intersectingLocals.Clear();
            definedLocals.Clear();
            renamedLocals.Clear();
            assigns.Clear();
            changes = false;

            //Make uses
            setUses = true;
            base.CaseAMethodDecl(node);
            setUses = false;

            //Build a list of what's visible
            do
            {
                changes = false;
                base.CaseAMethodDecl(node);
            } while (changes);

            PStm[] stms = new PStm[before.Keys.Count];
            before.Keys.CopyTo(stms, 0);
            foreach (PStm stm in stms)
            {
                if (assigns[stm] != null && //Assignment exp
                    !after[stm].Contains(assigns[stm]) && //Assignment unused
                    Util.GetAncestor<AMethodDecl>(assigns[stm]) != null &&
                    !(stm is ALocalDeclStm))//It is to a local
                {
                    stm.Apply(new MoveMethodDeclsOut(finalTrans.data));
                    stm.Parent().RemoveChild(stm);
                }
            }

            //Remove foo = foo;
            RemoveStupidAssignments assignmentRemover = new RemoveStupidAssignments(finalTrans.data);
            node.Apply(assignmentRemover);

            //Remove unused local variables
            foreach (AALocalDecl local in definedLocals)
            {
                if (Util.GetAncestor<AAProgram>(local) != null && Util.GetAncestor<AABlock>(local) != null &&
                    !finalTrans.data.LocalLinks.Where(p => p.Value == local).Any(p => Util.GetAncestor<AAProgram>(p.Key) != null))
                    local.Parent().Parent().RemoveChild(local.Parent());
            }

            if (assignmentRemover.RemovedOne)
            {
                CaseAMethodDecl(node);
                return;
            }

            //If an assignment to a variable is completely local, and that assignment is only used once, put the assignment where it is used
            //Since we changed some statements, rebuild stuff
            before.Clear();
            after.Clear();
            uses.Clear();
            intersectingLocals.Clear();
            definedLocals.Clear();
            renamedLocals.Clear();
            assigns.Clear();
            changes = false;

            //Make uses
            setUses = true;
            base.CaseAMethodDecl(node);
            setUses = false;

            //Build a list of what's visible
            do
            {
                changes = false;
                base.CaseAMethodDecl(node);
            } while (changes);
            foreach (KeyValuePair<PStm, AALocalDecl> pair in assigns)
            {
                PStm assignStm = pair.Key;
                AALocalDecl assignVar = pair.Value;
                bool isLocal = Util.IsLocal(assignStm, finalTrans.data);
                bool containsInvokeInPrevStm = false;
                if (assignVar != null && after[assignStm].Contains(assignVar))
                {
                    bool dontMove = false;
                    //First, if there are any conditional parrent statement, where the variable is in live before the stm, then we can't move it
                    PStm condParent = (PStm) Util.GetNearestAncestor(assignStm, typeof (AIfThenStm), typeof (AIfThenElseStm),
                                                                     typeof (AWhileStm));
                    while (condParent != null)
                    {
                        if (before[condParent].Contains(assignVar))
                        {
                            dontMove = true;
                            break;
                        }
                        condParent = (PStm)Util.GetNearestAncestor(condParent.Parent(), typeof(AIfThenStm), typeof(AIfThenElseStm),
                                                                     typeof(AWhileStm));
                    }

                    PStm useStm = null;
                    List<PStm> successors = GetSuccessor(assignStm);
                    bool containsConditionalAssignments = false;
                    while (successors.Count > 0)
                    {
                        if (successors.Count > 500)
                            useStm = useStm;
                        PStm successor = successors[0];
                        successors.RemoveAt(0);
                        if (uses[successor].Contains(assignVar))
                        {
                            if (useStm == null && !containsConditionalAssignments && !(successor is AWhileStm))
                                useStm = successor;
                            else
                            {
                                dontMove = true;
                                break;
                            }
                        }
                        if (after[successor].Contains(assignVar) && !(assigns.ContainsKey(successor) && assigns[successor] == assignVar))
                        {
                            List<PStm> newSuccessors = GetSuccessor(successor);
                            foreach (PStm stm in newSuccessors)
                            {
                                if (!successors.Contains(stm))
                                    successors.Add(stm);
                            }
                        }
                        if (assigns.ContainsKey(successor) && uses[assignStm].Contains(assigns[successor]))
                        {
                            dontMove = true;
                            break;
                        }

                        if (assigns.ContainsKey(successor) && assigns[successor] == assignVar)
                        {
                            condParent = (PStm)Util.GetNearestAncestor(successor, typeof(AIfThenStm), typeof(AIfThenElseStm),
                                                                       typeof(AWhileStm));
                            while (condParent != null)
                            {
                                if (!Util.IsAncestor(assignStm, condParent))
                                {
                                    containsConditionalAssignments = true;
                                    break;
                                }
                                condParent = (PStm)Util.GetNearestAncestor(condParent.Parent(), typeof(AIfThenStm), typeof(AIfThenElseStm),
                                                                             typeof(AWhileStm));
                            }

                            //If we found a usage, and it is inside a while that the assignStm is not inside, but we are inside, don't move
                            if (useStm != null)
                            {
                                AWhileStm whileParant = Util.GetAncestor<AWhileStm>(successor);
                                while (whileParant != null)
                                {
                                    if (Util.IsAncestor(useStm, whileParant) && !Util.IsAncestor(assignStm, whileParant))
                                    {
                                        dontMove = true;
                                        break;
                                    }
                                    whileParant = Util.GetAncestor<AWhileStm>(whileParant.Parent());
                                }
                            }
                        }

                        FindInvoke finder  = new FindInvoke();
                        successor.Apply(finder);
                        if (finder.ContainsInvoke && useStm == null)
                            containsInvokeInPrevStm = true;
                    }

                    if (useStm != null && !dontMove)
                    {
                        //If assignStm is inside an if, and the use stm is not, and there is another assignment
                        //to the same variable in an else block, then don't join
                        AIfThenElseStm ifThenElse = Util.GetAncestor<AIfThenElseStm>(assignStm);
                        while (ifThenElse != null)
                        {
                            if (!Util.IsAncestor(useStm, ifThenElse))
                            {
                                ABlockStm otherBlock;
                                if (Util.IsAncestor(assignStm, ifThenElse.GetThenBody()))
                                    otherBlock = (ABlockStm) ifThenElse.GetElseBody();
                                else
                                    otherBlock = (ABlockStm)ifThenElse.GetThenBody();
                                StmEnum enumerator = new StmEnum(otherBlock);
                                while (enumerator.MoveNext())
                                {
                                    PStm stm = (PStm) enumerator.Current;
                                    if (assigns.ContainsKey(stm) && assigns[stm] == assignVar)
                                    {
                                        dontMove = true;
                                        break;
                                    }
                                }
                                if (dontMove)
                                    break;
                            }
                            ifThenElse = Util.GetAncestor<AIfThenElseStm>(ifThenElse.Parent());
                        }

                        //If the assignStm or useStm is inside a while, it could get complicated
                        //if (Util.HasAncestor<AWhileStm>(assignStm) || Util.HasAncestor<AWhileStm>(useStm))
                        //    dontMove = true;
                    }

                    if (useStm != null && dontMove == false && (isLocal || !containsInvokeInPrevStm))
                    {

                        //Ensure that it is not used twice in this stm
                        FindLvalue finder = new FindLvalue(assignVar, finalTrans.data);
                        useStm.Apply(finder);
                        if (!finder.IsUsedTwice && (isLocal || !finder.HasPrevInvoke))
                        {
                            PExp rightside;
                            if (assignStm is ALocalDeclStm)
                            {
                                rightside = ((AALocalDecl)((ALocalDeclStm)assignStm).GetLocalDecl()).GetInit();
                            }
                            else
                            {
                                rightside = ((AAssignmentExp)((AExpStm)assignStm).GetExp()).GetExp();
                                assignStm.Parent().RemoveChild(assignStm);
                            }
                            if (rightside != null)
                            {
                                finder.Lvalue.Parent().ReplaceBy(rightside);
                                CaseAMethodDecl(node);
                                return;
                            }
                        }
                    }
                }
            }

            if (StatementRemover.Parse(node))
            {
                CaseAMethodDecl(node);
                return;
            }
            firstMethodCall = true;
        }
예제 #13
0
            public override void InAMethodDecl(AMethodDecl node)
            {
                //nullPointers.Clear();
                setPointers.Clear();
                exposedPointers.Clear();
                generatedPointers.Clear();

                //Paremeter pointers are exposed
                foreach (AALocalDecl formal in node.GetFormals())
                {
                    foreach (List<PointerType> pointer in GetAllPointerTypes(formal, formal.GetType()))
                    {
                        exposedPointers.Add(MakePointer(pointer));
                    }
                }
            }
예제 #14
0
            public override void CaseAMethodDecl(AMethodDecl node)
            {
                if (processedMethods.Contains(node))
                    return;
                processedMethods.Add(node);
                //For each bulk copy param, make it a pointer type
                foreach (AALocalDecl formal in node.GetFormals())
                {
                    PType type = formal.GetType();
                    if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null)
                    {
                        if (type is AArrayTempType)
                        {//make dynamic array
                            AArrayTempType aType = (AArrayTempType) type;
                            List<PExp> exps = new List<PExp>();
                            PType newType = new APointerType(new TStar("*"),
                                                             new ADynamicArrayType((TLBracket)aType.GetToken().Clone(),
                                                                         Util.MakeClone(aType.GetType(), data)));
                            /*exps.AddRange(data.ExpTypes.Where(k => k.Value == type).Select(k => k.Key));
                            foreach (PExp exp in exps)
                            {
                                data.ExpTypes[exp] = newType;
                            }*/
                            formal.SetType(newType);
                            foreach (KeyValuePair<ALocalLvalue, AALocalDecl> pair in data.LocalLinks)
                            {
                                if (pair.Value == formal)
                                {//Replace with *lvalue
                                    ALvalueExp innerExp = new ALvalueExp();
                                    APointerLvalue replacement = new APointerLvalue(new TStar("*"), innerExp);
                                    pair.Key.ReplaceBy(replacement);
                                    innerExp.SetLvalue(pair.Key);
                                    data.ExpTypes[innerExp] = data.LvalueTypes[pair.Key] = formal.GetType();
                                    data.LvalueTypes[replacement] = ((APointerType)newType).GetType();

                                    //if (replacement.Parent() is ALvalueExp)
                                    //    data.ExpTypes[(PExp)replacement.Parent()] = data.LvalueTypes[replacement];
                                }
                            }
                        }
                        else
                        {//Make pointer
                            formal.SetType(new APointerType(new TStar("*"), type));
                            foreach (KeyValuePair<ALocalLvalue, AALocalDecl> pair in data.LocalLinks)
                            {
                                if (pair.Value == formal)
                                {//Replace with *lvalue
                                    ALvalueExp innerExp = new ALvalueExp();
                                    APointerLvalue replacement = new APointerLvalue(new TStar("*"), innerExp);
                                    pair.Key.ReplaceBy(replacement);
                                    innerExp.SetLvalue(pair.Key);
                                    data.ExpTypes[innerExp] = data.LvalueTypes[pair.Key] = formal.GetType();
                                    data.LvalueTypes[replacement] = type;
                                }
                            }
                        }
                    }
                }
                if (Util.IsBulkCopy(node.GetReturnType()))
                {
                    PType oldType = node.GetReturnType();
                    PType newType;
                    if (node.GetReturnType() is AArrayTempType)
                    {//make dynamic array
                        AArrayTempType aType = (AArrayTempType) node.GetReturnType();
                        newType = new APointerType(new TStar("*"),
                                                   new ADynamicArrayType((TLBracket) aType.GetToken().Clone(),
                                                                         Util.MakeClone(aType.GetType(), data)));
                        node.SetReturnType(newType);
                    }
                    else
                    {//Make pointer
                        newType = new APointerType(new TStar("*"), node.GetReturnType());
                        node.SetReturnType(newType);
                    }
                    /*List<PExp> exps = new List<PExp>();
                    exps.AddRange(data.ExpTypes.Where(k => k.Value == oldType).Select(k => k.Key));
                    foreach (PExp exp in exps)
                    {
                        data.ExpTypes[exp] = newType;
                    }
                    List<PLvalue> lvalues = new List<PLvalue>();
                    lvalues.AddRange(data.LvalueTypes.Where(k => k.Value == oldType).Select(k => k.Key));
                    foreach (PLvalue lvalue in lvalues)
                    {
                        data.LvalueTypes[lvalue] = newType;
                    }*/
                }
                 	            base.CaseAMethodDecl(node);
            }
예제 #15
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);
                    }
                }
        }
            /*
             * 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);
                    }
                }
            }
        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
        }
        //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);
        }
        /*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);
        }
예제 #20
0
 public override void CaseAMethodDecl(AMethodDecl node)
 {
     //Remove ref and out
     foreach (AALocalDecl formal in node.GetFormals())
     {
         formal.SetRef(null);
         formal.SetOut(null);
     }
     base.CaseAMethodDecl(node);
 }
        public void LoadLibraries(List<DirectoryInfo> libraries)
        {
            LibraryData lib = new LibraryData();

            StreamWriter writer = new StreamWriter(new FileInfo("outputList.txt").Open(FileMode.Create, FileAccess.Write));
            foreach (DirectoryInfo library in libraries)
            {
            retry:
                FileInfo precompFile = new FileInfo(library.FullName + "\\Precompiled.LibraryData");
                /*if (!precompFile.Exists)*/
                CompileLibrary(library, writer);
                IFormatter formatter = new BinaryFormatter();
                Stream stream = precompFile.OpenRead();
                try
                {
                    lib.Join((LibraryData) formatter.Deserialize(stream));
                    stream.Close();
                }
                catch (Exception err)
                {
                    stream.Close();
                    precompFile.Delete();
                    goto retry;
                }
            }
            libraryData = lib;

            {
                List<AMethodDecl> newMethods = new List<AMethodDecl>();
                List<AFieldDecl> newFields = new List<AFieldDecl>();
                XmlTextReader reader = new XmlTextReader(new FileInfo("Galaxy.xml").Open(FileMode.Open, FileAccess.Read));

                while (reader.Read())
                {
                    if (reader.NodeType != XmlNodeType.Element)
                        continue;

                    if (reader.Name == "KeyWord")
                    {
                        if (reader.GetAttribute("func") == null)
                        {
                            AFieldDecl fieldDecl = new AFieldDecl(new APublicVisibilityModifier(), null, null, null, new TIdentifier(reader.GetAttribute("name")), null);
                            newFields.Add(fieldDecl);
                            continue;
                        }
                        AMethodDecl methodDecl = new AMethodDecl();
                        methodDecl.SetName(new TIdentifier(reader.GetAttribute("name")));
                        while (reader.Read())
                        {
                            if (reader.NodeType == XmlNodeType.EndElement)
                            {
                                break;
                            }
                            if (reader.NodeType != XmlNodeType.Element)
                                continue;
                            if (reader.Name != "Param")
                                continue;
                            string type = reader.GetAttribute("name");
                            type = type.Substring(0, type.IndexOf(" "));
                            string name = reader.GetAttribute("name");
                            name = name.Substring(name.IndexOf(" ") + 1);

                            methodDecl.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                        new ANamedType(new TIdentifier(type), null),
                                                                        new TIdentifier(name), null));

                        }
                        if (reader.EOF)
                            break;
                        newMethods.Add(methodDecl);
                    }
                }

                reader.Close();

                List<AMethodDecl> oldMethods = new List<AMethodDecl>();
                oldMethods.AddRange(libraryData.Methods);
                List<AFieldDecl> oldFields = new List<AFieldDecl>();
                oldFields.AddRange(libraryData.Fields);

                //Remove dublicates in old
                for (int i = 0; i < oldMethods.Count; i++)
                {
                    for (int j = i + 1; j < oldMethods.Count; j++)
                    {
                        if (oldMethods[i].GetName().Text == oldMethods[j].GetName().Text)
                        {
                            oldMethods.RemoveAt(j);
                            j--;
                        }
                    }
                }

                for (int i = 0; i < oldFields.Count; i++)
                {
                    for (int j = i + 1; j < oldFields.Count; j++)
                    {
                        if (oldFields[i].GetName().Text == oldFields[j].GetName().Text)
                        {
                            oldFields.RemoveAt(j);
                            j--;
                        }
                    }
                }

                //Remove dublicates in new
                for (int i = 0; i < newMethods.Count; i++)
                {
                    for (int j = i + 1; j < newMethods.Count; j++)
                    {
                        if (newMethods[i].GetName().Text == newMethods[j].GetName().Text)
                        {
                            newMethods.RemoveAt(j);
                            j--;
                        }
                    }
                }

                for (int i = 0; i < newFields.Count; i++)
                {
                    for (int j = i + 1; j < newFields.Count; j++)
                    {
                        if (newFields[i].GetName().Text == newFields[j].GetName().Text)
                        {
                            newFields.RemoveAt(j);
                            j--;
                        }
                    }
                }

                //Remove stuff they agree on
                for (int i = 0; i < newFields.Count; i++)
                {
                    for (int j = 0; j < oldFields.Count; j++)
                    {
                        if (newFields[i].GetName().Text == oldFields[j].GetName().Text)
                        {
                            newFields.RemoveAt(i);
                            oldFields.RemoveAt(j);
                            i--;
                            break;
                        }
                    }
                }
                for (int j = 0; j < oldFields.Count; j++)
                {
                    if (oldFields[j].GetStatic() != null)
                    {
                        oldFields.RemoveAt(j);
                        j--;
                    }
                }
                for (int i = 0; i < newMethods.Count; i++)
                {
                    for (int j = 0; j < oldMethods.Count; j++)
                    {
                        if (newMethods[i].GetName().Text == oldMethods[j].GetName().Text)
                        {
                            newMethods.RemoveAt(i);
                            oldMethods.RemoveAt(j);
                            i--;
                            break;
                        }
                    }
                }
                for (int j = 0; j < oldMethods.Count; j++)
                {
                    if (oldMethods[j].GetStatic() != null ||
                        (oldMethods[j].GetNative() == null && oldMethods[j].GetBlock() == null))
                    {
                        oldMethods.RemoveAt(j);
                        j--;
                    }
                }

            }

            {
                /*StreamWriter writer = new StreamWriter(new FileInfo("outputList.txt").Open(FileMode.Create, FileAccess.Write));
                foreach (AMethodDecl method in libraryData.Methods)
                {
                    string str = "native " + TypeToString(method.GetReturnType()) + " " + method.GetName().Text +
                                 "(";
                    bool first = true;
                    foreach (AALocalDecl formal in method.GetFormals())
                    {
                        if (!first)
                            str += ", ";
                        str += TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                        first = false;
                    }
                    str += ");";

                    writer.WriteLine(str);
                }

                foreach (AFieldDecl field in libraryData.Fields)
                {
                    if (field.GetName().Text == "libNtve_gv__GameUIVisible")
                        writer = writer;
                    writer.WriteLine(TypeToString(field.GetType()) + " " + field.GetName().Text + ";");
                }*/
                writer.Flush();
                writer.Close();
            }
        }
        /// <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;
        }