Пример #1
0
 /// <summary>
 /// Resolves a type reference.
 /// </summary>
 /// <param name="typeRef">The type reference to resolve.</param>
 /// <param name="assembly">The assembly in which the reference occurs.</param>
 /// <param name="enclosingMember">
 /// The generic member that references a particular type. If non-null, type
 /// parameters are resolved from this member.
 /// </param>
 /// <returns>The type referred to by the reference.</returns>
 internal IType Resolve(
     TypeReference typeRef,
     ClrAssembly assembly,
     IGenericMember enclosingMember)
 {
     return(Resolve(typeRef, assembly, enclosingMember, false));
 }
 /// <summary>
 /// Creates a generic parameter specialization from a generic parameter
 /// and a parent type that is itself an (indirect) generic type.
 /// </summary>
 /// <param name="declaration">
 /// The generic parameter to specialize.
 /// </param>
 /// <param name="parentMember">
 /// A specialization of the generic declaration's parent member.
 /// </param>
 /// <returns>A specialization of the generic declaration.</returns>
 internal static IndirectGenericParameterSpecialization Create(
     IGenericParameter declaration,
     IGenericMember parentMember)
 {
     return(instanceCache.Intern(
                new IndirectGenericParameterSpecialization(declaration, parentMember)));
 }
Пример #3
0
 /// <summary>
 /// Creates a generic parameter from a declaring member
 /// and a name.
 /// </summary>
 /// <param name="parentMember">
 /// The member that declares the generic parameter.
 /// </param>
 /// <param name="name">
 /// The generic parameter's name.
 /// </param>
 public DescribedGenericParameter(
     IGenericMember parentMember,
     SimpleName name)
     : base(name.Qualify(parentMember.FullName))
 {
     this.ParentMember = parentMember;
 }
Пример #4
0
 /// <summary>
 /// Finds all generic parameters defined by a particular member that have
 /// a specific imprecise unqualified name.
 /// </summary>
 /// <param name="parentMember">
 /// The generic member that defines the generic parameters.
 /// </param>
 /// <param name="name">The imprecise unqualified name to look for.</param>
 /// <returns>
 /// A list of generic parameters that are defined by <paramref name="parentMember"/>
 /// and have name <paramref name="name"/>. This includes all simply
 /// named types with name <paramref name="name"/>, regardless of
 /// the number of type parameters in the type's name.
 /// </returns>
 public IReadOnlyList <IType> ResolveGenericParameters(
     IGenericMember parentMember,
     string name)
 {
     return(ResolveGenericParametersImpl <string>(
                parentMember,
                name,
                ResolveImprecise));
 }
Пример #5
0
 /// <summary>
 /// Finds all generic parameters defined by a particular member that have
 /// a specific unqualified name.
 /// </summary>
 /// <param name="parentMember">
 /// The generic member that defines the generic parameters.
 /// </param>
 /// <param name="name">The unqualified name to look for.</param>
 /// <returns>
 /// A list of generic parameters that are defined by <paramref name="parentMember"/>
 /// and have name <paramref name="name"/>.
 /// </returns>
 public IReadOnlyList <IType> ResolveGenericParameters(
     IGenericMember parentMember,
     UnqualifiedName name)
 {
     return(ResolveGenericParametersImpl <UnqualifiedName>(
                parentMember,
                name,
                ResolvePrecise));
 }
Пример #6
0
 /// <summary>
 /// Encodes a generic member reference.
 /// </summary>
 /// <returns>An encoded generic member reference.</returns>
 /// <param name="genericMember">The generic member to encode.</param>
 public LNode Encode(IGenericMember genericMember)
 {
     if (genericMember is IType)
     {
         return(Factory.Call(typeHintSymbol, Encode((IType)genericMember)));
     }
     else
     {
         return(Factory.Call(methodHintSymbol, Encode((IMethod)genericMember)));
     }
 }
Пример #7
0
        private IReadOnlyList <IType> ResolveGenericParametersImpl <T>(
            IGenericMember parentMember,
            T name,
            Func <TypeResolverNamespace, T, IReadOnlyList <IType> > resolve)
        {
            var typeNamespace = genericMemberNamespaces.GetOrAdd(
                parentMember,
                CreateGenericParameterNamespace);

            return(resolve(typeNamespace, name));
        }
Пример #8
0
        private static TypeResolverNamespace CreateGenericParameterNamespace(IGenericMember member)
        {
            var originalPathLength = member.FullName.PathLength;

            var result = new TypeResolverNamespace();

            foreach (var genericParam in member.GenericParameters)
            {
                result.Add(genericParam.FullName.Slice(originalPathLength), genericParam);
            }
            return(result);
        }
        /// <summary>
        /// Specializes the generic parameter list of a generic member to
        /// an indirectly specialized generic parameter list for a
        /// specialization of the aforementioned generic member.
        /// </summary>
        /// <param name="genericMember">
        /// The original generic member whose generic parameters are specialized.
        /// </param>
        /// <param name="specializedMember">
        /// The proud parent of the indirectly specialized generic parameters
        /// produced by this method.
        /// </param>
        /// <returns>
        /// A list of indirectly specialized generic parameters.
        /// </returns>
        internal static IReadOnlyList <IndirectGenericParameterSpecialization> CreateAll(
            IGenericMember genericMember,
            IGenericMember specializedMember)
        {
            var originalTypeParams = genericMember.GenericParameters;
            var results            = new IndirectGenericParameterSpecialization[originalTypeParams.Count];

            for (int i = 0; i < results.Length; i++)
            {
                results[i] = Create(originalTypeParams[i], specializedMember);
            }
            return(results);
        }
Пример #10
0
 /// <summary>
 /// Decodes an LNode as a reference to a generic member.
 /// Logs an error if the decoding process fails.
 /// </summary>
 /// <param name="node">A node to decode as a generic member.</param>
 /// <param name="genericMember">The generic member described by <paramref name="node"/>.</param>
 /// <returns>
 /// <c>true</c> if <paramref name="node"/> can be decoded as a
 /// generic member; otherwise, <c>false</c>.
 /// </returns>
 public bool AssertDecodeGenericMember(
     LNode node,
     out IGenericMember genericMember)
 {
     if (node.Calls(EncoderState.typeHintSymbol))
     {
         if (!FeedbackHelpers.AssertArgCount(node, 1, Log))
         {
             genericMember = null;
             return(false);
         }
         else
         {
             var type = DecodeType(node.Args[0]);
             genericMember = type;
             return(!(type == null || type is ErrorType));
         }
     }
     else if (node.Calls(EncoderState.methodHintSymbol))
     {
         if (!FeedbackHelpers.AssertArgCount(node, 1, Log))
         {
             genericMember = null;
             return(false);
         }
         else
         {
             var method = DecodeMethod(node.Args[0]);
             genericMember = method;
             return(method != null);
         }
     }
     else
     {
         FeedbackHelpers.LogSyntaxError(
             Log,
             node,
             FeedbackHelpers.QuoteEven(
                 "unknown kind of generic member; " +
                 "generic member kinds must be hinted using either ",
                 EncoderState.methodHintSymbol.ToString(),
                 " or ",
                 EncoderState.typeHintSymbol.ToString(),
                 " nodes."));
         genericMember = null;
         return(false);
     }
 }
Пример #11
0
        internal static Parameter WrapReturnParameter(
            MethodReturnType returnParameter,
            ClrAssembly assembly,
            IGenericMember enclosingMember)
        {
            var attrBuilder = new AttributeMapBuilder();

            // TODO: actually analyze the parameter's attributes.
            return(new Parameter(
                       TypeHelpers.BoxIfReferenceType(
                           assembly.Resolve(
                               returnParameter.ReturnType,
                               enclosingMember)),
                       returnParameter.Name,
                       new AttributeMap(attrBuilder)));
        }
Пример #12
0
 /// <summary>
 /// Resolves a type reference declared in this assembly.
 /// </summary>
 /// <param name="typeRef">The type reference to resolve.</param>
 /// <param name="enclosingMember">
 /// The generic member that references a particular type. If non-null, type
 /// parameters are resolved from this member.
 /// </param>
 /// <returns>A type referred to by the reference.</returns>
 internal IType Resolve(TypeReference typeRef, IGenericMember enclosingMember)
 {
     return(Resolver.Resolve(typeRef, this, enclosingMember));
 }
Пример #13
0
 /// <summary>
 /// Finds all generic parameters defined by a particular member that have
 /// a specific unqualified name.
 /// </summary>
 /// <param name="parentMember">
 /// The generic member that defines the generic parameters.
 /// </param>
 /// <param name="name">The unqualified name to look for.</param>
 /// <returns>
 /// A list of generic parameters that are defined by <paramref name="parentMember"/>
 /// and have name <paramref name="name"/>.
 /// </returns>
 public IReadOnlyList <IType> ResolveGenericParameters(
     IGenericMember parentMember,
     UnqualifiedName name)
 {
     return(resolver.ResolveGenericParameters(parentMember, name));
 }
Пример #14
0
        /// <summary>
        /// Resolves a type reference.
        /// </summary>
        /// <param name="typeRef">The type reference to resolve.</param>
        /// <param name="assembly">The assembly in which the reference occurs.</param>
        /// <param name="enclosingMember">
        /// The generic member that references a particular type. If non-null, type
        /// parameters are resolved from this member.
        /// </param>
        /// <param name="useStandins">
        /// A Boolean that specifies if stand-ins should be used for generic parameters.
        /// </param>
        /// <returns>The type referred to by the reference.</returns>
        private IType Resolve(
            TypeReference typeRef,
            ClrAssembly assembly,
            IGenericMember enclosingMember,
            bool useStandins)
        {
            if (typeRef is TypeSpecification)
            {
                var typeSpec = (TypeSpecification)typeRef;
                var elemType = Resolve(typeSpec.ElementType, assembly, enclosingMember, useStandins);
                if (typeSpec is GenericInstanceType)
                {
                    var genInstType = (GenericInstanceType)typeSpec;
                    return(elemType.MakeRecursiveGenericType(
                               genInstType.GenericArguments
                               .Select(arg => Resolve(arg, assembly, enclosingMember, useStandins))
                               .Zip(elemType.GetRecursiveGenericParameters(), BoxTypeArgumentIfNecessary)
                               .ToArray()));
                }
                else if (typeSpec is Mono.Cecil.PointerType)
                {
                    return(TypeHelpers.BoxIfReferenceType(elemType)
                           .MakePointerType(PointerKind.Transient));
                }
                else if (typeSpec is ByReferenceType)
                {
                    return(TypeHelpers.BoxIfReferenceType(elemType)
                           .MakePointerType(PointerKind.Reference));
                }
                else if (typeSpec is Mono.Cecil.ArrayType)
                {
                    var   arraySpec = (Mono.Cecil.ArrayType)typeSpec;
                    var   boxedElem = TypeHelpers.BoxIfReferenceType(elemType);
                    IType arrayType;
                    if (TypeEnvironment.TryMakeArrayType(
                            boxedElem,
                            arraySpec.Rank,
                            out arrayType))
                    {
                        return(arrayType);
                    }
                    else
                    {
                        throw new NotSupportedException(
                                  "Cannot resolve array specification '" +
                                  typeSpec.ToString() + "' because the type environment " +
                                  "does not support arrays with that element type and rank.");
                    }
                }
                else if (typeSpec is Mono.Cecil.IModifierType)
                {
                    var modType = Resolve(
                        ((Mono.Cecil.IModifierType)typeSpec).ModifierType,
                        assembly,
                        enclosingMember,
                        useStandins);

                    return(ClrModifierType.Create(elemType, modType, typeSpec.IsRequiredModifier));
                }
                else
                {
                    throw new NotSupportedException(
                              "Unsupported kind of type specification '" +
                              typeSpec.ToString() + "'.");
                }
            }
            else if (typeRef is GenericParameter)
            {
                var genericParam = (GenericParameter)typeRef;
                if (useStandins)
                {
                    return(ClrGenericParameterStandin.Create(
                               genericParam.Type,
                               genericParam.Position));
                }
                else if (genericParam.DeclaringMethod == null)
                {
                    var declType = enclosingMember is IType
                        ? (IType)enclosingMember
                        : enclosingMember is IMethod
                            ? ((IMethod)enclosingMember).ParentType
                            : Resolve(
                        genericParam.DeclaringType,
                        assembly,
                        enclosingMember,
                        useStandins);

                    return(declType.GetRecursiveGenericParameters()[genericParam.Position]);
                }
                else
                {
                    var declMethod = enclosingMember is IMethod
                        ? (IMethod)enclosingMember
                        : Resolve(genericParam.DeclaringMethod, assembly);
                    return(declMethod.GenericParameters[genericParam.Position]);
                }
            }
            else
            {
                if (typeRef.DeclaringType != null)
                {
                    var declType = Resolve(
                        typeRef.DeclaringType,
                        assembly,
                        enclosingMember,
                        useStandins);

                    var nestedTypes = GetTypeResolver(assembly).ResolveNestedTypes(
                        declType,
                        NameConversion.ParseSimpleName(typeRef.Name));
                    return(PickSingleResolvedType(typeRef, nestedTypes));
                }

                var scope = typeRef.Scope;

                if (scope == null)
                {
                    throw new ResolutionException(typeRef);
                }

                switch (scope.MetadataScopeType)
                {
                case MetadataScopeType.AssemblyNameReference:
                    return(FindInAssembly(typeRef, Resolve((AssemblyNameReference)scope)));

                case MetadataScopeType.ModuleDefinition:
                case MetadataScopeType.ModuleReference:
                default:
                    return(FindInAssembly(typeRef, assembly));
                }
            }
        }
Пример #15
0
 /// <summary>
 /// Finds all generic parameters defined by a particular member that have
 /// a specific imprecise unqualified name.
 /// </summary>
 /// <param name="parentMember">
 /// The generic member that defines the generic parameters.
 /// </param>
 /// <param name="name">The imprecise unqualified name to look for.</param>
 /// <returns>
 /// A list of generic parameters that are defined by <paramref name="parentMember"/>
 /// and have name <paramref name="name"/>. This includes all simply
 /// named types with name <paramref name="name"/>, regardless of
 /// the number of type parameters in the type's name.
 /// </returns>
 public IReadOnlyList <IType> ResolveGenericParameters(
     IGenericMember parentMember,
     string name)
 {
     return(resolver.ResolveGenericParameters(parentMember, name));
 }
Пример #16
0
 /// <summary>
 /// Creates a generic parameter from a declaring member
 /// and a name.
 /// </summary>
 /// <param name="parentMember">
 /// The member that declares the generic parameter.
 /// </param>
 /// <param name="name">
 /// The generic parameter's name.
 /// </param>
 public DescribedGenericParameter(
     IGenericMember parentMember,
     string name)
     : this(parentMember, new SimpleName(name))
 {
 }
 private IndirectGenericParameterSpecialization(
     IGenericParameter declaration, IGenericMember parentMember)
     : base(declaration)
 {
     this.ParentMember = parentMember;
 }