void AddNewVariable(IVariable variable, Expression initializer, AstNode node)
        {
            var variablePath       = new AccessPath(variable);
            var rightResolveResult = context.Resolve(initializer) as LocalResolveResult;

            if (rightResolveResult != null)
            {
                var rightPath = AccessPath.FromResolveResult(rightResolveResult);
                if (rightPath != null && accessPaths.ContainsKey(rightPath))
                {
                    var rightInitializer = accessPaths [rightPath];
                    ReplacementNodeHelper.AddReplacementAnnotation(rightInitializer, node);
                    accessPaths.Remove(rightPath);
                    accessPaths [variablePath] = rightInitializer;
                    if (rightPath == mainAccessPath)
                    {
                        mainAccessPath = variablePath;
                    }
                }
            }
            else
            {
                accessPaths [variablePath] = ReplacementNodeHelper.CloneWithReplacementAnnotation(initializer, node);
            }
        }
        public AssignmentExpression ConvertToInitializer(AssignmentExpression assignmentExpression, ref IList <AstNode> statements)
        {
            if (assignmentExpression == null)
            {
                throw new ArgumentNullException("assignmentExpression");
            }
            if (statements == null)
            {
                throw new ArgumentNullException("statements");
            }
            if (!(assignmentExpression.Right is ObjectCreateExpression))
            {
                throw new ArgumentException("assignmentExpression.Right must be an ObjectCreateExpression", "assignmentExpression");
            }

            if (!Initialize(assignmentExpression.Left))
            {
                return(null);
            }
            accessPaths [mainAccessPath] = assignmentExpression.Right.Clone();

            Convert(statements);
            statements = ReplacementNodeHelper.GetReplacedNodes(accessPaths [mainAccessPath]);
            return(new AssignmentExpression(new IdentifierExpression(mainAccessPath.RootName), accessPaths [mainAccessPath]));
        }
        bool TryHandleAddCall(ExpressionStatement expressionStatement)
        {
            var invocationExpression = expressionStatement.Expression as InvocationExpression;

            if (invocationExpression == null)
            {
                return(false);
            }
            var invocationResolveResult = context.Resolve(invocationExpression) as InvocationResolveResult;

            if (invocationResolveResult == null)
            {
                return(false);
            }
            if (invocationResolveResult.Member.Name != "Add")
            {
                return(false);
            }
            var targetResult = invocationResolveResult.TargetResult;

            if (targetResult is MemberResolveResult)
            {
                return(false);
            }

            var tuple = new ArrayInitializerExpression();

            foreach (var argument in invocationExpression.Arguments)
            {
                var argumentLocalResolveResult = context.Resolve(argument) as LocalResolveResult;
                if (argumentLocalResolveResult != null)
                {
                    var initializerPath = AccessPath.FromResolveResult(argumentLocalResolveResult);
                    if (initializerPath == null || !accessPaths.ContainsKey(initializerPath))
                    {
                        return(false);
                    }
                    // Add a clone, since we do not yet know if this is where the initializer will be used
                    var initializerClone = accessPaths[initializerPath].Clone();
                    tuple.Elements.Add(initializerClone);
                }
                else
                {
                    tuple.Elements.Add(argument.Clone());
                }
            }
            ReplacementNodeHelper.AddReplacementAnnotation(tuple, expressionStatement);

            var targetPath = AccessPath.FromResolveResult(targetResult);

            if (targetPath == null || !accessPaths.ContainsKey(targetPath))
            {
                return(false);
            }
            InsertImplicitInitializersForPath(targetPath);
            var targetInitializer = accessPaths [targetPath];

            AddToInitializer(targetInitializer, tuple);
            return(true);
        }
 void Convert(IList <AstNode> originalStatements)
 {
     foreach (var node in originalStatements)
     {
         var comment = node as Comment;
         if (comment != null)
         {
             comments.Add((Comment)ReplacementNodeHelper.CloneWithReplacementAnnotation(comment, node));
             continue;
         }
         var success = TryHandleInitializer(node);
         if (success)
         {
             continue;
         }
         var expressionStatement = node as ExpressionStatement;
         if (expressionStatement == null)
         {
             break;
         }
         success = TryHandleAssignmentExpression(expressionStatement);
         if (success)
         {
             continue;
         }
         success = TryHandleAddCall(expressionStatement);
         if (success)
         {
             continue;
         }
         break;
     }
 }
 void AddOldAnnotationsToInitializer(AccessPath targetPath, IAnnotatable initializer)
 {
     if (targetPath != null)
     {
         if (accessPaths.ContainsKey(targetPath))
         {
             foreach (var astNode in ReplacementNodeHelper.GetAllReplacementAnnotations(accessPaths[targetPath]))
             {
                 initializer.AddAnnotation(astNode);
             }
         }
     }
 }
        public VariableInitializer ConvertToInitializer(VariableInitializer variableInitializer, ref IList <AstNode> statements)
        {
            if (variableInitializer == null)
            {
                throw new ArgumentNullException("variableInitializer");
            }
            if (statements == null)
            {
                throw new ArgumentNullException("statements");
            }

            if (!Initialize(variableInitializer))
            {
                return(null);
            }
            accessPaths [mainAccessPath] = variableInitializer.Initializer.Clone();

            Convert(statements);
            statements = ReplacementNodeHelper.GetReplacedNodes(accessPaths [mainAccessPath]);
            return(new VariableInitializer(mainAccessPath.RootName, accessPaths [mainAccessPath]));
        }
        bool PushAssignment(Expression left, Expression right, AstNode node)
        {
            var        rightResolveResult = context.Resolve(right) as LocalResolveResult;
            var        leftResolveResult  = context.Resolve(left);
            Expression initializer;

            if (rightResolveResult != null)
            {
                var rightPath = AccessPath.FromResolveResult(rightResolveResult);
                if (accessPaths.ContainsKey(rightPath))
                {
                    initializer = accessPaths [rightPath];
                }
                else
                {
                    initializer = right.Clone();
                }
            }
            else
            {
                initializer = right.Clone();
            }
            var leftPath = AccessPath.FromResolveResult(leftResolveResult);

            if (leftPath == null)
            {
                return(false);
            }

            // Move replacement annotations over, in case this is the second assignment
            // to the same variable/member.
            AddOldAnnotationsToInitializer(leftPath, initializer);

            if (leftPath.PartCount == 1)
            {
                ReplacementNodeHelper.AddReplacementAnnotation(initializer, node);
                accessPaths [leftPath] = initializer;
                return(true);
            }
            if (!(leftResolveResult is MemberResolveResult))
            {
                return(false);
            }

            Debug.Assert(leftPath.PartCount > 1, "No top level assignment should get here.");

            var parentKey = leftPath.GetParentPath();
            var member    = leftPath.MemberPath.Last();

            var success = InsertImplicitInitializersForPath(parentKey);

            if (!success)
            {
                return(false);
            }

            var parentInitializer = accessPaths [parentKey];

            AddToInitializer(parentInitializer, comments.ToArray());
            comments.Clear();

            AddToInitializer(parentInitializer, new NamedExpression(member.Name, initializer));
            ReplacementNodeHelper.AddReplacementAnnotation(initializer, node);
            accessPaths [leftPath] = initializer;
            return(true);
        }