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; var 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))); }
public override BoundNode?VisitCall(BoundCall node) { BoundExpression?receiverOpt = (BoundExpression)this.Visit(node.ReceiverOpt); ImmutableArray <BoundExpression> arguments = this.VisitList(node.Arguments); BoundCall updatedNode; if (_updatedNullabilities.TryGetValue(node, out (NullabilityInfo Info, TypeSymbol Type)infoAndType) && _updatedMethodSymbols.TryGetValue(node, out MethodSymbol updatedMethodSymbol)) { updatedNode = node.Update(receiverOpt, updatedMethodSymbol, arguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.IsDelegateCall, node.Expanded, node.InvokedAsExtensionMethod, node.ArgsToParamsOpt, node.ResultKind, node.BinderOpt, infoAndType.Type); updatedNode.TopLevelNullability = infoAndType.Info; } else { updatedNode = node.Update(receiverOpt, node.Method, arguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.IsDelegateCall, node.Expanded, node.InvokedAsExtensionMethod, node.ArgsToParamsOpt, node.ResultKind, node.BinderOpt, node.Type); } return(updatedNode); }
public override BoundNode VisitCall(BoundCall node) { if (node.Method.MethodKind == MethodKind.LocalFunction) { BoundExpression receiver; MethodSymbol method; var arguments = node.Arguments; _lambdaRewriter.RemapLocalFunction(node.Syntax, node.Method, out receiver, out method, ref arguments); node = node.Update(receiver, method, arguments); } return(base.VisitCall(node)); }
public override BoundNode VisitCall(BoundCall node) { if (node.Method.MethodKind == MethodKind.LocalFunction) { BoundExpression receiver; MethodSymbol method; var arguments = node.Arguments; _lambdaRewriter.RemapLocalFunction(node.Syntax, node.Method, out receiver, out method, ref arguments); node = node.Update(receiver, method, arguments); } return base.VisitCall(node); }
public override BoundNode VisitCall(BoundCall node) { BoundExpression receiverOpt = (BoundExpression)this.Visit(node.ReceiverOpt); ReadOnlyArray <BoundExpression> arguments = this.VisitList(node.Arguments); TypeSymbol type = this.VisitType(node.Type); if (!RequiresSpill(arguments) && !RequiresSpill(receiverOpt)) { return(node.Update( receiverOpt, node.Method, arguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.IsDelegateCall, node.Expanded, node.InvokedAsExtensionMethod, node.ArgsToParamsOpt, node.ResultKind, type)); } var spillBuilder = new SpillBuilder(); var spillResult = SpillExpressionsWithReceiver(receiverOpt, arguments, spillBuilder, node.Method.ParameterRefKinds); var newCall = node.Update( spillResult.Item1, node.Method, spillResult.Item2, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.IsDelegateCall, node.Expanded, node.InvokedAsExtensionMethod, node.ArgsToParamsOpt, node.ResultKind, type); return(spillBuilder.BuildSequenceAndFree(F, newCall)); }
public override BoundNode VisitCall(BoundCall node) { BoundSpillSequence2 ss = null; var arguments = this.VisitExpressionList(ref ss, node.Arguments, node.ArgumentRefKindsOpt); BoundExpression receiver = null; if (ss == null) { receiver = VisitExpression(ref ss, node.ReceiverOpt); } else if (!node.Method.IsStatic) { // spill the receiver if there were await expressions in the arguments var ss2 = new BoundSpillSequence2(); receiver = Spill(ss2, VisitExpression(ref ss2, node.ReceiverOpt), refKind: node.ReceiverOpt.Type.IsReferenceType ? RefKind.None : RefKind.Ref); ss2.IncludeSequence(ss); ss = ss2; } return(UpdateExpression(ss, 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)); }
public override BoundNode VisitCall(BoundCall node) { BoundSpillSequence2 ss = null; var arguments = this.VisitExpressionList(ref ss, node.Arguments, node.ArgumentRefKindsOpt); BoundExpression receiver = null; if (ss == null) { receiver = VisitExpression(ref ss, node.ReceiverOpt); } else if (!node.Method.IsStatic) { // spill the receiver if there were await expressions in the arguments var ss2 = new BoundSpillSequence2(); receiver = Spill(ss2, VisitExpression(ref ss2, node.ReceiverOpt), refKind: node.ReceiverOpt.Type.IsReferenceType ? RefKind.None : RefKind.Ref); ss2.IncludeSequence(ss); ss = ss2; } return UpdateExpression(ss, node.Update(receiver, node.Method, arguments)); }
private BoundExpression MakeCall( BoundCall node, SyntaxNode syntax, BoundExpression rewrittenReceiver, MethodSymbol method, ImmutableArray<BoundExpression> rewrittenArguments, ImmutableArray<RefKind> argumentRefKinds, bool invokedAsExtensionMethod, LookupResultKind resultKind, TypeSymbol type, ImmutableArray<LocalSymbol> temps = default(ImmutableArray<LocalSymbol>)) { BoundExpression rewrittenBoundCall; if (method.IsStatic && method.ContainingType.IsObjectType() && !_inExpressionLambda && (object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_Object__ReferenceEquals)) { Debug.Assert(rewrittenArguments.Length == 2); // ECMA - 335 // I.8.2.5.1 Identity // ... // Identity is implemented on System.Object via the ReferenceEquals method. rewrittenBoundCall = new BoundBinaryOperator( syntax, BinaryOperatorKind.ObjectEqual, rewrittenArguments[0], rewrittenArguments[1], null, null, resultKind, type); } else if (node == null) { rewrittenBoundCall = new BoundCall( syntax, rewrittenReceiver, method, rewrittenArguments, default(ImmutableArray<string>), argumentRefKinds, isDelegateCall: false, expanded: false, invokedAsExtensionMethod: invokedAsExtensionMethod, argsToParamsOpt: default(ImmutableArray<int>), resultKind: resultKind, type: type); } else { rewrittenBoundCall = node.Update( rewrittenReceiver, method, rewrittenArguments, default(ImmutableArray<string>), argumentRefKinds, node.IsDelegateCall, false, node.InvokedAsExtensionMethod, default(ImmutableArray<int>), node.ResultKind, node.Type); } if (!temps.IsDefaultOrEmpty) { return new BoundSequence( syntax, locals: temps, sideEffects: ImmutableArray<BoundExpression>.Empty, value: rewrittenBoundCall, type: type); } return rewrittenBoundCall; }
public override BoundNode VisitCall(BoundCall node) { BoundExpression receiverOpt = (BoundExpression)this.Visit(node.ReceiverOpt); ReadOnlyArray<BoundExpression> arguments = this.VisitList(node.Arguments); TypeSymbol type = this.VisitType(node.Type); if (!RequiresSpill(arguments) && !RequiresSpill(receiverOpt)) { return node.Update( receiverOpt, node.Method, arguments, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.IsDelegateCall, node.Expanded, node.InvokedAsExtensionMethod, node.ArgsToParamsOpt, node.ResultKind, type); } var spillBuilder = new SpillBuilder(); var spillResult = SpillExpressionsWithReceiver(receiverOpt, arguments, spillBuilder, node.Method.ParameterRefKinds); var newCall = node.Update( spillResult.Item1, node.Method, spillResult.Item2, node.ArgumentNamesOpt, node.ArgumentRefKindsOpt, node.IsDelegateCall, node.Expanded, node.InvokedAsExtensionMethod, node.ArgsToParamsOpt, node.ResultKind, type); return spillBuilder.BuildSequenceAndFree(F, newCall); }
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.Type); }
private BoundExpression MakeCall( BoundCall node, CSharpSyntaxNode syntax, BoundExpression rewrittenReceiver, MethodSymbol method, ImmutableArray <BoundExpression> rewrittenArguments, ImmutableArray <RefKind> argumentRefKinds, bool invokedAsExtensionMethod, LookupResultKind resultKind, TypeSymbol type, ImmutableArray <LocalSymbol> temps = default(ImmutableArray <LocalSymbol>)) { BoundExpression rewrittenBoundCall; if (method.IsStatic && method.ContainingType.IsObjectType() && !inExpressionLambda && (object)method == (object)this.compilation.GetSpecialTypeMember(SpecialMember.System_Object__ReferenceEquals)) { Debug.Assert(rewrittenArguments.Length == 2); // ECMA - 335 // I.8.2.5.1 Identity // ... // Identity is implemented on System.Object via the ReferenceEquals method. rewrittenBoundCall = new BoundBinaryOperator( syntax, BinaryOperatorKind.ObjectEqual, rewrittenArguments[0], rewrittenArguments[1], null, null, resultKind, type); } else if (node == null) { rewrittenBoundCall = new BoundCall( syntax, rewrittenReceiver, method, rewrittenArguments, default(ImmutableArray <string>), argumentRefKinds, isDelegateCall: false, expanded: false, invokedAsExtensionMethod: invokedAsExtensionMethod, argsToParamsOpt: default(ImmutableArray <int>), resultKind: resultKind, type: type); } else { rewrittenBoundCall = node.Update( rewrittenReceiver, method, rewrittenArguments, default(ImmutableArray <string>), argumentRefKinds, node.IsDelegateCall, false, node.InvokedAsExtensionMethod, default(ImmutableArray <int>), node.ResultKind, node.Type); } if (!temps.IsDefaultOrEmpty) { return(new BoundSequence( syntax, locals: temps, sideEffects: ImmutableArray <BoundExpression> .Empty, value: rewrittenBoundCall, type: type)); } return(rewrittenBoundCall); }