/// <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))); }
/// <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; }
/// <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)); }
/// <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)); }
/// <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))); } }
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)); }
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); }
/// <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); } }
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))); }
/// <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)); }
/// <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)); }
/// <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)); } } }
/// <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)); }
/// <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; }