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)); }
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); }
public override BoundNode VisitMethodGroup(BoundMethodGroup node) { throw ExceptionUtilities.Unreachable; }
public override BoundNode VisitMethodGroup(BoundMethodGroup node) { return(VisitMethodGroup(node, parentIsConversion: false)); }
public static bool MethodGroupReceiverIsDynamic(this BoundMethodGroup node) { return(node.InstanceOpt != null && node.InstanceOpt.HasDynamicType()); }
/// <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)); } }
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); }
public override Conversion GetMethodGroupConversion(BoundMethodGroup source, TypeSymbol destination, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { // Conversions involving method groups require a Binder. throw ExceptionUtilities.Unreachable; }
private BoundNode VisitMethodGroup(BoundMethodGroup node, bool parentIsConversion) { CheckReceiverIfField(node.ReceiverOpt); return(base.VisitMethodGroup(node)); }