Пример #1
0
        public override void ExitIfStatement(IfStatement ifStatement)
        {
            var block = (BlockStatement)ifStatement.Parent;
            var trueBranchGotoTarget = new GotoTargetStatement(ifStatement.Context);
            var endGotoTarget        = new GotoTargetStatement(ifStatement.Context);
            var trueBranch           = ifStatement.TrueBranch;
            var falseBranch          = ifStatement.FalseBranch;

            if (falseBranch != null)
            {
                block.AddChildBefore(ifStatement,
                                     new GotoStatement(ifStatement.Context, ifStatement.Condition, trueBranchGotoTarget));
                block.AddChildBefore(ifStatement, falseBranch);
                block.AddChildBefore(ifStatement, new GotoStatement(ifStatement.Context, endGotoTarget));
                block.AddChildBefore(ifStatement, trueBranchGotoTarget);
                block.AddChildBefore(ifStatement, trueBranch);
                block.AddChildBefore(ifStatement, endGotoTarget);
            }
            else
            {
                var condition = new UnaryExpression(ifStatement.Context, new INode[]
                {
                    new Token(ifStatement.Context, "!"),
                    ifStatement.Condition
                });
                block.AddChildBefore(ifStatement, new GotoStatement(ifStatement.Context, condition, endGotoTarget));
                block.AddChildBefore(ifStatement, trueBranch);
                block.AddChildBefore(ifStatement, endGotoTarget);
            }
            ifStatement.Remove();
            BlockFlattener.FlattenAllSubBlocks(block);
        }
Пример #2
0
        public override void EnterForStatement(ForStatement forStatement)
        {
            var block           = (BlockStatement)forStatement.Parent;
            var addedStatements = new List <IStatement>();

            var allowedConditionOperators = new[] { "==", "!=", "<", ">", "<=", ">=" };
            var allowedUpdateOperators    = new[] { "+", "-", "*", "/", "%" };

            if (forStatement.Variables.Count() == 1 &&
                forStatement.Variables.Single() is VariableDeclaration singleVariable &&
                singleVariable.Type is NumberType &&
                singleVariable.InitExpression is NumberLiteral initLiteral &&
                !forStatement.InitExpressions.Any() &&
                forStatement.Condition is BinaryExpression condition &&
                condition.Left is SimpleNameExpression conditionVar &&
                conditionVar.Declaration == singleVariable &&
                condition.Right is NumberLiteral &&
                allowedConditionOperators.Contains(condition.Operator.Text) &&
                forStatement.NextExpressions.Count() == 1 &&
                forStatement.NextExpressions.Single() is AssignmentExpression update &&
                update.Left is SimpleNameExpression updateVarWrite &&
                updateVarWrite.Declaration == singleVariable &&
                update.Right is BinaryExpression updateBinaryExpression &&
                allowedUpdateOperators.Contains(updateBinaryExpression.Operator.Text) &&
                updateBinaryExpression.Left is SimpleNameExpression updateVarRead &&
                updateVarRead.Declaration == singleVariable &&
                updateBinaryExpression.Right is NumberLiteral &&
                CountIterations(initLiteral, condition, updateBinaryExpression) is List <double> iterations)
            {
                var breakGotoTarget = new GotoTargetStatement(forStatement.Context);
                foreach (var iteration in iterations)
                {
                    var continueGotoTarget = new GotoTargetStatement(forStatement.Context);
                    var clone = AstCloner.Clone(forStatement);
                    ReplaceContinueAndBreakStatements(
                        clone,
                        new GotoStatement(clone.Context, breakGotoTarget),
                        new GotoStatement(clone.Context, continueGotoTarget));

                    var variable = clone.Variables.Single();
                    variable.InitExpression.ReplaceWith(new NumberLiteral(variable.Context, iteration));
                    var variableDeclarationStatement = new VariableDeclarationStatement(variable.Context, variable);
                    block.AddChildBefore(forStatement, variableDeclarationStatement);
                    block.AddChildBefore(forStatement, clone.Body);
                    block.AddChildBefore(forStatement, continueGotoTarget);


                    addedStatements.Add(variableDeclarationStatement);
                    addedStatements.Add(clone.Body);
                    addedStatements.Add(continueGotoTarget);
                }
                block.AddChildBefore(forStatement, breakGotoTarget);
                addedStatements.Add(breakGotoTarget);

                forStatement.Remove();
            }
Пример #3
0
        //private void ReplaceGenerics()

        private void ReplaceReturnStatements(INode node, GotoTargetStatement gotoTarget, VariableDeclaration returnValueVar)
        {
            if (!(node is IStatement))
            {
                return;
            }
            switch (node)
            {
            case ReturnStatement returnStatement:
                var block = (BlockStatement)returnStatement.Parent;
                if (returnValueVar != null)
                {
                    block.AddChildBefore(returnStatement, new ExpressionStatement(
                                             returnStatement.Context,
                                             new AssignmentExpression(
                                                 returnStatement.Context,
                                                 new INode[]
                    {
                        new SimpleNameExpression(returnStatement.Context, returnValueVar.Name)
                        {
                            Declaration = returnValueVar,
                            Type        = returnValueVar.Type
                        },
                        new AssignmentOperator(returnStatement.Context, "="),
                        returnStatement.Value
                    })
                                             ));
                }
                block.AddChildBefore(returnStatement, new GotoStatement(returnStatement.Context, gotoTarget));
                returnStatement.Remove();
                return;
            }
            //Any other statement
            foreach (var child in node.Children.ToList())
            {
                ReplaceReturnStatements(child, gotoTarget, returnValueVar);
            }
        }
Пример #4
0
 public override INode VisitGotoTargetStatement(GotoTargetStatement gotoTargetStatement)
 {
     return(new GotoTargetStatement(gotoTargetStatement.Context));
 }
Пример #5
0
 public virtual void ExitGotoTargetStatement(GotoTargetStatement gotoTargetStatement)
 {
 }
Пример #6
0
 public virtual void EnterGotoTargetStatement(GotoTargetStatement gotoTargetStatement)
 {
 }
Пример #7
0
        private void UnwrapMethodInvocation(MethodInvocationExpression invocation, MethodDeclaration declaration)
        {
            if (invocation.Parent == null)
            {
                return;
            }

            var context            = invocation.Context;
            var parentStatement    = invocation.NearestAncestorOfType <IStatement>();
            var discardReturnValue = invocation.Parent is ExpressionStatement;
            var block = (BlockStatement)parentStatement.Parent;

            var addedStatements = new List <IStatement>();
            VariableDeclaration returnValueVar = null;

            if (!discardReturnValue)
            {
                returnValueVar = new VariableDeclaration(
                    context,
                    declaration.Name + NumberWheel.Next(),
                    new INode[] { AstCloner.Clone(declaration.ReturnType) });
                var variableDeclarationStatement = new VariableDeclarationStatement(context, returnValueVar);
                block.AddChildBefore(parentStatement, variableDeclarationStatement);
                block.VariableDeclarations.Add(returnValueVar);
                invocation.ReplaceWith(new SimpleNameExpression(context, returnValueVar.Name)
                {
                    Type        = returnValueVar.Type,
                    Declaration = returnValueVar
                });
                addedStatements.Add(variableDeclarationStatement);
            }
            else
            {
                invocation.Remove();
            }


            var clonedDeclaration = AstCloner.Clone(declaration);
            var parameters        = clonedDeclaration.Variables.ToList();
            var arguments         = invocation.Arguments.ToList();

            for (int i = 0; i < parameters.Count; i++)
            {
                if (arguments.Count > i)
                {
                    if (parameters[i].InitExpression != null)
                    {
                        parameters[i].InitExpression.ReplaceWith(arguments[i]);
                    }
                    else
                    {
                        parameters[i].AddChild(arguments[i]);
                    }
                }
                parameters[i].Remove();
                parameters[i].Name += NumberWheel.Next();
                var variableDeclarationStatement = new VariableDeclarationStatement(parameters[i].Context, parameters[i]);
                block.AddChildBefore(parentStatement, variableDeclarationStatement);
                block.VariableDeclarations.Add(parameters[i]);
                addedStatements.Add(variableDeclarationStatement);
            }

            foreach (var expression in clonedDeclaration.AllDescendantsAndSelf().OfType <SimpleNameExpression>())
            {
                var index = parameters.IndexOf(expression.Declaration);
                if (index == -1)
                {
                    continue;
                }
                expression.Name = parameters[index].Name;
            }

            var body = clonedDeclaration.Body;

            block.AddChildBefore(parentStatement, body);
            addedStatements.Add(body);
            var gotoTarget = new GotoTargetStatement(invocation.Context);

            block.AddChildBefore(parentStatement, gotoTarget);
            addedStatements.Add(gotoTarget);

            ReplaceReturnStatements(clonedDeclaration.Body, gotoTarget, returnValueVar);

            if (discardReturnValue)
            {
                parentStatement.Remove();
            }

            foreach (var subInvocation in addedStatements.SelectMany(x => x.AllDescendantsAndSelf()).OfType <MethodInvocationExpression>().ToList())
            {
                var subTarget = ((MethodReferenceType)subInvocation.Base.Type).Declaration;
                UnwrapMethodInvocation(subInvocation, subTarget);
            }
            BlockFlattener.FlattenAllSubBlocks(block);
        }
Пример #8
0
 public virtual T VisitGotoTargetStatement(GotoTargetStatement gotoTargetStatement)
 {
     return(VisitChildren(gotoTargetStatement));
 }