public override BoundNode VisitCollectionElementInitializer(BoundCollectionElementInitializer node) { if (_inExpressionLambda && node.AddMethod.IsStatic) { Error(ErrorCode.ERR_ExtensionCollectionElementInitializerInExpressionTree, node); } VisitCall(node.AddMethod, null, node.Arguments, default(ImmutableArray <RefKind>), default(ImmutableArray <string>), node.Expanded, node); return(base.VisitCollectionElementInitializer(node)); }
// Rewrite collection initializer element Add method call: // new List<int> { 1, 2, 3 }; OR new List<int> { { 1, 2 }, 3 }; // ~ ~~~~~~~~ private BoundExpression MakeCollectionInitializer(BoundExpression rewrittenReceiver, BoundCollectionElementInitializer initializer) { MethodSymbol addMethod = initializer.AddMethod; Debug.Assert(addMethod.Name == "Add"); Debug.Assert(addMethod.Parameters .Skip(addMethod.IsExtensionMethod ? 1 : 0) .All(p => p.RefKind == RefKind.None || p.RefKind == RefKind.In)); Debug.Assert(initializer.Arguments.Any()); Debug.Assert(rewrittenReceiver != null); var syntax = initializer.Syntax; if (_allowOmissionOfConditionalCalls) { // NOTE: Calls cannot be omitted within an expression tree (CS0765); this should already // have been checked. if (addMethod.CallsAreOmitted(initializer.SyntaxTree)) { return(null); } } var rewrittenArguments = VisitList(initializer.Arguments); var rewrittenType = VisitType(initializer.Type); // We have already lowered each argument, but we may need some additional rewriting for the arguments, // such as generating a params array, re-ordering arguments based on argsToParamsOpt map, inserting arguments for optional parameters, etc. ImmutableArray <LocalSymbol> temps; var argumentRefKindsOpt = default(ImmutableArray <RefKind>); if (addMethod.Parameters[0].RefKind == RefKind.Ref) { // If the Add method is an extension which takes a `ref this` as the first parameter, implicitly add a `ref` to the argument // Initializer element syntax cannot have `ref`, `in`, or `out` keywords. // Arguments to `in` parameters will be converted to have RefKind.In later on. var builder = ArrayBuilder <RefKind> .GetInstance(addMethod.Parameters.Length, RefKind.None); builder[0] = RefKind.Ref; argumentRefKindsOpt = builder.ToImmutableAndFree(); } rewrittenArguments = MakeArguments(syntax, rewrittenArguments, addMethod, addMethod, initializer.Expanded, initializer.ArgsToParamsOpt, ref argumentRefKindsOpt, out temps, enableCallerInfo: ThreeState.True); if (initializer.InvokedAsExtensionMethod) { // the add method was found as an extension method. Replace the implicit receiver (first argument) with the rewritten receiver. Debug.Assert(addMethod.IsStatic && addMethod.IsExtensionMethod); Debug.Assert(rewrittenArguments[0].Kind == BoundKind.ImplicitReceiver); rewrittenArguments = rewrittenArguments.SetItem(0, rewrittenReceiver); rewrittenReceiver = null; } return(MakeCall(null, syntax, rewrittenReceiver, addMethod, rewrittenArguments, argumentRefKindsOpt, initializer.InvokedAsExtensionMethod, initializer.ResultKind, addMethod.ReturnType.TypeSymbol, temps)); }
public override BoundNode VisitCollectionElementInitializer(BoundCollectionElementInitializer node) { VisitCall(node.AddMethod, null, node.Arguments, default(ImmutableArray <RefKind>), default(ImmutableArray <string>), node.Expanded, node); return(base.VisitCollectionElementInitializer(node)); }