public MethodGroupResolution( MethodGroup methodGroup, Symbol otherSymbol, OverloadResolutionResult<MethodSymbol> overloadResolutionResult, AnalyzedArguments analyzedArguments, LookupResultKind resultKind, ImmutableArray<Diagnostic> diagnostics, bool extensionMethodsOfSameViabilityAreAvailable) { Debug.Assert((methodGroup == null) || (methodGroup.Methods.Count > 0)); Debug.Assert((methodGroup == null) || ((object)otherSymbol == null)); // Methods should be represented in the method group. Debug.Assert(((object)otherSymbol == null) || (otherSymbol.Kind != SymbolKind.Method)); Debug.Assert(resultKind != LookupResultKind.Ambiguous); // HasAnyApplicableMethod is expecting Viable methods. Debug.Assert(!diagnostics.IsDefault); Debug.Assert(!extensionMethodsOfSameViabilityAreAvailable || methodGroup == null || !methodGroup.IsExtensionMethodGroup); this.MethodGroup = methodGroup; this.OtherSymbol = otherSymbol; this.OverloadResolutionResult = overloadResolutionResult; this.AnalyzedArguments = analyzedArguments; this.ResultKind = resultKind; this.Diagnostics = diagnostics; this.ExtensionMethodsOfSameViabilityAreAvailable = extensionMethodsOfSameViabilityAreAvailable; }
public BoundFunctionInvocationExpression(FunctionInvocationExpressionSyntax syntax, ImmutableArray<BoundExpression> arguments, OverloadResolutionResult<FunctionSymbolSignature> result) : base(BoundNodeKind.FunctionInvocationExpression) { Syntax = syntax; Arguments = arguments; Result = result; }
public BoundUnaryExpression(UnaryOperatorKind operatorKind, BoundExpression expression, OverloadResolutionResult<UnaryOperatorSignature> result) : base(BoundNodeKind.UnaryExpression) { OperatorKind = operatorKind; Expression = expression; Result = result; }
public BoundNumericConstructorInvocationExpression(NumericConstructorInvocationExpressionSyntax syntax, TypeSymbol type, ImmutableArray <BoundExpression> arguments, OverloadResolutionResult <FunctionSymbolSignature> result) : base(BoundNodeKind.NumericConstructorInvocationExpression) { Syntax = syntax; Type = type; Arguments = arguments; Result = result; }
public BoundBinaryExpression(BinaryOperatorKind operatorKind, BoundExpression left, BoundExpression right, OverloadResolutionResult <BinaryOperatorSignature> result) : base(BoundNodeKind.BinaryExpression) { OperatorKind = operatorKind; Left = left; Right = right; Result = result; }
public BoundNumericConstructorInvocationExpression(NumericConstructorInvocationExpressionSyntax syntax, TypeSymbol type, ImmutableArray<BoundExpression> arguments, OverloadResolutionResult<FunctionSymbolSignature> result) : base(BoundNodeKind.NumericConstructorInvocationExpression) { Syntax = syntax; Type = type; Arguments = arguments; Result = result; }
public MethodGroupResolution( MethodGroup methodGroup, OverloadResolutionResult <MethodSymbol> overloadResolutionResult, AnalyzedArguments analyzedArguments, ImmutableArray <Diagnostic> diagnostics) : this(methodGroup, null, overloadResolutionResult, analyzedArguments, methodGroup.ResultKind, diagnostics) { }
public BoundElementAccessExpression(BoundExpression expression, BoundExpression index, OverloadResolutionResult<IndexerSymbolSignature> result) : base(BoundNodeKind.ElementAccessExpression) { Expression = expression; Index = index; Result = result; Type = Symbol?.ValueType ?? TypeFacts.Unknown; }
public BoundMethodInvocationExpression(MethodInvocationExpressionSyntax syntax, BoundExpression target, ImmutableArray <BoundExpression> arguments, OverloadResolutionResult <FunctionSymbolSignature> result) : base(BoundNodeKind.MethodInvocationExpression) { Syntax = syntax; Target = target; Arguments = arguments; Result = result; }
public BoundElementAccessExpression(BoundExpression expression, BoundExpression index, OverloadResolutionResult <IndexerSymbolSignature> result) : base(BoundNodeKind.ElementAccessExpression) { Expression = expression; Index = index; Result = result; Type = Symbol?.ValueType ?? TypeFacts.Unknown; }
public BoundBinaryExpression(BinaryOperatorKind operatorKind, BoundExpression left, BoundExpression right, OverloadResolutionResult<BinaryOperatorSignature> result) : base(BoundNodeKind.BinaryExpression) { OperatorKind = operatorKind; Left = left; Right = right; Result = result; }
public MethodGroupResolution( MethodGroup methodGroup, OverloadResolutionResult<MethodSymbol> overloadResolutionResult, AnalyzedArguments analyzedArguments, ImmutableArray<Diagnostic> diagnostics) : this(methodGroup, null, overloadResolutionResult, analyzedArguments, methodGroup.ResultKind, diagnostics) { }
public BoundMethodInvocationExpression(MethodInvocationExpressionSyntax syntax, BoundExpression target, ImmutableArray<BoundExpression> arguments, OverloadResolutionResult<FunctionSymbolSignature> result) : base(BoundNodeKind.MethodInvocationExpression) { Syntax = syntax; Target = target; Arguments = arguments; Result = result; }
private static Conversion ToConversion(OverloadResolutionResult <MethodSymbol> result, MethodGroup methodGroup, NamedTypeSymbol delegateType) { // 6.6 An implicit conversion (6.1) exists from a method group (7.1) to a compatible // delegate type. Given a delegate type D and an expression E that is classified as // a method group, an implicit conversion exists from E to D if E contains at least // one method that is applicable in its normal form (7.5.3.1) to an argument list // constructed by use of the parameter types and modifiers of D... // 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 can capture methods // of object on a nullable receiver, but not GetValueOrDefault.) if (!result.Succeeded) { return(Conversion.NoConversion); } MethodSymbol method = result.BestResult.Member; if (methodGroup.IsExtensionMethodGroup && !method.Parameters[0].Type.IsReferenceType) { return(Conversion.NoConversion); } //cannot capture stack-only types. if (!method.IsStatic && methodGroup.Receiver?.Type?.IsRestrictedType() == true) { return(Conversion.NoConversion); } if (method.OriginalDefinition.ContainingType.SpecialType == SpecialType.System_Nullable_T && !method.IsOverride) { return(Conversion.NoConversion); } // NOTE: Section 6.6 will be slightly updated: // // - The candidate methods considered are only those methods that are applicable in their // normal form (§7.5.3.1), and do not omit any optional parameters. Thus, candidate methods // are ignored if they are applicable only in their expanded form, or if one or more of their // optional parameters do not have a corresponding parameter in the targeted delegate type. // // Therefore, we shouldn't get here unless the parameter count matches. // NOTE: Delegate type compatibility is important, but is not part of the existence check. Debug.Assert(method.ParameterCount == delegateType.DelegateInvokeMethod.ParameterCount + (methodGroup.IsExtensionMethodGroup ? 1 : 0)); return(new Conversion(ConversionKind.MethodGroup, method, methodGroup.IsExtensionMethodGroup)); }
public BoundFunctionInvocationExpression Update(IEnumerable<BoundExpression> arguments, OverloadResolutionResult<FunctionSymbolSignature> result) { var newArguments = arguments.ToImmutableArray(); if (newArguments == Arguments && result == Result) return this; return new BoundFunctionInvocationExpression(Syntax, newArguments, result); }
/// <summary> /// The overload resolution portion of FindForEachPatternMethod. /// </summary> private MethodSymbol PerformForEachPatternOverloadResolution(TypeSymbol patternType, ArrayBuilder <MethodSymbol> candidateMethods, bool warningsOnly, DiagnosticBag diagnostics) { ArrayBuilder <TypeSymbol> typeArguments = ArrayBuilder <TypeSymbol> .GetInstance(); AnalyzedArguments arguments = AnalyzedArguments.GetInstance(); OverloadResolutionResult <MethodSymbol> overloadResolutionResult = OverloadResolutionResult <MethodSymbol> .GetInstance(); HashSet <DiagnosticInfo> useSiteDiagnostics = null; this.OverloadResolution.MethodInvocationOverloadResolution(candidateMethods, typeArguments, arguments, overloadResolutionResult, ref useSiteDiagnostics); diagnostics.Add(syntax.Expression, useSiteDiagnostics); MethodSymbol result = null; if (overloadResolutionResult.Succeeded) { result = overloadResolutionResult.ValidResult.Member; if (result.IsStatic || result.DeclaredAccessibility != Accessibility.Public) { if (warningsOnly) { diagnostics.Add(ErrorCode.WRN_PatternStaticOrInaccessible, syntax.Expression.Location, patternType, MessageID.IDS_Collection.Localize(), result); } result = null; } else if (result.CallsAreOmitted(syntax.SyntaxTree)) { // Calls to this method are omitted in the current syntax tree, i.e it is either a partial method with no implementation part OR a conditional method whose condition is not true in this source file. // We don't want to want to allow this case, see StatementBinder::bindPatternToMethod. result = null; } } else if (overloadResolutionResult.Results.Length > 1) { if (warningsOnly) { diagnostics.Add(ErrorCode.WRN_PatternIsAmbiguous, syntax.Expression.Location, patternType, MessageID.IDS_Collection.Localize(), overloadResolutionResult.Results[0].Member, overloadResolutionResult.Results[1].Member); } } overloadResolutionResult.Free(); arguments.Free(); typeArguments.Free(); return(result); }
public Conversion MethodGroupConversion(CSharpSyntaxNode syntax, MethodGroup methodGroup, NamedTypeSymbol delegateType, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { var analyzedArguments = AnalyzedArguments.GetInstance(); var result = OverloadResolutionResult <MethodSymbol> .GetInstance(); Debug.Assert((object)delegateType.DelegateInvokeMethod != null && !delegateType.DelegateInvokeMethod.HasUseSiteError, "This method should only be called for valid delegate types"); GetDelegateArguments(syntax, analyzedArguments, delegateType.DelegateInvokeMethod.Parameters, Compilation); _binder.OverloadResolution.MethodInvocationOverloadResolution( methodGroup.Methods, methodGroup.TypeArguments, analyzedArguments, result, ref useSiteDiagnostics, isMethodGroupConversion: true); var conversion = ToConversion(result, methodGroup, delegateType); analyzedArguments.Free(); result.Free(); return(conversion); }
internal void ResolveOverloads <TMember>( ImmutableArray <TMember> members, ImmutableArray <TypeSymbol> typeArguments, ImmutableArray <ArgumentSyntax> arguments, OverloadResolutionResult <TMember> result, ref HashSet <DiagnosticInfo> useSiteDiagnostics, bool allowRefOmittedArguments) where TMember : Symbol { var methodsBuilder = ArrayBuilder <TMember> .GetInstance(members.Length); methodsBuilder.AddRange(members); var typeArgumentsBuilder = ArrayBuilder <TypeSymbol> .GetInstance(typeArguments.Length); typeArgumentsBuilder.AddRange(typeArguments); var analyzedArguments = AnalyzedArguments.GetInstance(); var unusedDiagnostics = DiagnosticBag.GetInstance(); foreach (var argumentSyntax in arguments) { var argument = this.BindExpression(argumentSyntax.Expression, unusedDiagnostics); analyzedArguments.Arguments.Add(argument); analyzedArguments.RefKinds.Add(argumentSyntax.RefOrOutKeyword.CSharpKind().GetRefKind()); analyzedArguments.Names.Add(argumentSyntax.NameColon == null ? null : argumentSyntax.NameColon.Name); } OverloadResolution.MethodOrPropertyOverloadResolution( methodsBuilder, typeArgumentsBuilder, analyzedArguments, result, isMethodGroupConversion: false, allowRefOmittedArguments: allowRefOmittedArguments, useSiteDiagnostics: ref useSiteDiagnostics); methodsBuilder.Free(); typeArgumentsBuilder.Free(); analyzedArguments.Free(); unusedDiagnostics.Free(); }
public MethodGroupResolution( MethodGroup methodGroup, Symbol otherSymbol, OverloadResolutionResult <MethodSymbol> overloadResolutionResult, AnalyzedArguments analyzedArguments, LookupResultKind resultKind, ImmutableArray <Diagnostic> diagnostics) { Debug.Assert((methodGroup == null) || (methodGroup.Methods.Count > 0)); Debug.Assert((methodGroup == null) || ((object)otherSymbol == null)); // Methods should be represented in the method group. Debug.Assert(((object)otherSymbol == null) || (otherSymbol.Kind != SymbolKind.Method)); Debug.Assert(resultKind != LookupResultKind.Ambiguous); // HasAnyApplicableMethod is expecting Viable methods. Debug.Assert(!diagnostics.IsDefault); this.MethodGroup = methodGroup; this.OtherSymbol = otherSymbol; this.OverloadResolutionResult = overloadResolutionResult; this.AnalyzedArguments = analyzedArguments; this.ResultKind = resultKind; this.Diagnostics = diagnostics; }
internal void ResolveOverloads <TMember>( ImmutableArray <TMember> members, ImmutableArray <TypeSymbol> typeArguments, ImmutableArray <ArgumentSyntax> arguments, OverloadResolutionResult <TMember> result, ref HashSet <DiagnosticInfo> useSiteDiagnostics, bool allowRefOmittedArguments) where TMember : Symbol { var methodsBuilder = ArrayBuilder <TMember> .GetInstance(members.Length); methodsBuilder.AddRange(members); var typeArgumentsBuilder = ArrayBuilder <TypeSymbol> .GetInstance(typeArguments.Length); typeArgumentsBuilder.AddRange(typeArguments); var analyzedArguments = AnalyzedArguments.GetInstance(); var unusedDiagnostics = DiagnosticBag.GetInstance(); foreach (var argumentSyntax in arguments) { BindArgumentAndName(analyzedArguments, unusedDiagnostics, false, argumentSyntax, allowArglist: false); } OverloadResolution.MethodOrPropertyOverloadResolution( methodsBuilder, typeArgumentsBuilder, analyzedArguments, result, isMethodGroupConversion: false, allowRefOmittedArguments: allowRefOmittedArguments, useSiteDiagnostics: ref useSiteDiagnostics); methodsBuilder.Free(); typeArgumentsBuilder.Free(); analyzedArguments.Free(); unusedDiagnostics.Free(); }
public BoundFunctionInvocationExpression(SyntaxNode syntax, IEnumerable <BoundExpression> arguments, OverloadResolutionResult <FunctionSymbolSignature> result) : base(BoundNodeKind.FunctionInvocationExpression, syntax) { Arguments = arguments.ToImmutableArray(); Result = result; }
public BoundFunctionInvocationExpression(FunctionInvocationExpressionSyntax syntax, ImmutableArray <BoundExpression> arguments, OverloadResolutionResult <FunctionSymbolSignature> result) : base(BoundNodeKind.FunctionInvocationExpression) { Syntax = syntax; Arguments = arguments; Result = result; }
public BoundUnaryExpression(UnaryOperatorKind operatorKind, BoundExpression expression, OverloadResolutionResult <UnaryOperatorSignature> result) : base(BoundNodeKind.UnaryExpression) { OperatorKind = operatorKind; Expression = expression; Result = result; }
public BoundFunctionInvocationExpression(SyntaxNode syntax, IEnumerable<BoundExpression> arguments, OverloadResolutionResult<FunctionSymbolSignature> result) : base(BoundNodeKind.FunctionInvocationExpression, syntax) { Arguments = arguments.ToImmutableArray(); Result = result; }
private static Conversion ToConversion(OverloadResolutionResult<MethodSymbol> result, MethodGroup methodGroup, NamedTypeSymbol delegateType) { // 6.6 An implicit conversion (6.1) exists from a method group (7.1) to a compatible // delegate type. Given a delegate type D and an expression E that is classified as // a method group, an implicit conversion exists from E to D if E contains at least // one method that is applicable in its normal form (7.5.3.1) to an argument list // constructed by use of the parameter types and modifiers of D... // 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 can capture methods // of object on a nullable receiver, but not GetValueOrDefault.) if (!result.Succeeded) { return Conversion.NoConversion; } MethodSymbol method = result.BestResult.Member; if (methodGroup.IsExtensionMethodGroup && !method.Parameters[0].Type.IsReferenceType) { return Conversion.NoConversion; } if (method.OriginalDefinition.ContainingType.SpecialType == SpecialType.System_Nullable_T && !method.IsOverride) { return Conversion.NoConversion; } // NOTE: Section 6.6 will be slightly updated: // // - The candidate methods considered are only those methods that are applicable in their // normal form (§7.5.3.1), and do not omit any optional parameters. Thus, candidate methods // are ignored if they are applicable only in their expanded form, or if one or more of their // optional parameters do not have a corresponding parameter in the targeted delegate type. // // Therefore, we shouldn't get here unless the parameter count matches. // NOTE: Delegate type compatibility is important, but is not part of the existence check. Debug.Assert(method.ParameterCount == delegateType.DelegateInvokeMethod.ParameterCount + (methodGroup.IsExtensionMethodGroup ? 1 : 0)); return new Conversion(ConversionKind.MethodGroup, method, methodGroup.IsExtensionMethodGroup); }
public BoundFunctionInvocationExpression Update(IEnumerable <BoundExpression> arguments, OverloadResolutionResult <FunctionSymbolSignature> result) { var newArguments = arguments.ToImmutableArray(); if (newArguments == Arguments && result == Result) { return(this); } return(new BoundFunctionInvocationExpression(Syntax, newArguments, result)); }