Example #1
0
        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;
 }
Example #9
0
 public BoundMethodInvocationExpression(MethodInvocationExpressionSyntax syntax, BoundExpression target, ImmutableArray <BoundExpression> arguments, OverloadResolutionResult <FunctionSymbolSignature> result)
     : base(BoundNodeKind.MethodInvocationExpression)
 {
     Syntax    = syntax;
     Target    = target;
     Arguments = arguments;
     Result    = result;
 }
Example #10
0
 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;
 }
Example #12
0
 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;
 }
Example #14
0
        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);
        }
Example #16
0
        /// <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);
        }
Example #17
0
        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);
        }
Example #18
0
        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;
        }
Example #20
0
        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();
        }
Example #21
0
 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);
        }
Example #26
0
        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));
        }