コード例 #1
0
        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));
        }
コード例 #2
0
        public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationExpression node)
        {
            if (node.Argument.Kind != BoundKind.MethodGroup)
            {
                this.Visit(node.Argument);
            }

            return(null);
        }
コード例 #3
0
 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));
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        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));
        }
コード例 #6
0
ファイル: MethodToClassRewriter.cs プロジェクト: znatz/roslyn
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
                }
            }
        }
コード例 #9
0
ファイル: EmitExpression.cs プロジェクト: tvsonar/roslyn
 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);
 }
コード例 #10
0
 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);
 }
コード例 #11
0
        /// <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&lt;EventHandler&gt;
        ///     (new Func&lt;EventHandler, EventRegistrationToken&gt;(@object.add),
        ///      new Action&lt;EventRegistrationToken&gt;(@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));
        }