Ejemplo n.º 1
0
        protected BoundExpression MakeConstruction(CSharpSyntaxNode node, NamedTypeSymbol toCreate, ImmutableArray <BoundExpression> args, DiagnosticBag diagnostics)
        {
            AnalyzedArguments analyzedArguments = AnalyzedArguments.GetInstance();

            analyzedArguments.Arguments.AddRange(args);
            var result = BindClassCreationExpression(node, toCreate.Name, node, toCreate, analyzedArguments, diagnostics);

            result.WasCompilerGenerated = true;
            analyzedArguments.Free();
            return(result);
        }
Ejemplo n.º 2
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, isMethodGroupConversion: true, inferWithDynamic: true, useSiteDiagnostics: ref useSiteDiagnostics);
         analyzedArguments.Free();
         return(resolution);
     }
     else
     {
         return(binder.ResolveMethodGroup(source, null, isMethodGroupConversion: true, useSiteDiagnostics: ref useSiteDiagnostics));
     }
 }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
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();
        }
Ejemplo n.º 6
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();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Find the Deconstruct method for the expression on the right, that will fit the number of assignable variables on the left.
        /// Returns an invocation expression if the Deconstruct method is found.
        ///     If so, it outputs placeholders that were coerced to the output types of the resolved Deconstruct method.
        /// The overload resolution is similar to writing `receiver.Deconstruct(out var x1, out var x2, ...)`.
        /// </summary>
        private BoundExpression MakeDeconstructInvocationExpression(
            int numCheckedVariables, BoundExpression receiver, CSharpSyntaxNode syntax,
            DiagnosticBag diagnostics, out ImmutableArray <BoundDeconstructValuePlaceholder> outPlaceholders)
        {
            var receiverSyntax = receiver.Syntax;

            if (receiver.Type.IsDynamic())
            {
                Error(diagnostics, ErrorCode.ERR_CannotDeconstructDynamic, receiverSyntax);
                outPlaceholders = default(ImmutableArray <BoundDeconstructValuePlaceholder>);

                return(BadExpression(receiverSyntax, receiver));
            }

            var analyzedArguments = AnalyzedArguments.GetInstance();
            var outVars           = ArrayBuilder <OutDeconstructVarPendingInference> .GetInstance(numCheckedVariables);

            DiagnosticBag bag = null;

            try
            {
                for (int i = 0; i < numCheckedVariables; i++)
                {
                    var variable = new OutDeconstructVarPendingInference(syntax);
                    analyzedArguments.Arguments.Add(variable);
                    analyzedArguments.RefKinds.Add(RefKind.Out);
                    outVars.Add(variable);
                }

                const string methodName   = "Deconstruct";
                var          memberAccess = BindInstanceMemberAccess(
                    receiverSyntax, receiverSyntax, receiver, methodName, rightArity: 0,
                    typeArgumentsSyntax: default(SeparatedSyntaxList <TypeSyntax>), typeArguments: default(ImmutableArray <TypeSymbol>),
                    invoked: true, diagnostics: diagnostics);

                memberAccess = CheckValue(memberAccess, BindValueKind.RValueOrMethodGroup, diagnostics);
                memberAccess.WasCompilerGenerated = true;

                if (memberAccess.Kind != BoundKind.MethodGroup)
                {
                    return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, receiver));
                }

                // After the overload resolution completes, the last step is to coerce the arguments with inferred types.
                // That step returns placeholder (of correct type) instead of the outVar nodes that were passed in as arguments.
                // So the generated invocation expression will contain placeholders instead of those outVar nodes.
                // Those placeholders are also recorded in the outVar for easy access below, by the `SetInferredType` call on the outVar nodes.
                bag = DiagnosticBag.GetInstance();
                BoundExpression result = BindMethodGroupInvocation(
                    receiverSyntax, receiverSyntax, methodName, (BoundMethodGroup)memberAccess, analyzedArguments, bag, queryClause: null,
                    allowUnexpandedForm: true);

                result.WasCompilerGenerated = true;
                diagnostics.AddRange(bag);

                if (bag.HasAnyErrors())
                {
                    return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result));
                }

                // Verify all the parameters (except "this" for extension methods) are out parameters
                if (result.Kind != BoundKind.Call)
                {
                    return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result));
                }

                var deconstructMethod = ((BoundCall)result).Method;
                var parameters        = deconstructMethod.Parameters;
                for (int i = (deconstructMethod.IsExtensionMethod ? 1 : 0); i < parameters.Length; i++)
                {
                    if (parameters[i].RefKind != RefKind.Out)
                    {
                        return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result));
                    }
                }

                if (outVars.Any(v => (object)v.Placeholder == null))
                {
                    return(MissingDeconstruct(receiver, syntax, numCheckedVariables, diagnostics, out outPlaceholders, result));
                }

                outPlaceholders = outVars.SelectAsArray(v => v.Placeholder);

                return(result);
            }
            finally
            {
                analyzedArguments.Free();
                outVars.Free();

                if (bag != null)
                {
                    bag.Free();
                }
            }
        }
Ejemplo n.º 8
0
        private void BindPCallNativeAndDelegate(InvocationExpressionSyntax node, ArrayBuilder <BoundExpression> args,
                                                DiagnosticBag diagnostics, TypeSyntax type)
        {
            var    XNode  = node.XNode as XP.MethodCallContext;
            string method = XNode?.Expr.GetText();

            if (string.IsNullOrEmpty(method))
            {
                method = "PCALLNATIVE";
            }
            if (!ValidatePCallArguments(node, args, diagnostics, method))
            {
                return;
            }
            // Our parent is the invocation expression of the delegate
            AnalyzedArguments analyzedArguments = AnalyzedArguments.GetInstance();

            try
            {
                var ts = FindPCallDelegateType(type as IdentifierNameSyntax);
                if (ts != null && ts.IsDelegateType())
                {
                    SourceDelegateMethodSymbol delmeth = ts.DelegateInvokeMethod() as SourceDelegateMethodSymbol;
                    // create new parameters based on the parameters from out parent call
                    var invoke    = node.Parent as InvocationExpressionSyntax;
                    var realargs  = invoke.ArgumentList;
                    var delparams = ts.DelegateParameters();
                    BindArgumentsAndNames(realargs, diagnostics, analyzedArguments);
                    var builder = ArrayBuilder <ParameterSymbol> .GetInstance();

                    int i = 0;
                    foreach (var expr in analyzedArguments.Arguments)
                    {
                        var ptype = expr.Type;
                        if (ptype == null)
                        {
                            ptype = new PointerTypeSymbol(Compilation.GetSpecialType(SpecialType.System_Void));
                        }
                        var parameter = new SourceSimpleParameterSymbol(
                            delmeth,
                            ptype,
                            i,
                            delparams[i].RefKind,
                            delparams[i].Name,
                            delparams[i].Locations);
                        builder.Add(parameter);
                        i++;
                    }
                    delmeth.InitializeParameters(builder.ToImmutableAndFree());
                }
                else
                {
                    Error(diagnostics, ErrorCode.ERR_PCallResolveGeneratedDelegate, node, method, type.ToString());
                }

                return;
            }
            finally
            {
                analyzedArguments.Free();
            }
        }