| File: System\Reflection\TypeLoading\Types\Ecma\EcmaDefinitionType.cs | Web Access |
| Project: src\runtime\src\libraries\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj (System.Reflection.MetadataLoadContext) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Diagnostics; using System.Reflection.Metadata; namespace System.Reflection.TypeLoading.Ecma { /// <summary> /// RoTypes that return true for IsTypeDefinition and get its metadata from a PEReader. /// </summary> internal sealed partial class EcmaDefinitionType : RoDefinitionType { private readonly EcmaModule _module; private readonly TypeDefinitionHandle _handle; internal EcmaDefinitionType(TypeDefinitionHandle handle, EcmaModule module) : base() { Debug.Assert(module != null); Debug.Assert(!handle.IsNil); _module = module; _handle = handle; _neverAccessThisExceptThroughTypeDefinitionProperty = handle.GetTypeDefinition(Reader); } internal sealed override RoModule GetRoModule() => _module; internal EcmaModule GetEcmaModule() => _module; protected sealed override RoType? ComputeDeclaringType() { if (!TypeDefinition.IsNested) return null; return TypeDefinition.GetDeclaringType().ResolveTypeDef(GetEcmaModule()); } protected sealed override string ComputeName() => TypeDefinition.Name.GetString(Reader).EscapeTypeNameIdentifier(); protected sealed override string? ComputeNamespace() { Type? declaringType = DeclaringType; if (declaringType != null) return declaringType.Namespace; return TypeDefinition.Namespace.GetStringOrNull(Reader)?.EscapeTypeNameIdentifier(); } protected sealed override TypeAttributes ComputeAttributeFlags() => TypeDefinition.Attributes; internal sealed override RoType? SpecializeBaseType(RoType[] instantiation) { EntityHandle baseTypeHandle = TypeDefinition.BaseType; if (baseTypeHandle.IsNil) return null; return baseTypeHandle.ResolveTypeDefRefOrSpec(GetEcmaModule(), instantiation.ToTypeContext()); } internal sealed override IEnumerable<RoType> SpecializeInterfaces(RoType[] instantiation) { MetadataReader reader = Reader; EcmaModule module = GetEcmaModule(); TypeContext typeContext = instantiation.ToTypeContext(); foreach (InterfaceImplementationHandle h in TypeDefinition.GetInterfaceImplementations()) { InterfaceImplementation ifc = h.GetInterfaceImplementation(reader); yield return ifc.Interface.ResolveTypeDefRefOrSpec(module, typeContext); } } protected sealed override IEnumerable<CustomAttributeData> GetTrueCustomAttributes() => TypeDefinition.GetCustomAttributes().ToTrueCustomAttributes(GetEcmaModule()); internal sealed override bool IsCustomAttributeDefined(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name) => TypeDefinition.GetCustomAttributes().IsCustomAttributeDefined(ns, name, GetEcmaModule()); internal sealed override CustomAttributeData? TryFindCustomAttribute(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name) => TypeDefinition.GetCustomAttributes().TryFindCustomAttribute(ns, name, GetEcmaModule()); public sealed override int MetadataToken => _handle.GetToken(); public sealed override bool IsGenericTypeDefinition => GetGenericParameterCount() != 0; internal sealed override int GetGenericParameterCount() => GetGenericTypeParametersNoCopy().Length; internal sealed override RoType[] GetGenericTypeParametersNoCopy() => _lazyGenericParameters ??= ComputeGenericTypeParameters(); private RoType[] ComputeGenericTypeParameters() { EcmaModule module = GetEcmaModule(); GenericParameterHandleCollection gps = TypeDefinition.GetGenericParameters(); if (gps.Count == 0) return Array.Empty<RoType>(); RoType[] genericParameters = new RoType[gps.Count]; foreach (GenericParameterHandle h in gps) { RoType gp = h.ResolveGenericParameter(module); genericParameters[gp.GenericParameterPosition] = gp; } return genericParameters; } private RoType[]? _lazyGenericParameters; protected internal sealed override RoType ComputeEnumUnderlyingType() { // // This performs the functional equivalent of the base Type GetEnumUnderlyingType without going through all the BindingFlag lookup overhead. // if (!IsEnum) throw new ArgumentException(SR.Arg_MustBeEnum); MetadataReader reader = Reader; TypeContext typeContext = Instantiation.ToTypeContext(); RoType? underlyingType = null; foreach (FieldDefinitionHandle handle in TypeDefinition.GetFields()) { FieldDefinition fd = handle.GetFieldDefinition(reader); if ((fd.Attributes & FieldAttributes.Static) != 0) continue; if (underlyingType != null) throw new ArgumentException(SR.Argument_InvalidEnum); underlyingType = fd.DecodeSignature(GetEcmaModule(), typeContext); } if (underlyingType == null) throw new ArgumentException(SR.Argument_InvalidEnum); return underlyingType; } protected sealed override void GetPackSizeAndSize(out int packSize, out int size) { TypeLayout layout = TypeDefinition.GetLayout(); packSize = layout.PackingSize; size = layout.Size; } internal sealed override bool IsTypeNameEqual(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name) { MetadataReader reader = Reader; TypeDefinition td = TypeDefinition; return td.Name.Equals(name, reader) && td.Namespace.Equals(ns, reader); } private new MetadataLoadContext Loader => _module.Loader; private MetadataReader Reader => GetEcmaModule().Reader; private ref readonly TypeDefinition TypeDefinition { get { Loader.DisposeCheck(); return ref _neverAccessThisExceptThroughTypeDefinitionProperty; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] // Block from debugger watch windows so they don't AV the debugged process. private readonly TypeDefinition _neverAccessThisExceptThroughTypeDefinitionProperty; } }