Exemplo n.º 1
0
        /// <summary>
        /// Resolves an invocation.
        /// </summary>
        /// <param name="target">The target of the invocation. Usually a MethodGroupResolveResult.</param>
        /// <param name="arguments">
        /// Arguments passed to the method.
        /// The resolver may mutate this array to wrap elements in <see cref="ConversionResolveResult"/>s!
        /// </param>
        /// <param name="argumentNames">
        /// The argument names. Pass the null string for positional arguments.
        /// </param>
        /// <returns>InvocationExpression</returns>
        private Expression ResolveInvocation(ResolveContext rc, Expression target, Expression[] arguments, string[] argumentNames, bool allowOptionalParameters)
        {
            // C# 4.0 spec: §7.6.5
            MethodGroupExpression mgrr = target as MethodGroupExpression;

            if (mgrr != null)
            {
                OverloadResolution or = mgrr.PerformOverloadResolution(rc.compilation, arguments, argumentNames, checkForOverflow: rc.checkForOverflow, conversions: rc.conversions, allowOptionalParameters: allowOptionalParameters);
                if (or.BestCandidate != null)
                {
                    var m = or.BestCandidate;

                    if (arguments == null && m.Name == DestructorDeclaration.MetadataName)
                    {
                        rc.Report.Error(0, loc, "Destructors cannot be called directly. Consider calling IDisposable.Dispose if available");
                    }

                    CheckSpecialMethod(rc, m);


                    if (or.BestCandidate.IsStatic && !or.IsExtensionMethodInvocation && !(mgrr.TargetResult is TypeExpression))
                    {
                        return(or.CreateInvocation(new TypeExpression(mgrr.TargetType), returnTypeOverride:  null));
                    }
                    else
                    {
                        return(or.CreateInvocation(mgrr.TargetResult, returnTypeOverride: null));
                    }
                }
                else
                {
                    // No candidate found at all (not even an inapplicable one).
                    // This can happen with empty method groups (as sometimes used with extension methods)
                    rc.Report.Error(0, loc, "`{0}' does not contain a definition for `{1}'",
                                    mgrr.TargetType.ToString(), mgrr.MethodName);
                    return(null);
                }
            }
            if (target == null && expr is SimpleName)
            {
                rc.Report.Error(0, loc, "`{0}' does not contain a definition for `{1}'",
                                rc.CurrentTypeDefinition.ToString(), expr.GetSignatureForError());
                return(null);
            }
            else if (target == null)
            {
                return(null);
            }


            IMethod invokeMethod = target.Type.GetDelegateInvokeMethod();

            if (invokeMethod != null)
            {
                // is it a delegate ?
                if (target.Type.Kind != TypeKind.Delegate)
                {
                    rc.Report.Error(0, loc, "Cannot invoke a non-delegate type `{0}'",
                                    target.Type.ToString());
                    return(null);
                }
                OverloadResolution or = rc.CreateOverloadResolution(arguments, argumentNames);
                or.AddCandidate(invokeMethod);

                return(new Invocation(
                           target, invokeMethod, //invokeMethod.ReturnType.Resolve(context),
                           or.GetArgumentsWithConversionsAndNames(), or.BestCandidateErrors,
                           isExpandedForm: or.BestCandidateIsExpandedForm,
                           isDelegateInvocation: true,
                           argumentToParameterMap: or.GetArgumentToParameterMap(),
                           returnTypeOverride: null));
            }

            rc.Report.Error(0, loc, "The member `{0}' cannot be used as method or delegate",
                            target.GetSignatureForError());

            return(ErrorResult);
        }