Beispiel #1
0
        private BoundNode VisitMethodGroup(BoundMethodGroup node, bool parentIsConversion)
        {
            // Formerly reported ERR_MemGroupInExpressionTree when this occurred, but the expanded
            // ERR_LambdaInIsAs makes this impossible (since the node will always be wrapped in
            // a failed conversion).
            Debug.Assert(!(!parentIsConversion && _inExpressionLambda));

            if (_inExpressionLambda && (node.LookupSymbolOpt as MethodSymbol)?.MethodKind == MethodKind.LocalFunction)
            {
                Error(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, node);
            }

            CheckReceiverIfField(node.ReceiverOpt);
            return(base.VisitMethodGroup(node));
        }
Beispiel #2
0
        public override Conversion GetMethodGroupConversion(BoundMethodGroup source, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            // Must be a bona fide delegate type, not an expression tree type.
            if (!destination.IsDelegateType())
            {
                return(Conversion.NoConversion);
            }

            var methodSymbol = GetDelegateInvokeMethodIfAvailable(destination);

            if ((object)methodSymbol == null)
            {
                return(Conversion.NoConversion);
            }

            var resolution = ResolveDelegateMethodGroup(_binder, source, methodSymbol, ref useSiteDiagnostics);
            var conversion = (resolution.IsEmpty || resolution.HasAnyErrors) ?
                             Conversion.NoConversion :
                             ToConversion(resolution.OverloadResolutionResult, resolution.MethodGroup, (NamedTypeSymbol)destination);

            resolution.Free();
            return(conversion);
        }
Beispiel #3
0
 public override BoundNode VisitMethodGroup(BoundMethodGroup node)
 {
     throw ExceptionUtilities.Unreachable;
 }
Beispiel #4
0
 public override BoundNode VisitMethodGroup(BoundMethodGroup node)
 {
     return(VisitMethodGroup(node, parentIsConversion: false));
 }
Beispiel #5
0
 public static bool MethodGroupReceiverIsDynamic(this BoundMethodGroup node)
 {
     return(node.InstanceOpt != null && node.InstanceOpt.HasDynamicType());
 }
Beispiel #6
0
 /// <summary>
 /// Resolve method group based on the optional delegate invoke method.
 /// If the invoke method is null, ignore arguments in resolution.
 /// </summary>
 private static MethodGroupResolution ResolveDelegateMethodGroup(Binder binder, BoundMethodGroup source, MethodSymbol delegateInvokeMethodOpt, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
 {
     if ((object)delegateInvokeMethodOpt != null)
     {
         var analyzedArguments = AnalyzedArguments.GetInstance();
         GetDelegateArguments(source.Syntax, analyzedArguments, delegateInvokeMethodOpt.Parameters, binder.Compilation);
         var resolution = binder.ResolveMethodGroup(source, analyzedArguments, useSiteDiagnostics: ref useSiteDiagnostics, inferWithDynamic: true,
                                                    isMethodGroupConversion: true, returnRefKind: delegateInvokeMethodOpt.RefKind, returnType: delegateInvokeMethodOpt.ReturnType.TypeSymbol);
         analyzedArguments.Free();
         return(resolution);
     }
     else
     {
         return(binder.ResolveMethodGroup(source, analyzedArguments: null, isMethodGroupConversion: true, ref useSiteDiagnostics));
     }
 }
Beispiel #7
0
        public static bool ReportDelegateMethodGroupDiagnostics(Binder binder, BoundMethodGroup expr, TypeSymbol targetType, DiagnosticBag diagnostics)
        {
            var invokeMethodOpt = GetDelegateInvokeMethodIfAvailable(targetType);
            HashSet <DiagnosticInfo> useSiteDiagnostics = null;
            var resolution = ResolveDelegateMethodGroup(binder, expr, invokeMethodOpt, ref useSiteDiagnostics);

            diagnostics.Add(expr.Syntax, useSiteDiagnostics);

            bool hasErrors = resolution.HasAnyErrors;

            diagnostics.AddRange(resolution.Diagnostics);

            // SPEC VIOLATION: Unfortunately, we cannot exactly implement the specification for
            // the scenario in which an extension method that extends a value type is converted
            // to a delegate. The code we generate that captures a delegate to a static method
            // that is "partially evaluated" with the bound-to-the-delegate first argument
            // requires that the first argument be of reference type.
            //
            // SPEC VIOLATION: Similarly, we cannot capture a method of Nullable<T>, because
            // boxing a Nullable<T> gives a T, not a boxed Nullable<T>.
            //
            // We give special error messages in these situations.

            if (resolution.MethodGroup != null)
            {
                var result = resolution.OverloadResolutionResult;
                if (result != null)
                {
                    if (result.Succeeded)
                    {
                        var method = result.BestResult.Member;
                        Debug.Assert((object)method != null);
                        if (resolution.MethodGroup.IsExtensionMethodGroup)
                        {
                            Debug.Assert(method.IsExtensionMethod);

                            var thisParameter = method.Parameters[0];
                            if (!thisParameter.Type.IsReferenceType)
                            {
                                // Extension method '{0}' defined on value type '{1}' cannot be used to create delegates
                                diagnostics.Add(
                                    ErrorCode.ERR_ValueTypeExtDelegate,
                                    expr.Syntax.Location,
                                    method,
                                    thisParameter.Type.TypeSymbol);
                                hasErrors = true;
                            }
                        }
                        else if (method.ContainingType.IsNullableType() && !method.IsOverride)
                        {
                            // CS1728: Cannot bind delegate to '{0}' because it is a member of 'System.Nullable<T>'
                            diagnostics.Add(
                                ErrorCode.ERR_DelegateOnNullable,
                                expr.Syntax.Location,
                                method);
                            hasErrors = true;
                        }
                    }
                    else if (!hasErrors &&
                             !resolution.IsEmpty &&
                             resolution.ResultKind == LookupResultKind.Viable)
                    {
                        var overloadDiagnostics = DiagnosticBag.GetInstance();

                        result.ReportDiagnostics(
                            binder: binder, location: expr.Syntax.Location, nodeOpt: expr.Syntax, diagnostics: overloadDiagnostics,
                            name: expr.Name,
                            receiver: resolution.MethodGroup.Receiver, invokedExpression: expr.Syntax, arguments: resolution.AnalyzedArguments,
                            memberGroup: resolution.MethodGroup.Methods.ToImmutable(),
                            typeContainingConstructor: null, delegateTypeBeingInvoked: null,
                            isMethodGroupConversion: true, returnRefKind: invokeMethodOpt?.RefKind, delegateType: targetType);

                        if (!overloadDiagnostics.IsEmptyWithoutResolution)
                        {
                            hasErrors = overloadDiagnostics.HasAnyErrors();
                            diagnostics.AddRange(overloadDiagnostics);
                        }

                        overloadDiagnostics.Free();
                    }
                }
            }

            resolution.Free();
            return(hasErrors);
        }
Beispiel #8
0
 public override Conversion GetMethodGroupConversion(BoundMethodGroup source, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
 {
     // Conversions involving method groups require a Binder.
     throw ExceptionUtilities.Unreachable;
 }
Beispiel #9
0
 private BoundNode VisitMethodGroup(BoundMethodGroup node, bool parentIsConversion)
 {
     CheckReceiverIfField(node.ReceiverOpt);
     return(base.VisitMethodGroup(node));
 }