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))); }
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)); }