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));
 }
Beispiel #7
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);
         _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);
        }
Beispiel #9
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);
        }
Beispiel #10
0
 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);
        }
Beispiel #19
0
 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));
 }
Beispiel #20
0
        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&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.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&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.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));
        }
Beispiel #24
0
        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;
        }