Пример #1
0
        private void MoveOutOfClass(MethodDeclaration methodDeclaration)
        {
            var classDeclaration = (ClassDeclaration)methodDeclaration.Parent;

            if (!methodDeclaration.Modifiers.Contains(MemberModifier.Static))
            {
                var thisParameter = new VariableDeclaration(
                    methodDeclaration.Context,
                    "this" + NumberWheel.Next(),
                    new ReferenceType(methodDeclaration.Context, methodDeclaration.Parent).Yield()
                    );
                methodDeclaration.AddChildBefore(methodDeclaration.Variables.FirstOrDefault() ?? (INode)methodDeclaration.Body, thisParameter);
                ReplaceThisWithReferencesToVariable(methodDeclaration, thisParameter);
            }
            var classDeclarationParent = classDeclaration.Parent;

            methodDeclaration.Remove();
            classDeclarationParent.AddChildAfter(classDeclaration, methodDeclaration);
        }
Пример #2
0
        public override void ExitAssignmentExpression(AssignmentExpression assignmentExpression)
        {
            if (assignmentExpression.Operator.Value != "=")
            {
                var rightSide = assignmentExpression.Right;
                rightSide.Remove();
                var leftClone = AstCloner.Clone(assignmentExpression.Left);
                switch (leftClone)
                {
                case SimpleNameExpression simpleNameExpression:
                    if (simpleNameExpression.Declaration is SetterDeclaration)
                    {
                        var classDeclaration = (ClassDeclaration)simpleNameExpression.Declaration.Parent;
                        var getterSetter     = classDeclaration.GettersAndSetters.Single(x => x.Setter == simpleNameExpression.Declaration);
                        simpleNameExpression.Declaration = getterSetter.Getter;
                    }
                    break;

                case MemberExpression memberExpression:
                    if (memberExpression.Declaration is SetterDeclaration)
                    {
                        var classDeclaration = (ClassDeclaration)memberExpression.Declaration.Parent;
                        var getterSetter     = classDeclaration.GettersAndSetters.Single(x => x.Setter == memberExpression.Declaration);
                        memberExpression.Declaration = getterSetter.Getter;
                    }
                    break;
                }
                assignmentExpression.AddChild(
                    new BinaryExpression(assignmentExpression.Context,
                                         new INode[]
                {
                    leftClone,
                    new Token(assignmentExpression.Context, assignmentExpression.Operator.Value.Substring(0, assignmentExpression.Operator.Value.Length - 1)),
                    rightSide
                }));
                assignmentExpression.Operator.Value = "=";
            }

            if (!(assignmentExpression.Parent is ExpressionStatement || assignmentExpression.Parent is ForStatement || assignmentExpression.Parent is ForeachStatement))
            {
                var statement = assignmentExpression.NearestAncestorOfType <IStatement>();
                var block     = (BlockStatement)statement.Parent;
                var variable  = new VariableDeclaration(assignmentExpression.Context,
                                                        "var" + NumberWheel.Next(),
                                                        new INode[]
                {
                    assignmentExpression.Type.Wrap(assignmentExpression.Context),
                    assignmentExpression.Right
                })
                {
                    VariableType = VariableType.Const
                };
                block.VariableDeclarations.Add(variable);
                block.AddChildBefore(statement, new VariableDeclarationStatement(assignmentExpression.Context, variable));
                block.AddChildBefore(statement, new ExpressionStatement(assignmentExpression.Context,
                                                                        new AssignmentExpression(
                                                                            assignmentExpression.Context,
                                                                            new INode[]
                {
                    assignmentExpression.Left,
                    assignmentExpression.Operator,
                    new SimpleNameExpression(assignmentExpression.Context, variable.Name)
                    {
                        Declaration = variable,
                        Type        = variable.Type
                    },
                })
                {
                    Type = assignmentExpression.Type
                })
                                     );
                assignmentExpression.ReplaceWith(
                    new SimpleNameExpression(assignmentExpression.Context, variable.Name)
                {
                    Declaration = variable,
                    Type        = variable.Type
                });
            }
        }
Пример #3
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);
        }
Пример #4
0
        public override void EnterForeachStatement(ForeachStatement foreachStatement)
        {
            var listVariable = new VariableDeclaration(
                foreachStatement.Context,
                "list" + NumberWheel.Next(),
                new INode[]
            {
                AstCloner.Clone((GenericType)foreachStatement.List.Type),
                foreachStatement.List
            });
            var indexVariable = new VariableDeclaration(
                foreachStatement.Context,
                "index" + NumberWheel.Next(),
                new INode[]
            {
                new NumberType(foreachStatement.Context),
                new NumberLiteral(foreachStatement.Context, "0")
            });

            var condition = new BinaryExpression(
                foreachStatement.Context,
                new INode[]
            {
                new SimpleNameExpression(foreachStatement.Context, indexVariable.Name)
                {
                    Declaration = indexVariable,
                    Type        = indexVariable.Type
                },
                new Token(foreachStatement.Context, "<"),
                NativeMethods.ArrayCount(
                    foreachStatement.Context,
                    new SimpleNameExpression(foreachStatement.Context, listVariable.Name)
                {
                    Declaration = listVariable,
                    Type        = listVariable.Type
                })
            });
            var update = new AssignmentExpression(
                foreachStatement.Context,
                new INode[]
            {
                new SimpleNameExpression(foreachStatement.Context, indexVariable.Name)
                {
                    Declaration = indexVariable,
                    Type        = indexVariable.Type
                },
                new AssignmentOperator(foreachStatement.Context, "="),
                new BinaryExpression(
                    foreachStatement.Context,
                    new INode[]
                {
                    new SimpleNameExpression(foreachStatement.Context, indexVariable.Name)
                    {
                        Declaration = indexVariable,
                        Type        = indexVariable.Type
                    },
                    new Token(foreachStatement.Context, "+"),
                    new NumberLiteral(foreachStatement.Context, "1")
                }),
            });
            var forStatement = new ForStatement(
                foreachStatement.Context,
                new[]
            {
                listVariable,
                indexVariable
            },
                new IExpression[0],
                condition,
                update.Yield(),
                foreachStatement.Body);
            var elmVariable = foreachStatement.Variable;

            elmVariable.AddChild(
                NativeMethods.ArrayIndex(
                    foreachStatement.Context,
                    new SimpleNameExpression(foreachStatement.Context, listVariable.Name)
            {
                Declaration = listVariable,
                Type        = listVariable.Type
            },
                    new SimpleNameExpression(foreachStatement.Context, indexVariable.Name)
            {
                Declaration = indexVariable,
                Type        = indexVariable.Type
            })
                );
            forStatement.Body.AddChildFirst(new VariableDeclarationStatement(foreachStatement.Context, elmVariable));
            foreachStatement.ReplaceWith(forStatement);
            Visit(forStatement);
            skipChildren = true;
        }