public static bool Parse(AMethodDecl method)
        {
            StatementRemover remover = new StatementRemover();

            method.Apply(remover);
            return(remover.changedSomething);
        }
 public override void CaseAMethodDecl(AMethodDecl node)
 {
     if (node.GetInline() == null && node.GetTrigger() == null && !(data.ConstructorMap.ContainsValue(node) && !inlineConstructors) && node != finalTrans.mainEntry)
     {
         CountStatements counter = new CountStatements();
         node.Apply(counter);
         if (counter.Count <= 2)
         {
             //Don't inline if it has a recurssive call to itself
             FindRecurssiveCall recurssiveCallSearcher = new FindRecurssiveCall(node, data);
             node.Apply(recurssiveCallSearcher);
             if (!recurssiveCallSearcher.InlinedCallToItself)
             {
                 node.SetInline(new TInline("inline"));
             }
         }
     }
     base.CaseAMethodDecl(node);
 }
                public override void CaseASimpleInvokeExp(ASimpleInvokeExp node)
                {
                    AMethodDecl target = data.SimpleMethodLinks[node];

                    if (target == initialMethod)
                    {
                        InlinedCallToItself = true;
                    }
                    else if (target.GetInline() != null)
                    {
                        target.Apply(this);
                    }
                    base.CaseASimpleInvokeExp(node);
                }
示例#4
0
        public override void CaseAOperatorDecl(AOperatorDecl node)
        {
            AMethodDecl replacer = new AMethodDecl(node.GetVisibilityModifier(), null, node.GetStatic(), null, null,
                                                   null, node.GetReturnType(),
                                                   new TIdentifier(""), new ArrayList(),
                                                   node.GetBlock());

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

            node.ReplaceBy(replacer);
            replacer.Apply(this);
        }
示例#5
0
        public override void CaseASimpleInvokeExp(ASimpleInvokeExp node)
        {
            AMethodDecl target = data.SimpleMethodLinks[node];

            for (int i = 0; i < node.GetArgs().Count; i++)
            {
                PExp arg = (PExp)node.GetArgs()[i];
                currentLocal = null;
                arg.Apply(this);
                if (currentLocal != null && target.GetFormals().Cast <AALocalDecl>().ToList()[i].GetRef() != null)
                {
                    ALocalLvalue local = currentLocal;
                    target.Apply(this);
                    if (target.GetFormals().Cast <AALocalDecl>().ToList()[i].GetRef() != null)
                    {
                        AALocalDecl decl = data.LocalLinks[local];
                        NeededRefs[Util.GetAncestor <AMethodDecl>(node)].Add(decl);
                    }
                }
            }
        }
        public static List <AABlock> Inline(ASimpleInvokeExp node, FinalTransformations finalTrans)
        {
            /*if (Util.GetAncestor<AMethodDecl>(node) != null && Util.GetAncestor<AMethodDecl>(node).GetName().Text == "UIChatFrame_LeaveChannel")
             *  node = node;*/

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

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


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

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

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



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

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


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


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

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

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

            outerBlock.GetStatements().Add(stm);

            AALocalDecl methodReturnerVar = null;

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

            AABlock afterBlock = new AABlock();

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

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

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


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

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

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

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

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

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

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

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

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

            GetNonBlockStm stmFinder = new GetNonBlockStm(false);

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

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

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

            pBlock = (AABlock)pStm.Parent();

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

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

                node.ReplaceBy(exp);
            }
            return(new List <AABlock>()
            {
                outerBlock
            });
        }
示例#7
0
        public static void Parse(FinalTransformations finalTrans)
        {
            SharedData data = finalTrans.data;

            for (int i = 0; i < data.Methods.Count; i++)
            {
                for (int j = i + 1; j < data.Methods.Count; j++)
                {
                    AMethodDecl m1       = data.Methods[i].Decl;
                    AMethodDecl m2       = data.Methods[j].Decl;
                    bool        switched = false;
                    if (finalTrans.mainEntry == m1 || m1.GetTrigger() != null)
                    {
                        if (finalTrans.mainEntry == m2 || m2.GetTrigger() != null)
                        {
                            continue;
                        }
                    }
                    else if (finalTrans.mainEntry == m2 || m2.GetTrigger() != null)
                    {
                        AMethodDecl temp = m1;
                        m1       = m2;
                        m2       = temp;
                        switched = true;
                    }

                    MergeSameMethods merger = new MergeSameMethods(m2, data);
                    m1.Apply(merger);
                    if (merger.canMerge)
                    {
                        merger.otherNode = m1;
                        m2.Apply(merger);
                        if (merger.canMerge)
                        {
                            var arr = data.SimpleMethodLinks.ToArray();
                            foreach (KeyValuePair <ASimpleInvokeExp, AMethodDecl> link in arr)
                            {
                                if (link.Value == m2)
                                {
                                    data.SimpleMethodLinks[link.Key] = m1;
                                    link.Key.SetName(new TIdentifier(m1.GetName().Text));
                                }
                            }


                            m2.Parent().RemoveChild(m2);
                            if (switched)
                            {
                                data.Methods.RemoveAt(i);
                                i--;
                                break;
                            }
                            else
                            {
                                data.Methods.RemoveAt(j);
                                j--;
                                continue;
                            }
                        }
                    }
                }
            }
        }
示例#8
0
        private void MakeInitializerInvokes()
        {
            AABlock      block = (AABlock)mainEntry.GetBlock();
            AASourceFile file  = Util.GetAncestor <AASourceFile>(mainEntry);
            AMethodDecl  invokeMethod;

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

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

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

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

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

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

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


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



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

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

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


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


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

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

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

                block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), assignment));
            }
            block.RemoveChild(mainEntryFieldInitBlock);
            block.GetStatements().Insert(0, mainEntryFieldInitBlock);
        }
示例#9
0
 public Parser(AMethodDecl start)
 {
     start.Apply(this);
 }
        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 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);
        }