예제 #1
0
        private Expression VisitExpression(ref BoundSpillSequenceBuilder builder, Expression expression)
        {
            // wrap the node in a spill sequence to mark the fact that it must be moved up the tree.
            // The caller will handle this node type if the result is discarded.
            if (expression != null && expression.NodeType == NodeType.AwaitExpression)
            {
                // we force the await expression to be assigned to a temp variable
                var awaitExpression = (AwaitExpression)expression;
                awaitExpression.BaseExpression = VisitExpression(ref builder, awaitExpression.BaseExpression);

                var local       = _F.DeclareTempLocal(_currentMethod, awaitExpression.ExpressionType);
                var replacement = _F.CreateAssignment(
                    awaitExpression.LexicalInfo,
                    _F.CreateLocalReference(local),
                    awaitExpression);
                if (builder == null)
                {
                    builder = new BoundSpillSequenceBuilder();
                }

                builder.AddLocal(local);
                builder.AddStatement(new ExpressionStatement(replacement));
                return(_F.CreateLocalReference(local));
            }

            var e = Visit(expression);

            if (e == null || e.NodeType != SpillSequenceBuilder)
            {
                return(e);
            }

            var newBuilder = (BoundSpillSequenceBuilder)e;

            if (builder == null)
            {
                builder = newBuilder.Update(null);
            }
            else
            {
                builder.Include(newBuilder);
            }

            return(newBuilder.Value);
        }