예제 #1
0
        protected override Expression VisitIndex(IndexExpression node)
        {
            int        yields = _yields.Count;
            Expression o      = Visit(node.Object);
            ReadOnlyCollection <Expression> a = Visit(node.Arguments);

            if (o == node.Object && a == node.Arguments)
            {
                return(node);
            }
            if (yields == _yields.Count)
            {
                return(Expression.MakeIndex(o, node.Indexer, a));
            }
            return(Expression.Block(
                       ToTemp(ref o),
                       ToTemp(ref a),
                       Expression.MakeIndex(o, node.Indexer, a)
                       ));
        }
예제 #2
0
        private Expression VisitAssign(BinaryExpression node)
        {
            int        yields = _yields.Count;
            Expression left   = Visit(node.Left);
            Expression right  = Visit(node.Right);

            if (left == node.Left && right == node.Right)
            {
                return(node);
            }
            if (yields == _yields.Count)
            {
                return(Expression.Assign(left, right));
            }

            var block = new List <Expression>();

            // If the left hand side did not rewrite itself, we may still need
            // to rewrite to ensure proper evaluation order. Essentially, we
            // want all of the left side evaluated first, then the value, then
            // the assignment
            if (left == node.Left)
            {
                switch (left.NodeType)
                {
                case ExpressionType.MemberAccess:
                    var        member = (MemberExpression)node.Left;
                    Expression e      = Visit(member.Expression);
                    block.Add(ToTemp(ref e));
                    left = Expression.MakeMemberAccess(e, member.Member);
                    break;

                case ExpressionType.Index:
                    var        index = (IndexExpression)node.Left;
                    Expression o     = Visit(index.Object);
                    ReadOnlyCollection <Expression> a = Visit(index.Arguments);
                    if (o == index.Object && a == index.Arguments)
                    {
                        return(index);
                    }
                    block.Add(ToTemp(ref o));
                    block.Add(ToTemp(ref a));
                    left = Expression.MakeIndex(o, index.Indexer, a);
                    break;

                case ExpressionType.Parameter:
                    // no action needed
                    break;

                default:
                    // Extension should've been reduced by Visit above,
                    // and returned a different node
                    throw Assert.Unreachable;
                }
            }
            else
            {
                // Get the last expression of the rewritten left side
                var leftBlock = (BlockExpression)left;
                left = leftBlock.Expressions[leftBlock.Expressions.Count - 1];
                block.AddRange(leftBlock.Expressions);
                block.RemoveAt(block.Count - 1);
            }

            if (right != node.Right)
            {
                block.Add(ToTemp(ref right));
            }

            block.Add(Expression.Assign(left, right));
            return(Expression.Block(block));
        }