public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { BoundExpression originalArgument = node.Argument; BoundExpression rewrittenArgument = (BoundExpression)this.Visit(originalArgument); MethodSymbol method = node.MethodOpt; if (originalArgument.Kind == BoundKind.MethodGroup && rewrittenArgument.Kind == BoundKind.MethodGroup) { // if the original argument was a method group AND the receiver was BoundKind.BaseReference // and the visited argument is still a method group with receiver overridden, change the // method to point to the wrapper method var originalReceiver = ((BoundMethodGroup)originalArgument).ReceiverOpt; var newReceiver = ((BoundMethodGroup)rewrittenArgument).ReceiverOpt; if (BaseReferenceInReceiverWasRewritten(originalReceiver, newReceiver) && method.IsMetadataVirtual()) { method = GetMethodWrapperForBaseNonVirtualCall(method, originalArgument.Syntax); // NOTE: we substitute the method in rewritten bound delegate // creation node, but leave the method group unchanged } } method = VisitMethodSymbol(method); TypeSymbol type = this.VisitType(node.Type); return(node.Update(rewrittenArgument, method, node.IsExtensionMethod, type)); }
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 var method = node.MethodOpt.OriginalDefinition; AddIfCaptured(method, node.Syntax); _methodsConvertedToDelegates.Add(method); } return(base.VisitDelegateCreationExpression(node)); }
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) { 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.IsStatic && !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) { BoundExpression originalArgument = node.Argument; BoundExpression rewrittenArgument = (BoundExpression)this.Visit(originalArgument); MethodSymbol method = node.MethodOpt; // if the original receiver was BoundKind.BaseReference (i.e. from a method group) // and the receiver is overridden, change the method to point to a wrapper method if (BaseReferenceInReceiverWasRewritten(originalArgument, rewrittenArgument) && method.IsMetadataVirtual()) { method = GetMethodWrapperForBaseNonVirtualCall(method, originalArgument.Syntax); } method = VisitMethodSymbol(method); TypeSymbol type = this.VisitType(node.Type); return node.Update(rewrittenArgument, method, node.IsExtensionMethod, type); }
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); }
internal void Parse(BoundDelegateCreationExpression boundDelegateCreationExpression) { base.Parse(boundDelegateCreationExpression); var argument = Deserialize(boundDelegateCreationExpression.Argument) as Expression; Debug.Assert(argument != null); if (boundDelegateCreationExpression.MethodOpt != null && !(boundDelegateCreationExpression.Argument is BoundMethodGroup)) { var methodGroup = new MethodGroup { ReceiverOpt = argument, Method = boundDelegateCreationExpression.MethodOpt, TypeArgumentsOpt = boundDelegateCreationExpression.MethodOpt.TypeArguments.Select(t => TypeImpl.Wrap(t)).ToList() }; Arguments.Add(methodGroup); } else { if (argument.Type != null && argument.Type.TypeKind == TypeKind.Delegate) { this.clone = true; this.cloneArgument = argument; } else { var methodGroup = argument as MethodGroup; if (methodGroup != null && boundDelegateCreationExpression.MethodOpt != null) { methodGroup.Method = boundDelegateCreationExpression.MethodOpt; } Arguments.Add(argument); } } }
private void EmitDelegateCreationExpression(BoundDelegateCreationExpression expression, bool used) { var mg = expression.Argument as BoundMethodGroup; var receiver = mg != null ? mg.ReceiverOpt : expression.Argument; var meth = expression.MethodOpt ?? receiver.Type.DelegateInvokeMethod(); Debug.Assert((object)meth != null); EmitDelegateCreation(expression, receiver, expression.IsExtensionMethod, meth, expression.Type, used); }
public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node) { BoundExpression originalArgument = node.Argument; BoundExpression rewrittenArgument = (BoundExpression)this.Visit(originalArgument); MethodSymbol method = node.MethodOpt; if (originalArgument.Kind == BoundKind.MethodGroup && rewrittenArgument.Kind == BoundKind.MethodGroup) { // if the original argument was a method group AND the receiver was BoundKind.BaseReference // and the visited argument is still a method group with receiver overridden, change the // method to point to the wrapper method var originalReceiver = ((BoundMethodGroup)originalArgument).ReceiverOpt; var newReceiver = ((BoundMethodGroup)rewrittenArgument).ReceiverOpt; if (BaseReferenceInReceiverWasRewritten(originalReceiver, newReceiver) && method.IsMetadataVirtual()) { method = GetMethodWrapperForBaseNonVirtualCall(method, originalArgument.Syntax); // NOTE: we substitute the method in rewritten bound delegate // creation node, but leave the method group unchanged } } method = VisitMethodSymbol(method); TypeSymbol type = this.VisitType(node.Type); return node.Update(rewrittenArgument, method, node.IsExtensionMethod, type); }
/// <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.core_runtime_WindowsRuntime_EventRegistrationToken); NamedTypeSymbol marshalType = _factory.WellKnownType(WellKnownType.core_runtime_WindowsRuntime_WindowsRuntimeMarshal); NamedTypeSymbol actionType = _factory.WellKnownType(WellKnownType.core_Action_T).Construct(tokenType); TypeSymbol eventType = eventSymbol.Type.TypeSymbol; 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.TypeSymbol); } 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.core_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.TypeSymbol); } 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)); }