Example #1
0
        public override BoundNode VisitCall(BoundCall node)
        {
            BoundSpillSequenceBuilder builder = null;
            var arguments = this.VisitExpressionList(ref builder, node.Arguments, node.ArgumentRefKindsOpt);

            BoundExpression receiver = null;

            if (builder == null)
            {
                receiver = VisitExpression(ref builder, node.ReceiverOpt);
            }
            else if (!node.Method.IsStatic)
            {
                // spill the receiver if there were await expressions in the arguments
                var receiverBuilder = new BoundSpillSequenceBuilder();

                receiver = node.ReceiverOpt;
                RefKind refKind = ReceiverSpillRefKind(receiver);

                receiver = Spill(receiverBuilder, VisitExpression(ref receiverBuilder, receiver), refKind: refKind);
                receiverBuilder.Include(builder);
                builder = receiverBuilder;
            }

            return(UpdateExpression(builder, node.Update(receiver, node.Method, arguments)));
        }
Example #2
0
        private static BoundCall ReverseLastTwoParameterOrder(BoundCall result)
        {
            // The input call has its arguments in the appropriate order for the invocation, but its last
            // two argument expressions appear in the reverse order from which they appeared in source.
            // Since we want region analysis to see them in source order, we rewrite the call so that these
            // two arguments are evaluated in source order.
            int n         = result.Arguments.Length;
            var arguments = ArrayBuilder <BoundExpression> .GetInstance();

            arguments.AddRange(result.Arguments);
            var lastArgument = arguments[n - 1];

            arguments[n - 1] = arguments[n - 2];
            arguments[n - 2] = lastArgument;
            var argsToParams = ArrayBuilder <int> .GetInstance();

            argsToParams.AddRange(Enumerable.Range(0, n));
            argsToParams[n - 1] = n - 2;
            argsToParams[n - 2] = n - 1;
            return(result.Update(
                       result.ReceiverOpt, result.Method, arguments.ToImmutableAndFree(), default(ImmutableArray <string>),
                       default(ImmutableArray <RefKind>), result.IsDelegateCall, result.Expanded, result.InvokedAsExtensionMethod,
                       argsToParams.ToImmutableAndFree(), result.ResultKind, result.BinderOpt, result.Type));
        }