Ejemplo n.º 1
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
                });
            }
        }