public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { BoundSpillSequenceBuilder builder = null; var argument = VisitExpression(ref builder, node.Argument); return(UpdateExpression(builder, node.Update(argument, node.MethodOpt, node.IsExtensionMethod, node.Type))); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.HasDynamicType()) { var loweredArgument = VisitExpression(node.Argument); // Creates a delegate whose instance is the delegate that is returned by the call-site and the method is Invoke. var loweredReceiver = _dynamicFactory.MakeDynamicConversion(loweredArgument, isExplicit: false, isArrayIndex: false, isChecked: false, resultType: node.Type).ToExpression(); return(new BoundDelegateCreationExpression(node.Syntax, loweredReceiver, methodOpt: null, isExtensionMethod: false, type: node.Type)); } if (node.Argument.Kind == BoundKind.MethodGroup) { var mg = (BoundMethodGroup)node.Argument; var method = node.MethodOpt; var oldSyntax = _factory.Syntax; _factory.Syntax = (mg.ReceiverOpt ?? mg).Syntax; var receiver = (!method.RequiresInstanceReceiver && !node.IsExtensionMethod) ? _factory.Type(method.ContainingType) : VisitExpression(mg.ReceiverOpt); _factory.Syntax = oldSyntax; return(node.Update(receiver, method, node.IsExtensionMethod, node.Type)); } return(base.VisitDelegateCreationExpression(node)); }
public override BoundNode VisitDelegateCreationExpression( BoundDelegateCreationExpression node ) { if (node.Argument.HasDynamicType()) { var loweredArgument = VisitExpression(node.Argument); // Creates a delegate whose instance is the delegate that is returned by the call-site and the method is Invoke. var loweredReceiver = _dynamicFactory .MakeDynamicConversion( loweredArgument, isExplicit: false, isArrayIndex: false, isChecked: false, resultType: node.Type ) .ToExpression(); return(new BoundDelegateCreationExpression( node.Syntax, loweredReceiver, methodOpt: null, isExtensionMethod: false, type: node.Type )); } if (node.Argument.Kind == BoundKind.MethodGroup) { var mg = (BoundMethodGroup)node.Argument; var method = node.MethodOpt; Debug.Assert(method is { });
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (IsInside && node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { _interactsWithLocalFunction = true; } return(base.VisitDelegateCreationExpression(node)); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.Kind != BoundKind.MethodGroup) { this.Visit(node.Argument); } return(null); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { // Use OriginalDefinition to strip generic type parameters ReferenceVariable(node.Syntax, node.MethodOpt.OriginalDefinition); MethodsConvertedToDelegates.Add(node.MethodOpt.OriginalDefinition); } return(base.VisitDelegateCreationExpression(node)); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { // Use OriginalDefinition to strip generic type parameters var method = node.MethodOpt.OriginalDefinition; AddIfCaptured(method); _analysis.MethodsConvertedToDelegates.Add(method); } return(base.VisitDelegateCreationExpression(node)); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.Kind != BoundKind.MethodGroup) { this.Visit(node.Argument); } else { CheckMethodGroup((BoundMethodGroup)node.Argument, node.MethodOpt, parentIsConversion: true, convertedToType: node.Type); } return(null); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.Kind != BoundKind.MethodGroup) { this.Visit(node.Argument); } else if (_inExpressionLambda && node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { Error(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, node); } return(null); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { // A delegate creation expression of the form "new Action( ()=>{} )" is treated exactly like // (Action)(()=>{}) if (node.Argument.Kind == BoundKind.Lambda) { return(RewriteLambdaConversion((BoundLambda)node.Argument)); } else { return(base.VisitDelegateCreationExpression(node)); } }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.HasDynamicType()) { var loweredArgument = VisitExpression(node.Argument); // Creates a delegate whose instance is the delegate that is returned by the call-site and the method is Invoke. var loweredReceiver = _dynamicFactory.MakeDynamicConversion(loweredArgument, isExplicit: false, isArrayIndex: false, isChecked: false, resultType: node.Type).ToExpression(); return new BoundDelegateCreationExpression(node.Syntax, loweredReceiver, methodOpt: null, isExtensionMethod: false, type: node.Type); } return base.VisitDelegateCreationExpression(node); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { BoundExpression receiver; MethodSymbol method; var arguments = default(ImmutableArray <BoundExpression>); _lambdaRewriter.RemapLocalFunction( node.Syntax, node.MethodOpt, out receiver, out method, ref arguments); return(new BoundDelegateCreationExpression( node.Syntax, receiver, method, isExtensionMethod: false, type: node.Type)); } return(base.VisitDelegateCreationExpression(node)); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { BoundExpression receiver; MethodSymbol method; var arguments = default(ImmutableArray<BoundExpression>); _lambdaRewriter.RemapLocalFunction( node.Syntax, node.MethodOpt, out receiver, out method, ref arguments); return new BoundDelegateCreationExpression( node.Syntax, receiver, method, isExtensionMethod: false, type: node.Type); } return base.VisitDelegateCreationExpression(node); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { bool mightMutate = node.MethodOpt?.MethodKind == MethodKind.LocalFunction; if (mightMutate) { _mightAssignSomething = true; } else { base.VisitDelegateCreationExpression(node); } return(null); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { BoundExpression argument = (BoundExpression)this.Visit(node.Argument); TypeSymbol type = this.VisitType(node.Type); if (argument.Kind != BoundKind.SpillSequence) { return(node.Update(argument, node.MethodOpt, node.IsExtensionMethod, type)); } var spill = (BoundSpillSequence)argument; return(RewriteSpillSequence(spill, node.Update( spill.Value, node.MethodOpt, node.IsExtensionMethod, type))); }
private BoundExpression VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { var mg = node.Argument as BoundMethodGroup; if (mg != null) { return(DelegateCreation(mg.ReceiverOpt, node.MethodOpt, node.Type, node.MethodOpt.IsStatic && !mg.SearchExtensionMethods)); } var d = node.Argument.Type as NamedTypeSymbol; if ((object)d != null && d.TypeKind == TypeKind.Delegate) { return(DelegateCreation(node.Argument, d.DelegateInvokeMethod, node.Type, false)); } // there should be no other cases. Have we missed one? throw ExceptionUtilities.UnexpectedValue(node.Argument); }
private BoundExpression VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.Kind == BoundKind.MethodGroup) { throw ExceptionUtilities.UnexpectedValue(BoundKind.MethodGroup); } if ((object)node.MethodOpt != null) { bool staticMember = node.MethodOpt.IsStatic && !node.IsExtensionMethod; return(DelegateCreation(node.Argument, node.MethodOpt, node.Type, staticMember)); } var d = node.Argument.Type as NamedTypeSymbol; if ((object)d != null && d.TypeKind == TypeKind.Delegate) { return(DelegateCreation(node.Argument, d.DelegateInvokeMethod, node.Type, false)); } // there should be no other cases. Have we missed one? throw ExceptionUtilities.UnexpectedValue(node.Argument); }
private BoundExpression VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { var mg = node.Argument as BoundMethodGroup; if (mg != null) { return DelegateCreation(mg.ReceiverOpt, node.MethodOpt, node.Type, node.MethodOpt.IsStatic && !mg.SearchExtensionMethods); } var d = node.Argument.Type as NamedTypeSymbol; if ((object)d != null && d.TypeKind == TypeKind.Delegate) { return DelegateCreation(node.Argument, d.DelegateInvokeMethod, node.Type, false); } // there should be no other cases. Have we missed one? throw ExceptionUtilities.UnexpectedValue(node.Argument); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { BoundSpillSequence2 ss = null; var argument = VisitExpression(ref ss, node.Argument); return UpdateExpression(ss, node.Update(argument, node.MethodOpt, node.IsExtensionMethod, node.Type)); }
private BoundNode RewriteLambdaConversion(BoundLambda node) { var wasInExpressionLambda = inExpressionLambda; inExpressionLambda = inExpressionLambda || node.Type.IsExpressionTree(); if (inExpressionLambda) { var newType = VisitType(node.Type); var newBody = (BoundBlock)Visit(node.Body); node = node.Update(node.Symbol, newBody, node.Diagnostics, node.Binder, newType); var result0 = wasInExpressionLambda ? node : ExpressionLambdaRewriter.RewriteLambda(node, CompilationState, Diagnostics); inExpressionLambda = wasInExpressionLambda; return(result0); } NamedTypeSymbol translatedLambdaContainer; BoundNode lambdaScope = null; if (analysis.lambdaScopes.TryGetValue(node.Symbol, out lambdaScope)) { translatedLambdaContainer = frames[lambdaScope]; } else { translatedLambdaContainer = topLevelMethod.ContainingType; } // Move the body of the lambda to a freshly generated synthetic method on its frame. bool lambdaIsStatic = analysis.captures[node.Symbol].IsEmpty(); var synthesizedMethod = new SynthesizedLambdaMethod(translatedLambdaContainer, topLevelMethod, node, lambdaIsStatic, CompilationState); if (CompilationState.Emitting) { CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(translatedLambdaContainer, synthesizedMethod); } for (int i = 0; i < node.Symbol.ParameterCount; i++) { parameterMap.Add(node.Symbol.Parameters[i], synthesizedMethod.Parameters[i]); } // rewrite the lambda body as the generated method's body var oldMethod = currentMethod; var oldFrameThis = currentFrameThis; var oldTypeParameters = currentTypeParameters; var oldInnermostFramePointer = innermostFramePointer; var oldTypeMap = currentLambdaBodyTypeMap; var oldAddedStatements = addedStatements; var oldAddedLocals = addedLocals; addedStatements = null; addedLocals = null; // switch to the generated method currentMethod = synthesizedMethod; if (lambdaIsStatic) { // no link from a static lambda to its container innermostFramePointer = currentFrameThis = null; } else { currentFrameThis = synthesizedMethod.ThisParameter; innermostFramePointer = null; framePointers.TryGetValue(translatedLambdaContainer, out innermostFramePointer); } if (translatedLambdaContainer.OriginalDefinition is LambdaFrame) { currentTypeParameters = translatedLambdaContainer.TypeParameters; currentLambdaBodyTypeMap = ((LambdaFrame)translatedLambdaContainer).TypeMap; } else { currentTypeParameters = synthesizedMethod.TypeParameters; currentLambdaBodyTypeMap = new TypeMap(topLevelMethod.TypeParameters, currentTypeParameters); } var body = AddStatementsIfNeeded((BoundStatement)VisitBlock(node.Body)); CheckLocalsDefined(body); CompilationState.AddSynthesizedMethod(synthesizedMethod, body); // return to the old method currentMethod = oldMethod; currentFrameThis = oldFrameThis; currentTypeParameters = oldTypeParameters; innermostFramePointer = oldInnermostFramePointer; currentLambdaBodyTypeMap = oldTypeMap; addedLocals = oldAddedLocals; addedStatements = oldAddedStatements; // Rewrite the lambda expression (and the enclosing anonymous method conversion) as a delegate creation expression NamedTypeSymbol constructedFrame = (translatedLambdaContainer is LambdaFrame) ? translatedLambdaContainer.ConstructIfGeneric(StaticCast <TypeSymbol> .From(currentTypeParameters)) : translatedLambdaContainer; BoundExpression receiver = lambdaIsStatic ? new BoundTypeExpression(node.Syntax, null, constructedFrame) : FrameOfType(node.Syntax, constructedFrame); MethodSymbol referencedMethod = synthesizedMethod.AsMember(constructedFrame); if (referencedMethod.IsGenericMethod) { referencedMethod = referencedMethod.Construct(StaticCast <TypeSymbol> .From(currentTypeParameters)); } TypeSymbol type = this.VisitType(node.Type); BoundExpression result = new BoundDelegateCreationExpression( node.Syntax, receiver, referencedMethod, isExtensionMethod: false, type: type); // if the block containing the lambda is not the innermost block, // or the lambda is static, then the lambda object should be cached in its frame. // NOTE: we are not caching static lambdas in static ctors - cannot reuse such cache. var shouldCacheForStaticMethod = lambdaIsStatic && currentMethod.MethodKind != MethodKind.StaticConstructor && !referencedMethod.IsGenericMethod; // NOTE: We require "lambdaScope != null". // We do not want to introduce a field into an actual user's class (not a synthetic frame). var shouldCacheInLoop = lambdaScope != null && lambdaScope != analysis.blockParent[node.Body] && InLoopOrLambda(node.Syntax, lambdaScope.Syntax); if (shouldCacheForStaticMethod || shouldCacheInLoop) { // replace the expression "new Delegate(frame.M)" with "(frame.cache == null) ? (frame.cache = new Delegate(frame.M)) : frame.cache" var F = new SyntheticBoundNodeFactory(currentMethod, node.Syntax, CompilationState, Diagnostics); try { var cacheVariableName = GeneratedNames.MakeLambdaCacheName(CompilationState.GenerateTempNumber()); BoundExpression cacheVariable; if (shouldCacheForStaticMethod || shouldCacheInLoop && translatedLambdaContainer is LambdaFrame) { var cacheVariableType = lambdaIsStatic ? type : (translatedLambdaContainer as LambdaFrame).TypeMap.SubstituteType(type); var cacheField = new SynthesizedFieldSymbol(translatedLambdaContainer, cacheVariableType, cacheVariableName, isPublic: !lambdaIsStatic, isStatic: lambdaIsStatic); CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(translatedLambdaContainer, cacheField); cacheVariable = F.Field(receiver, cacheField.AsMember(constructedFrame)); //NOTE: the field was added to the unconstructed frame type. } else { // the lambda captures at most the "this" of the enclosing method. We cache its delegate in a local variable. var cacheLocal = F.SynthesizedLocal(type, cacheVariableName); if (addedLocals == null) { addedLocals = ArrayBuilder <LocalSymbol> .GetInstance(); } addedLocals.Add(cacheLocal); if (addedStatements == null) { addedStatements = ArrayBuilder <BoundStatement> .GetInstance(); } cacheVariable = F.Local(cacheLocal); addedStatements.Add(F.Assignment(cacheVariable, F.Null(type))); } result = F.Coalesce(cacheVariable, F.AssignmentExpression(cacheVariable, result)); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { Diagnostics.Add(ex.Diagnostic); return(new BoundBadExpression(F.Syntax, LookupResultKind.Empty, ImmutableArray <Symbol> .Empty, ImmutableArray.Create <BoundNode>(node), node.Type)); } } return(result); }
/// <summary> /// If we have a WinRT type event, we need to encapsulate the adder call /// (which returns an EventRegistrationToken) with a call to /// WindowsRuntimeMarshal.AddEventHandler or RemoveEventHandler, but these /// require us to create a new Func representing the adder and another /// Action representing the Remover. /// /// The rewritten call looks something like: /// /// WindowsRuntimeMarshal.AddEventHandler<EventHandler> /// (new Func<EventHandler, EventRegistrationToken>(@object.add), /// new Action<EventRegistrationToken>(@object.remove), handler); /// /// Where @object is a compiler-generated local temp if needed. /// </summary> /// <remarks> /// TODO: use or delete isDynamic. /// </remarks> private BoundExpression RewriteWindowsRuntimeEventAssignmentOperator(SyntaxNode syntax, EventSymbol eventSymbol, EventAssignmentKind kind, bool isDynamic, BoundExpression rewrittenReceiverOpt, BoundExpression rewrittenArgument) { BoundAssignmentOperator tempAssignment = null; BoundLocal boundTemp = null; if (!eventSymbol.IsStatic && CanChangeValueBetweenReads(rewrittenReceiverOpt)) { boundTemp = _factory.StoreToTemp(rewrittenReceiverOpt, out tempAssignment); } NamedTypeSymbol tokenType = _factory.WellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationToken); NamedTypeSymbol marshalType = _factory.WellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal); NamedTypeSymbol actionType = _factory.WellKnownType(WellKnownType.System_Action_T).Construct(tokenType); TypeSymbol eventType = eventSymbol.Type; BoundExpression delegateCreationArgument = boundTemp ?? rewrittenReceiverOpt ?? _factory.Type(eventType); BoundDelegateCreationExpression removeDelegate = new BoundDelegateCreationExpression( syntax: syntax, argument: delegateCreationArgument, methodOpt: eventSymbol.RemoveMethod, isExtensionMethod: false, type: actionType); BoundExpression clearCall = null; if (kind == EventAssignmentKind.Assignment) { MethodSymbol clearMethod; if (TryGetWellKnownTypeMember(syntax, WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal__RemoveAllEventHandlers, out clearMethod)) { clearCall = MakeCall( syntax: syntax, rewrittenReceiver: null, method: clearMethod, rewrittenArguments: ImmutableArray.Create<BoundExpression>(removeDelegate), type: clearMethod.ReturnType); } else { clearCall = new BoundBadExpression(syntax, LookupResultKind.NotInvocable, ImmutableArray<Symbol>.Empty, ImmutableArray.Create<BoundNode>(removeDelegate), ErrorTypeSymbol.UnknownResultType); } } ImmutableArray<BoundExpression> marshalArguments; WellKnownMember helper; if (kind == EventAssignmentKind.Subtraction) { helper = WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal__RemoveEventHandler_T; marshalArguments = ImmutableArray.Create<BoundExpression>(removeDelegate, rewrittenArgument); } else { NamedTypeSymbol func2Type = _factory.WellKnownType(WellKnownType.System_Func_T2).Construct(eventType, tokenType); BoundDelegateCreationExpression addDelegate = new BoundDelegateCreationExpression( syntax: syntax, argument: delegateCreationArgument, methodOpt: eventSymbol.AddMethod, isExtensionMethod: false, type: func2Type); helper = WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal__AddEventHandler_T; marshalArguments = ImmutableArray.Create<BoundExpression>(addDelegate, removeDelegate, rewrittenArgument); } BoundExpression marshalCall; MethodSymbol marshalMethod; if (TryGetWellKnownTypeMember(syntax, helper, out marshalMethod)) { marshalMethod = marshalMethod.Construct(eventType); marshalCall = MakeCall( syntax: syntax, rewrittenReceiver: null, method: marshalMethod, rewrittenArguments: marshalArguments, type: marshalMethod.ReturnType); } else { marshalCall = new BoundBadExpression(syntax, LookupResultKind.NotInvocable, ImmutableArray<Symbol>.Empty, StaticCast<BoundNode>.From(marshalArguments), ErrorTypeSymbol.UnknownResultType); } // In this case, we don't need a sequence. if (boundTemp == null && clearCall == null) { return marshalCall; } ImmutableArray<LocalSymbol> tempSymbols = boundTemp == null ? ImmutableArray<LocalSymbol>.Empty : ImmutableArray.Create<LocalSymbol>(boundTemp.LocalSymbol); ArrayBuilder<BoundExpression> sideEffects = ArrayBuilder<BoundExpression>.GetInstance(2); //max size if (clearCall != null) sideEffects.Add(clearCall); if (tempAssignment != null) sideEffects.Add(tempAssignment); Debug.Assert(sideEffects.Any(), "Otherwise, we shouldn't be building a sequence"); return new BoundSequence(syntax, tempSymbols, sideEffects.ToImmutableAndFree(), marshalCall, marshalCall.Type); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { // Use OriginalDefinition to strip generic type parameters ReferenceVariable(node.Syntax, node.MethodOpt.OriginalDefinition); MethodsConvertedToDelegates.Add(node.MethodOpt.OriginalDefinition); } return base.VisitDelegateCreationExpression(node); }
/// <summary> /// If we have a WinRT type event, we need to encapsulate the adder call /// (which returns an EventRegistrationToken) with a call to /// WindowsRuntimeMarshal.AddEventHandler or RemoveEventHandler, but these /// require us to create a new Func representing the adder and another /// Action representing the Remover. /// /// The rewritten call looks something like: /// /// WindowsRuntimeMarshal.AddEventHandler<EventHandler> /// (new Func<EventHandler, EventRegistrationToken>(@object.add), /// new Action<EventRegistrationToken>(@object.remove), handler); /// /// Where @object is a compiler-generated local temp if needed. /// </summary> /// <remarks> /// TODO: use or delete isDynamic. /// </remarks> private BoundExpression RewriteWindowsRuntimeEventAssignmentOperator(SyntaxNode syntax, EventSymbol eventSymbol, EventAssignmentKind kind, bool isDynamic, BoundExpression rewrittenReceiverOpt, BoundExpression rewrittenArgument) { BoundAssignmentOperator tempAssignment = null; BoundLocal boundTemp = null; if (!eventSymbol.IsStatic && CanChangeValueBetweenReads(rewrittenReceiverOpt)) { boundTemp = _factory.StoreToTemp(rewrittenReceiverOpt, out tempAssignment); } NamedTypeSymbol tokenType = _factory.WellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationToken); NamedTypeSymbol marshalType = _factory.WellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal); NamedTypeSymbol actionType = _factory.WellKnownType(WellKnownType.System_Action_T).Construct(tokenType); TypeSymbol eventType = eventSymbol.Type; BoundExpression delegateCreationArgument = boundTemp ?? rewrittenReceiverOpt ?? _factory.Type(eventType); BoundDelegateCreationExpression removeDelegate = new BoundDelegateCreationExpression( syntax: syntax, argument: delegateCreationArgument, methodOpt: eventSymbol.RemoveMethod, isExtensionMethod: false, type: actionType); BoundExpression clearCall = null; if (kind == EventAssignmentKind.Assignment) { MethodSymbol clearMethod; if (TryGetWellKnownTypeMember(syntax, WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal__RemoveAllEventHandlers, out clearMethod)) { clearCall = MakeCall( syntax: syntax, rewrittenReceiver: null, method: clearMethod, rewrittenArguments: ImmutableArray.Create <BoundExpression>(removeDelegate), type: clearMethod.ReturnType); } else { clearCall = new BoundBadExpression(syntax, LookupResultKind.NotInvocable, ImmutableArray <Symbol> .Empty, ImmutableArray.Create <BoundExpression>(removeDelegate), ErrorTypeSymbol.UnknownResultType); } } ImmutableArray <BoundExpression> marshalArguments; WellKnownMember helper; if (kind == EventAssignmentKind.Subtraction) { helper = WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal__RemoveEventHandler_T; marshalArguments = ImmutableArray.Create <BoundExpression>(removeDelegate, rewrittenArgument); } else { NamedTypeSymbol func2Type = _factory.WellKnownType(WellKnownType.System_Func_T2).Construct(eventType, tokenType); BoundDelegateCreationExpression addDelegate = new BoundDelegateCreationExpression( syntax: syntax, argument: delegateCreationArgument, methodOpt: eventSymbol.AddMethod, isExtensionMethod: false, type: func2Type); helper = WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_WindowsRuntimeMarshal__AddEventHandler_T; marshalArguments = ImmutableArray.Create <BoundExpression>(addDelegate, removeDelegate, rewrittenArgument); } BoundExpression marshalCall; MethodSymbol marshalMethod; if (TryGetWellKnownTypeMember(syntax, helper, out marshalMethod)) { marshalMethod = marshalMethod.Construct(eventType); marshalCall = MakeCall( syntax: syntax, rewrittenReceiver: null, method: marshalMethod, rewrittenArguments: marshalArguments, type: marshalMethod.ReturnType); } else { marshalCall = new BoundBadExpression(syntax, LookupResultKind.NotInvocable, ImmutableArray <Symbol> .Empty, marshalArguments, ErrorTypeSymbol.UnknownResultType); } // In this case, we don't need a sequence. if (boundTemp == null && clearCall == null) { return(marshalCall); } ImmutableArray <LocalSymbol> tempSymbols = boundTemp == null ? ImmutableArray <LocalSymbol> .Empty : ImmutableArray.Create <LocalSymbol>(boundTemp.LocalSymbol); ArrayBuilder <BoundExpression> sideEffects = ArrayBuilder <BoundExpression> .GetInstance(2); //max size if (clearCall != null) { sideEffects.Add(clearCall); } if (tempAssignment != null) { sideEffects.Add(tempAssignment); } Debug.Assert(sideEffects.Any(), "Otherwise, we shouldn't be building a sequence"); return(new BoundSequence(syntax, tempSymbols, sideEffects.ToImmutableAndFree(), marshalCall, marshalCall.Type)); }
private static ImmutableArray<Symbol> CreateReducedExtensionMethodIfPossible(BoundDelegateCreationExpression delegateCreation, BoundExpression receiverOpt) { var method = delegateCreation.MethodOpt; Debug.Assert((object)method != null); if (delegateCreation.IsExtensionMethod && method.IsExtensionMethod && (receiverOpt != null)) { MethodSymbol reduced = method.ReduceExtensionMethod(receiverOpt.Type); method = reduced ?? method; } return ImmutableArray.Create<Symbol>(method); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.Kind != BoundKind.MethodGroup) { this.Visit(node.Argument); } else if (_inExpressionLambda && node.MethodOpt?.MethodKind == MethodKind.LocalFunction) { Error(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, node); } return null; }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { BoundExpression argument = (BoundExpression)this.Visit(node.Argument); TypeSymbol type = this.VisitType(node.Type); if (argument.Kind != BoundKind.SpillSequence) { return node.Update(argument, node.MethodOpt, node.IsExtensionMethod, type); } var spill = (BoundSpillSequence)argument; return RewriteSpillSequence(spill, node.Update( spill.Value, node.MethodOpt, node.IsExtensionMethod, type)); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { if (node.Argument.Kind != BoundKind.MethodGroup) { this.Visit(node.Argument); } return null; }