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
        Expression LookInCurrentType(ResolveContext rc, string identifier, IList <IType> typeArguments, NameLookupMode lookupMode, bool parameterizeResultType)
        {
            int          k      = typeArguments.Count;
            MemberLookup lookup = rc.CreateMemberLookup(lookupMode);

            // look in current type definitions
            for (ITypeDefinition t = rc.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition)
            {
                if (k == 0)
                {
                    // Look for type parameter with that name
                    var typeParameters = t.TypeParameters;
                    // Look at all type parameters, including those copied from outer classes,
                    // so that we can fetch the version with the correct owner.
                    for (int i = 0; i < typeParameters.Count; i++)
                    {
                        if (typeParameters[i].Name == identifier)
                        {
                            return(new TypeExpression(typeParameters[i], Location));
                        }
                    }
                }

                if (lookupMode == NameLookupMode.BaseTypeReference && t == rc.CurrentTypeDefinition)
                {
                    // don't look in current type when resolving a base type reference
                    continue;
                }

                Expression r;
                if (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget)
                {
                    Expression targetResolveResult = (t == rc.CurrentTypeDefinition ? (Expression) new SelfReference(t, Location) : new TypeExpression(t, Location));
                    r = lookup.Lookup(targetResolveResult, identifier, typeArguments, lookupMode == NameLookupMode.InvocationTarget);
                }
                else
                {
                    r = lookup.LookupType(t, identifier, typeArguments, parameterizeResultType);
                }

                if (!(r is UnknownMemberExpression)) // but do return AmbiguousMemberResolveResult
                {
                    return(r);
                }
            }
            return(null);
        }
Esempio n. 3
0
        /// <summary>
        /// Resolves an indexer access.
        /// </summary>
        /// <param name="target">Target expression.</param>
        /// <param name="arguments">
        /// Arguments passed to the indexer.
        /// 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>
        /// <returns>ArrayAccessResolveResult, InvocationResolveResult, or ErrorResolveResult</returns>
        public Expression ResolveIndexer(ResolveContext rc, Expression target, Expression[] arguments, string[] argumentNames = null)
        {
            switch (target.Type.Kind)
            {
            case TypeKind.Array:
                // �6.6.1 Array access
                if (argumentNames != null && argumentNames.Length > 0)
                {
                    rc.Report.Error(0, Arguments.args.Where(x => x is NamedArgument).First().loc, "An element access expression cannot use named argument");
                }


                return(new ArrayAccessExpression(((ElementTypeSpec)target.Type).ElementType, target, arguments));

            case TypeKind.Pointer:
                // �.5.3 Pointer element access
                if (argumentNames != null && argumentNames.Length > 0)
                {
                    rc.Report.Error(0, Arguments.args.Where(x => x is NamedArgument).First().loc, "An element access expression cannot use named argument");
                }

                return(new PointerArithmeticExpression(((ElementTypeSpec)target.Type).ElementType, target, arguments));
            }

            // �6.6.2 Indexer access
            MemberLookup lookup   = rc.CreateMemberLookup();
            var          indexers = lookup.LookupIndexers(target);

            OverloadResolution or = rc.CreateOverloadResolution(arguments, argumentNames);

            or.AddMethodLists(indexers);
            if (or.BestCandidate != null)
            {
                return(or.CreateInvocation(target));
            }
            else
            {
                rc.Report.Error(0, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
                                target.Type.ToString());
                return(null);
            }
        }
Esempio n. 4
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);
        }