Esempio n. 1
0
        /// <summary>
        /// Resolves an object creation.
        /// </summary>
        /// <param name="type">Type of the object to create.</param>
        /// <param name="arguments">
        /// Arguments passed to the constructor.
        /// The resolver may mutate this array to wrap elements in <see cref="CastExpression"/>s!
        /// </param>
        /// <param name="argumentNames">
        /// The argument names. Pass the null string for positional arguments.
        /// </param>
        /// <param name="allowProtectedAccess">
        /// Whether to allow calling protected constructors.
        /// This should be false except when resolving constructor initializers.
        /// </param>
        /// <param name="initializerStatements">
        /// Statements for Objects/Collections initializer.
        /// <see cref="InvocationExpression.InitializerStatements"/>
        /// </param>
        /// <returns>InvocationResolveResult or ErrorResolveResult</returns>
        public static Expression ResolveObjectCreation(ResolveContext rc, Location l, IType type, Expression[] arguments, string[] argumentNames = null, bool allowProtectedAccess = false, IList <Expression> initializerStatements = null)
        {
            if (type.Kind == TypeKind.Delegate)
            {
                if (arguments == null || arguments.Length != 1)
                {
                    rc.Report.Error(0, l, "Method name expected");
                    return(null);
                }
                Expression input  = arguments[0];
                IMethod    invoke = input.Type.GetDelegateInvokeMethod();
                if (invoke != null)
                {
                    input = new MethodGroupExpression(
                        input, invoke.Name,
                        methods: new[] { new MethodListWithDeclaringType(input.Type)
                                         {
                                             invoke
                                         } },
                        typeArguments: EmptyList <IType> .Instance
                        );
                }
                return(rc.Convert(input, type));
            }
            OverloadResolution or            = rc.CreateOverloadResolution(arguments, argumentNames);
            MemberLookup       lookup        = rc.CreateMemberLookup();
            List <IMethod>     allApplicable = null;

            foreach (IMethod ctor in type.GetConstructors())
            {
                if (lookup.IsAccessible(ctor, allowProtectedAccess))
                {
                    or.AddCandidate(ctor);
                }
                else
                {
                    or.AddCandidate(ctor, OverloadResolutionErrors.Inaccessible);
                }
            }
            if (or.BestCandidate != null)
            {
                return(or.CreateInvocation(null, initializerStatements));
            }
            else
            {
                rc.Report.Error(0, l,
                                "The type `{0}' does not contain a constructor that takes `{1}' arguments",
                                type.ToString(), arguments != null ? arguments.Length.ToString() : "0");
                return(ErrorResult);
            }
        }
Esempio n. 2
0
        public Expression ResolveMemberAccess(ResolveContext rc, VSC.AST.Expression target, string identifier, IList <IType> typeArguments, NameLookupMode lookupMode = NameLookupMode.Expression)
        {
            // V# 4.0 spec: §7.6.4

            bool           parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));
            AliasNamespace nrr = target as AliasNamespace;

            if (nrr != null)
            {
                return(ResolveMemberAccessOnNamespace(nrr, identifier, typeArguments, parameterizeResultType));
            }

            // TODO:Dynamic Resolution
            //if (target.Type.Kind == TypeKind.Dynamic)
            //    return new DynamicMemberResolveResult(target, identifier);

            MemberLookup lookup = rc.CreateMemberLookup(lookupMode);
            Expression   result;

            switch (lookupMode)
            {
            case NameLookupMode.Expression:
                result = lookup.Lookup(target, identifier, typeArguments, isInvocation: false);
                break;

            case NameLookupMode.InvocationTarget:
                result = lookup.Lookup(target, identifier, typeArguments, isInvocation: true);
                break;

            case NameLookupMode.Type:
            case NameLookupMode.TypeInUsingDeclaration:
            case NameLookupMode.BaseTypeReference:
                // Don't do the UnknownMemberResolveResult/MethodGroupResolveResult processing,
                // it's only relevant for expressions.
                return(lookup.LookupType(target.Type, identifier, typeArguments, parameterizeResultType));

            default:
                throw new NotSupportedException("Invalid value for NameLookupMode");
            }
            if (result is UnknownMemberExpression)
            {
                // We intentionally use all extension methods here, not just the eligible ones.
                // Proper eligibility checking is only possible for the full invocation
                // (after we know the remaining arguments).
                // The eligibility check in GetExtensionMethods is only intended for code completion.
                var extensionMethods = rc.GetExtensionMethods(identifier, typeArguments);
                if (extensionMethods.Count > 0)
                {
                    return(new MethodGroupExpression(target, identifier, EmptyList <MethodListWithDeclaringType> .Instance, typeArguments)
                    {
                        extensionMethods = extensionMethods
                    });
                }
            }
            else
            {
                MethodGroupExpression mgrr = result as MethodGroupExpression;
                if (mgrr != null)
                {
                    Debug.Assert(mgrr.extensionMethods == null);
                    // set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work
                    mgrr.resolver = rc;
                }
            }
            return(result);
        }
Esempio n. 3
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);
        }