< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 1372
Coverable lines: 1372
Total lines: 2460
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 460
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
File 1: .ctor(...)100%110%
File 1: .ctor(...)100%110%
File 1: .ctor(...)100%110%
File 1: .ctor(...)0%16160%
File 1: ReadMetadataHeader(...)0%660%
File 1: GetMetadataKind(...)0%660%
File 1: ReadStreamHeaders(...)0%880%
File 1: InitializeStreamReaders(...)0%44440%
File 1: ReadMetadataTableHeader(...)0%10100%
File 1: ReadMetadataTableRowCounts(...)0%880%
File 1: ReadStandalonePortablePdbStream(...)0%880%
File 1: GetReferenceSize(...)0%440%
File 1: InitializeTableReaders(...)0%20200%
File 1: CombineRowCounts(...)0%440%
File 1: ComputeCodedTokenSize(...)0%10100%
File 1: IsDeclaredSorted(...)100%110%
File 1: GetFieldRange(...)0%660%
File 1: GetMethodRange(...)0%660%
File 1: GetEventRange(...)0%660%
File 1: GetPropertyRange(...)0%660%
File 1: GetParameterRange(...)0%660%
File 1: GetLocalVariableRange(...)0%440%
File 1: GetLocalConstantRange(...)0%440%
File 1: GetAssemblyDefinition()0%220%
File 1: GetString(...)100%110%
File 1: GetString(...)0%220%
File 1: GetBlobBytes(...)100%110%
File 1: GetBlobContent(...)100%110%
File 1: GetBlobReader(...)100%110%
File 1: GetBlobReader(...)100%110%
File 1: GetUserString(...)100%110%
File 1: GetGuid(...)100%110%
File 1: GetModuleDefinition()0%220%
File 1: GetAssemblyReference(...)100%110%
File 1: GetTypeDefinition(...)100%110%
File 1: GetNamespaceDefinitionRoot()100%110%
File 1: GetNamespaceDefinition(...)100%110%
File 1: GetTypeDefTreatmentAndRowId(...)0%220%
File 1: GetTypeReference(...)100%110%
File 1: GetTypeRefTreatmentAndRowId(...)0%220%
File 1: GetExportedType(...)100%110%
File 1: GetCustomAttributes(...)100%110%
File 1: GetCustomAttribute(...)100%110%
File 1: GetCustomAttributeTreatmentAndRowId(...)0%220%
File 1: GetDeclarativeSecurityAttribute(...)100%110%
File 1: GetConstant(...)100%110%
File 1: GetMethodDefinition(...)100%110%
File 1: GetMethodDefTreatmentAndRowId(...)0%220%
File 1: GetFieldDefinition(...)100%110%
File 1: GetFieldDefTreatmentAndRowId(...)0%220%
File 1: GetPropertyDefinition(...)100%110%
File 1: GetEventDefinition(...)100%110%
File 1: GetMethodImplementation(...)100%110%
File 1: GetMemberReference(...)100%110%
File 1: GetMemberRefTreatmentAndRowId(...)0%220%
File 1: GetMethodSpecification(...)100%110%
File 1: GetParameter(...)100%110%
File 1: GetGenericParameter(...)100%110%
File 1: GetGenericParameterConstraint(...)100%110%
File 1: GetManifestResource(...)100%110%
File 1: GetAssemblyFile(...)100%110%
File 1: GetStandaloneSignature(...)100%110%
File 1: GetTypeSpecification(...)100%110%
File 1: GetModuleReference(...)100%110%
File 1: GetInterfaceImplementation(...)100%110%
File 1: GetDeclaringType(...)0%220%
File 1: GetDeclaringType(...)0%220%
File 1: GetDeclaringType(...)0%220%
File 1: GetDeclaringType(...)0%220%
File 1: GetString(...)100%110%
File 1: GetDocument(...)100%110%
File 1: GetMethodDebugInformation(...)100%110%
File 1: GetMethodDebugInformation(...)100%110%
File 1: GetLocalScope(...)100%110%
File 1: GetLocalVariable(...)100%110%
File 1: GetLocalConstant(...)100%110%
File 1: GetImportScope(...)100%110%
File 1: GetCustomDebugInformation(...)100%110%
File 1: GetCustomDebugInformation(...)100%110%
File 1: GetLocalScopes(...)100%110%
File 1: GetLocalScopes(...)100%110%
File 1: InitializeNestedTypesMap()0%880%
File 1: GetNestedTypes(...)0%440%
File 2: GetAssemblyName(...)0%660%
File 2: GetAssemblyNameInfo(...)0%440%
File 2: GetAssemblyName(...)0%12120%
File 2: GetAssemblyNameFlags(...)0%880%
File 2: GetContentTypeFromAssemblyFlags(...)100%110%
File 3: .cctor()100%110%
File 3: .ctor(...)100%110%
File 3: GetWellKnownTypeDefinitionTreatment(...)0%660%
File 3: GetProjectionIndexForTypeReference(...)0%440%
File 3: GetProjectedAssemblyRef(...)0%440%
File 3: GetProjectedName(...)0%440%
File 3: GetProjectedNamespace(...)0%440%
File 3: GetProjectedSignatureTreatment(...)0%440%
File 3: InitializeProjectedTypes()0%880%
File 3: AssertSorted(...)0%220%
File 3: GetProjectedTypeNames()100%110%
File 3: TreatmentAndRowId(...)100%110%
File 3: CalculateTypeDefTreatmentAndRowId(...)0%26260%
File 3: IsClrImplementationType(...)0%220%
File 3: CalculateTypeRefTreatmentAndRowId(...)0%220%
File 3: GetSpecialTypeRefTreatment(...)0%660%
File 3: IsSystemAttribute(...)0%220%
File 3: NeedsWinRTPrefix(...)0%12120%
File 3: CalculateMethodDefTreatmentAndRowId(...)0%38380%
File 3: GetMethodTreatmentFromCustomAttributes(...)0%12120%
File 3: CalculateFieldDefTreatmentAndRowId(...)0%10100%
File 3: CalculateMemberRefTreatmentAndRowId(...)0%220%
File 3: ImplementsRedirectedInterface(...)0%12120%
File 3: FindMscorlibAssemblyRefNoProjection()0%440%
File 3: CalculateCustomAttributeValueTreatment(...)0%10100%
File 3: IsWindowsAttributeUsageAttribute(...)0%880%
File 3: HasAttribute(...)0%880%
File 3: GetAttributeTypeNameRaw(...)0%12120%
File 3: GetAttributeTypeRaw(...)0%880%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Generic;
 5using System.Collections.Immutable;
 6using System.Diagnostics;
 7using System.Reflection.Internal;
 8using System.Reflection.Metadata.Ecma335;
 9using System.Runtime.InteropServices;
 10using System.Text;
 11
 12namespace System.Reflection.Metadata
 13{
 14    /// <summary>
 15    /// Reads metadata as defined byte the ECMA 335 CLI specification.
 16    /// </summary>
 17    public sealed partial class MetadataReader
 18    {
 19        internal readonly NamespaceCache NamespaceCache;
 20        internal readonly MemoryBlock Block;
 21
 22        // A row id of "mscorlib" AssemblyRef in a WinMD file (each WinMD file must have such a reference).
 23        internal readonly int WinMDMscorlibRef;
 24
 25        // Keeps the underlying memory alive.
 26        private readonly object? _memoryOwnerObj;
 27
 28        private readonly MetadataReaderOptions _options;
 29        private Dictionary<TypeDefinitionHandle, ImmutableArray<TypeDefinitionHandle>>? _lazyNestedTypesMap;
 30
 31        #region Constructors
 32
 33        /// <summary>
 34        /// Creates a metadata reader from the metadata stored at the given memory location.
 35        /// </summary>
 36        /// <remarks>
 37        /// The memory is owned by the caller and it must be kept memory alive and unmodified throughout the lifetime of
 38        /// </remarks>
 39        public unsafe MetadataReader(byte* metadata, int length)
 040            : this(metadata, length, MetadataReaderOptions.Default, utf8Decoder: null, memoryOwner: null)
 041        {
 042        }
 43
 44        /// <summary>
 45        /// Creates a metadata reader from the metadata stored at the given memory location.
 46        /// </summary>
 47        /// <remarks>
 48        /// The memory is owned by the caller and it must be kept memory alive and unmodified throughout the lifetime of
 49        /// Use <see cref="PEReaderExtensions.GetMetadataReader(PortableExecutable.PEReader, MetadataReaderOptions)"/> t
 50        /// metadata from a PE image.
 51        /// </remarks>
 52        public unsafe MetadataReader(byte* metadata, int length, MetadataReaderOptions options)
 053            : this(metadata, length, options, utf8Decoder: null, memoryOwner: null)
 054        {
 055        }
 56
 57        /// <summary>
 58        /// Creates a metadata reader from the metadata stored at the given memory location.
 59        /// </summary>
 60        /// <remarks>
 61        /// The memory is owned by the caller and it must be kept memory alive and unmodified throughout the lifetime of
 62        /// Use <see cref="PEReaderExtensions.GetMetadataReader(PortableExecutable.PEReader, MetadataReaderOptions, Meta
 63        /// metadata from a PE image.
 64        /// </remarks>
 65        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is not positive.</exception>
 66        /// <exception cref="ArgumentNullException"><paramref name="metadata"/> is null.</exception>
 67        /// <exception cref="ArgumentException">The encoding of <paramref name="utf8Decoder"/> is not <see cref="UTF8Enc
 68        /// <exception cref="PlatformNotSupportedException">The current platform is big-endian.</exception>
 69        /// <exception cref="BadImageFormatException">Bad metadata header.</exception>
 70        public unsafe MetadataReader(byte* metadata, int length, MetadataReaderOptions options, MetadataStringDecoder? u
 071            : this(metadata, length, options, utf8Decoder, memoryOwner: null)
 072        {
 073        }
 74
 075        internal unsafe MetadataReader(byte* metadata, int length, MetadataReaderOptions options, MetadataStringDecoder?
 076        {
 77            // Do not throw here when length is 0. We'll throw BadImageFormatException later on, so that the caller does
 78            // worry about the image (stream) being empty and can handle all image errors by catching BadImageFormatExce
 079            if (length < 0)
 080            {
 081                Throw.ArgumentOutOfRange(nameof(length));
 82            }
 83
 084            if (metadata == null)
 085            {
 086                Throw.ArgumentNull(nameof(metadata));
 87            }
 88
 089            utf8Decoder ??= MetadataStringDecoder.DefaultUTF8;
 90
 091            if (!(utf8Decoder.Encoding is UTF8Encoding))
 092            {
 093                Throw.InvalidArgument(SR.MetadataStringDecoderEncodingMustBeUtf8, nameof(utf8Decoder));
 94            }
 95
 096            Block = new MemoryBlock(metadata, length);
 97
 098            _memoryOwnerObj = memoryOwner;
 099            _options = options;
 0100            UTF8Decoder = utf8Decoder;
 101
 0102            var headerReader = new BlobReader(Block);
 0103            ReadMetadataHeader(ref headerReader, out _versionString);
 0104            _metadataKind = GetMetadataKind(_versionString);
 0105            var streamHeaders = ReadStreamHeaders(ref headerReader);
 106
 107            // storage header and stream headers:
 0108            InitializeStreamReaders(Block, streamHeaders, out _metadataStreamKind, out var metadataTableStream, out var 
 109
 110            int[]? externalTableRowCountsOpt;
 0111            if (pdbStream.Length > 0)
 0112            {
 0113                int pdbStreamOffset = (int)(pdbStream.Pointer - metadata);
 0114                ReadStandalonePortablePdbStream(pdbStream, pdbStreamOffset, out _debugMetadataHeader, out externalTableR
 0115            }
 116            else
 0117            {
 0118                externalTableRowCountsOpt = null;
 0119            }
 120
 0121            var tableReader = new BlobReader(metadataTableStream);
 122
 0123            ReadMetadataTableHeader(ref tableReader, out var heapSizes, out var metadataTableRowCounts, out _sortedTable
 124
 0125            InitializeTableReaders(tableReader.GetMemoryBlockAt(0, tableReader.RemainingBytes), heapSizes, metadataTable
 126
 127            // This previously could occur in obfuscated assemblies but a check was added to prevent
 128            // it getting to this point
 0129            Debug.Assert(AssemblyTable.NumberOfRows <= 1);
 130
 131            // Although the specification states that the module table will have exactly one row,
 132            // the native metadata reader would successfully read files containing more than one row.
 133            // Such files exist in the wild and may be produced by obfuscators.
 0134            if (pdbStream.Length == 0 && ModuleTable.NumberOfRows < 1)
 0135            {
 0136                throw new BadImageFormatException(SR.Format(SR.ModuleTableInvalidNumberOfRows, this.ModuleTable.NumberOf
 137            }
 138
 139            //  read
 0140            NamespaceCache = new NamespaceCache(this);
 141
 0142            if (_metadataKind != MetadataKind.Ecma335)
 0143            {
 0144                WinMDMscorlibRef = FindMscorlibAssemblyRefNoProjection();
 0145            }
 0146        }
 147
 148        #endregion
 149
 150        #region Metadata Headers
 151
 152        private readonly string _versionString;
 153        private readonly MetadataKind _metadataKind;
 154        private readonly MetadataStreamKind _metadataStreamKind;
 155        private readonly DebugMetadataHeader? _debugMetadataHeader;
 156
 157        internal StringHeap StringHeap;
 158        internal BlobHeap BlobHeap;
 159        internal GuidHeap GuidHeap;
 160        internal UserStringHeap UserStringHeap;
 161
 162        /// <summary>
 163        /// True if the metadata stream has minimal delta format. Used for EnC.
 164        /// </summary>
 165        /// <remarks>
 166        /// The metadata stream has minimal delta format if "#JTD" stream is present.
 167        /// Minimal delta format uses large size (4B) when encoding table/heap references.
 168        /// The heaps in minimal delta only contain data of the delta,
 169        /// there is no padding at the beginning of the heaps that would align them
 170        /// with the original full metadata heaps.
 171        /// </remarks>
 172        internal bool IsMinimalDelta;
 173
 174        /// <summary>
 175        /// Looks like this function reads beginning of the header described in
 176        /// ECMA-335 24.2.1 Metadata root
 177        /// </summary>
 178        private void ReadMetadataHeader(ref BlobReader memReader, out string versionString)
 0179        {
 0180            if (memReader.RemainingBytes < COR20Constants.MinimumSizeofMetadataHeader)
 0181            {
 0182                throw new BadImageFormatException(SR.MetadataHeaderTooSmall);
 183            }
 184
 0185            uint signature = memReader.ReadUInt32();
 0186            if (signature != COR20Constants.COR20MetadataSignature)
 0187            {
 0188                throw new BadImageFormatException(SR.MetadataSignature);
 189            }
 190
 191            // major version
 0192            memReader.ReadUInt16();
 193
 194            // minor version
 0195            memReader.ReadUInt16();
 196
 197            // reserved:
 0198            memReader.ReadUInt32();
 199
 0200            int versionStringSize = memReader.ReadInt32();
 0201            if (memReader.RemainingBytes < versionStringSize)
 0202            {
 0203                throw new BadImageFormatException(SR.NotEnoughSpaceForVersionString);
 204            }
 205
 0206            versionString = memReader.GetMemoryBlockAt(0, versionStringSize).PeekUtf8NullTerminated(0, null, UTF8Decoder
 0207            memReader.Offset += versionStringSize;
 0208        }
 209
 210        private MetadataKind GetMetadataKind(string versionString)
 0211        {
 212            // Treat metadata as CLI raw metadata if the client doesn't want to see projections.
 0213            if ((_options & MetadataReaderOptions.ApplyWindowsRuntimeProjections) == 0)
 0214            {
 0215                return MetadataKind.Ecma335;
 216            }
 217
 0218            if (!versionString.Contains("WindowsRuntime"))
 0219            {
 0220                return MetadataKind.Ecma335;
 221            }
 0222            else if (versionString.Contains("CLR"))
 0223            {
 0224                return MetadataKind.ManagedWindowsMetadata;
 225            }
 226            else
 0227            {
 0228                return MetadataKind.WindowsMetadata;
 229            }
 0230        }
 231
 232        /// <summary>
 233        /// Reads stream headers described in ECMA-335 24.2.2 Stream header
 234        /// </summary>
 235        private static StreamHeader[] ReadStreamHeaders(ref BlobReader memReader)
 0236        {
 237            // storage header:
 0238            memReader.ReadUInt16();
 0239            int streamCount = memReader.ReadInt16();
 240
 0241            var streamHeaders = new StreamHeader[streamCount];
 0242            for (int i = 0; i < streamHeaders.Length; i++)
 0243            {
 0244                if (memReader.RemainingBytes < COR20Constants.MinimumSizeofStreamHeader)
 0245                {
 0246                    throw new BadImageFormatException(SR.StreamHeaderTooSmall);
 247                }
 248
 0249                streamHeaders[i].Offset = memReader.ReadUInt32();
 0250                streamHeaders[i].Size = memReader.ReadInt32();
 0251                streamHeaders[i].Name = memReader.ReadUtf8NullTerminated();
 0252                bool aligned = memReader.TryAlign(4);
 253
 0254                if (!aligned || memReader.RemainingBytes == 0)
 0255                {
 0256                    throw new BadImageFormatException(SR.NotEnoughSpaceForStreamHeaderName);
 257                }
 0258            }
 259
 0260            return streamHeaders;
 0261        }
 262
 263        private void InitializeStreamReaders(
 264            in MemoryBlock metadataRoot,
 265            StreamHeader[] streamHeaders,
 266            out MetadataStreamKind metadataStreamKind,
 267            out MemoryBlock metadataTableStream,
 268            out MemoryBlock standalonePdbStream)
 0269        {
 0270            metadataTableStream = default;
 0271            standalonePdbStream = default;
 0272            metadataStreamKind = MetadataStreamKind.Illegal;
 273
 0274            foreach (StreamHeader streamHeader in streamHeaders)
 0275            {
 0276                switch (streamHeader.Name)
 277                {
 278                    case COR20Constants.StringStreamName:
 0279                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0280                        {
 0281                            throw new BadImageFormatException(SR.NotEnoughSpaceForStringStream);
 282                        }
 283
 0284                        this.StringHeap = new StringHeap(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamH
 0285                        break;
 286
 287                    case COR20Constants.BlobStreamName:
 0288                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0289                        {
 0290                            throw new BadImageFormatException(SR.NotEnoughSpaceForBlobStream);
 291                        }
 292
 0293                        this.BlobHeap = new BlobHeap(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeade
 0294                        break;
 295
 296                    case COR20Constants.GUIDStreamName:
 0297                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0298                        {
 0299                            throw new BadImageFormatException(SR.NotEnoughSpaceForGUIDStream);
 300                        }
 301
 0302                        this.GuidHeap = new GuidHeap(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeade
 0303                        break;
 304
 305                    case COR20Constants.UserStringStreamName:
 0306                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0307                        {
 0308                            throw new BadImageFormatException(SR.NotEnoughSpaceForBlobStream);
 309                        }
 310
 0311                        this.UserStringHeap = new UserStringHeap(metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset,
 0312                        break;
 313
 314                    case COR20Constants.CompressedMetadataTableStreamName:
 0315                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0316                        {
 0317                            throw new BadImageFormatException(SR.NotEnoughSpaceForMetadataStream);
 318                        }
 319
 0320                        metadataStreamKind = MetadataStreamKind.Compressed;
 0321                        metadataTableStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size)
 0322                        break;
 323
 324                    case COR20Constants.UncompressedMetadataTableStreamName:
 0325                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0326                        {
 0327                            throw new BadImageFormatException(SR.NotEnoughSpaceForMetadataStream);
 328                        }
 329
 0330                        metadataStreamKind = MetadataStreamKind.Uncompressed;
 0331                        metadataTableStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size)
 0332                        break;
 333
 334                    case COR20Constants.MinimalDeltaMetadataTableStreamName:
 0335                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0336                        {
 0337                            throw new BadImageFormatException(SR.NotEnoughSpaceForMetadataStream);
 338                        }
 339
 340                        // the content of the stream is ignored
 0341                        this.IsMinimalDelta = true;
 0342                        break;
 343
 344                    case COR20Constants.StandalonePdbStreamName:
 0345                        if (metadataRoot.Length < streamHeader.Offset + streamHeader.Size)
 0346                        {
 0347                            throw new BadImageFormatException(SR.NotEnoughSpaceForMetadataStream);
 348                        }
 349
 0350                        standalonePdbStream = metadataRoot.GetMemoryBlockAt((int)streamHeader.Offset, streamHeader.Size)
 0351                        break;
 352
 353                    default:
 354                        // Skip unknown streams. Some obfuscators insert invalid streams.
 0355                        continue;
 356                }
 0357            }
 358
 0359            if (IsMinimalDelta && metadataStreamKind != MetadataStreamKind.Uncompressed)
 0360            {
 0361                throw new BadImageFormatException(SR.InvalidMetadataStreamFormat);
 362            }
 0363        }
 364
 365        #endregion
 366
 367        #region Tables and Heaps
 368
 369        private readonly TableMask _sortedTables;
 370
 371        /// <summary>
 372        /// A row count for each possible table. May be indexed by <see cref="TableIndex"/>.
 373        /// </summary>
 0374        internal int[] TableRowCounts = null!;
 375
 376        internal ModuleTableReader ModuleTable;
 377        internal TypeRefTableReader TypeRefTable;
 378        internal TypeDefTableReader TypeDefTable;
 379        internal FieldPtrTableReader FieldPtrTable;
 380        internal FieldTableReader FieldTable;
 381        internal MethodPtrTableReader MethodPtrTable;
 382        internal MethodTableReader MethodDefTable;
 383        internal ParamPtrTableReader ParamPtrTable;
 384        internal ParamTableReader ParamTable;
 385        internal InterfaceImplTableReader InterfaceImplTable;
 386        internal MemberRefTableReader MemberRefTable;
 387        internal ConstantTableReader ConstantTable;
 388        internal CustomAttributeTableReader CustomAttributeTable;
 389        internal FieldMarshalTableReader FieldMarshalTable;
 390        internal DeclSecurityTableReader DeclSecurityTable;
 391        internal ClassLayoutTableReader ClassLayoutTable;
 392        internal FieldLayoutTableReader FieldLayoutTable;
 393        internal StandAloneSigTableReader StandAloneSigTable;
 394        internal EventMapTableReader EventMapTable;
 395        internal EventPtrTableReader EventPtrTable;
 396        internal EventTableReader EventTable;
 397        internal PropertyMapTableReader PropertyMapTable;
 398        internal PropertyPtrTableReader PropertyPtrTable;
 399        internal PropertyTableReader PropertyTable;
 400        internal MethodSemanticsTableReader MethodSemanticsTable;
 401        internal MethodImplTableReader MethodImplTable;
 402        internal ModuleRefTableReader ModuleRefTable;
 403        internal TypeSpecTableReader TypeSpecTable;
 404        internal ImplMapTableReader ImplMapTable;
 405        internal FieldRVATableReader FieldRvaTable;
 406        internal EnCLogTableReader EncLogTable;
 407        internal EnCMapTableReader EncMapTable;
 408        internal AssemblyTableReader AssemblyTable;
 409        internal AssemblyProcessorTableReader AssemblyProcessorTable;              // unused
 410        internal AssemblyOSTableReader AssemblyOSTable;                            // unused
 411        internal AssemblyRefTableReader AssemblyRefTable;
 412        internal AssemblyRefProcessorTableReader AssemblyRefProcessorTable;        // unused
 413        internal AssemblyRefOSTableReader AssemblyRefOSTable;                      // unused
 414        internal FileTableReader FileTable;
 415        internal ExportedTypeTableReader ExportedTypeTable;
 416        internal ManifestResourceTableReader ManifestResourceTable;
 417        internal NestedClassTableReader NestedClassTable;
 418        internal GenericParamTableReader GenericParamTable;
 419        internal MethodSpecTableReader MethodSpecTable;
 420        internal GenericParamConstraintTableReader GenericParamConstraintTable;
 421
 422        // debug tables
 423        internal DocumentTableReader DocumentTable;
 424        internal MethodDebugInformationTableReader MethodDebugInformationTable;
 425        internal LocalScopeTableReader LocalScopeTable;
 426        internal LocalVariableTableReader LocalVariableTable;
 427        internal LocalConstantTableReader LocalConstantTable;
 428        internal ImportScopeTableReader ImportScopeTable;
 429        internal StateMachineMethodTableReader StateMachineMethodTable;
 430        internal CustomDebugInformationTableReader CustomDebugInformationTable;
 431
 432        private void ReadMetadataTableHeader(ref BlobReader reader, out HeapSizes heapSizes, out int[] metadataTableRowC
 0433        {
 0434            if (reader.RemainingBytes < MetadataStreamConstants.SizeOfMetadataTableHeader)
 0435            {
 0436                throw new BadImageFormatException(SR.MetadataTableHeaderTooSmall);
 437            }
 438
 439            // reserved (shall be ignored):
 0440            reader.ReadUInt32();
 441
 442            // major version (shall be ignored):
 0443            reader.ReadByte();
 444
 445            // minor version (shall be ignored):
 0446            reader.ReadByte();
 447
 448            // heap sizes:
 0449            heapSizes = (HeapSizes)reader.ReadByte();
 450
 451            // reserved (shall be ignored):
 0452            reader.ReadByte();
 453
 0454            ulong presentTables = reader.ReadUInt64();
 0455            sortedTables = (TableMask)reader.ReadUInt64();
 456
 457            // According to ECMA-335, MajorVersion and MinorVersion have fixed values and,
 458            // based on recommendation in 24.1 Fixed fields: When writing these fields it
 459            // is best that they be set to the value indicated, on reading they should be ignored.
 460            // We will not be checking version values. We will continue checking that the set of
 461            // present tables is within the set we understand.
 462
 0463            ulong validTables = (ulong)(TableMask.TypeSystemTables | TableMask.DebugTables);
 464
 0465            if ((presentTables & ~validTables) != 0)
 0466            {
 0467                throw new BadImageFormatException(SR.Format(SR.UnknownTables, presentTables));
 468            }
 469
 0470            if (_metadataStreamKind == MetadataStreamKind.Compressed)
 0471            {
 472                // In general Ptr tables and EnC tables are not allowed in a compressed stream.
 473                // However when asked for a snapshot of the current metadata after an EnC change has been applied
 474                // the CLR includes the EnCLog table into the snapshot. We need to be able to read the image,
 475                // so we'll allow the table here but pretend it's empty later.
 0476                if ((presentTables & (ulong)(TableMask.PtrTables | TableMask.EnCMap)) != 0)
 0477                {
 0478                    throw new BadImageFormatException(SR.IllegalTablesInCompressedMetadataStream);
 479                }
 0480            }
 481
 0482            metadataTableRowCounts = ReadMetadataTableRowCounts(ref reader, presentTables);
 483
 0484            if ((heapSizes & HeapSizes.ExtraData) == HeapSizes.ExtraData)
 0485            {
 486                // Skip "extra data" used by some obfuscators. Although it is not mentioned in the CLI spec,
 487                // it is honored by the native metadata reader.
 0488                reader.ReadUInt32();
 0489            }
 0490        }
 491
 492        private static int[] ReadMetadataTableRowCounts(ref BlobReader memReader, ulong presentTableMask)
 0493        {
 0494            ulong currentTableBit = 1;
 495
 0496            var rowCounts = new int[MetadataTokens.TableCount];
 0497            for (int i = 0; i < rowCounts.Length; i++)
 0498            {
 0499                if ((presentTableMask & currentTableBit) != 0)
 0500                {
 0501                    if (memReader.RemainingBytes < sizeof(uint))
 0502                    {
 0503                        throw new BadImageFormatException(SR.TableRowCountSpaceTooSmall);
 504                    }
 505
 0506                    uint rowCount = memReader.ReadUInt32();
 0507                    if (rowCount > TokenTypeIds.RIDMask)
 0508                    {
 0509                        throw new BadImageFormatException(SR.Format(SR.InvalidRowCount, rowCount));
 510                    }
 511
 0512                    rowCounts[i] = (int)rowCount;
 0513                }
 514
 0515                currentTableBit <<= 1;
 0516            }
 517
 0518            return rowCounts;
 0519        }
 520
 521        // internal for testing
 522        internal static void ReadStandalonePortablePdbStream(MemoryBlock pdbStreamBlock, int pdbStreamOffset, out DebugM
 0523        {
 0524            var reader = new BlobReader(pdbStreamBlock);
 525
 526            const int PdbIdSize = 20;
 0527            byte[]? pdbId = reader.ReadBytes(PdbIdSize);
 528
 529            // ECMA-335 15.4.1.2:
 530            // The entry point to an application shall be static.
 531            // This entry point method can be a global method or it can appear inside a type.
 532            // The entry point method shall either accept no arguments or a vector of strings.
 533            // The return type of the entry point method shall be void, int32, or unsigned int32.
 534            // The entry point method cannot be defined in a generic class.
 0535            uint entryPointToken = reader.ReadUInt32();
 0536            int entryPointRowId = (int)(entryPointToken & TokenTypeIds.RIDMask);
 0537            if (entryPointToken != 0 && ((entryPointToken & TokenTypeIds.TypeMask) != TokenTypeIds.MethodDef || entryPoi
 0538            {
 0539                throw new BadImageFormatException(SR.Format(SR.InvalidEntryPointToken, entryPointToken));
 540            }
 541
 0542            ulong externalTableMask = reader.ReadUInt64();
 543
 544            // EnC & Ptr tables can't be referenced from standalone PDB metadata:
 545            const ulong validTables = (ulong)TableMask.ValidPortablePdbExternalTables;
 546
 0547            if ((externalTableMask & ~validTables) != 0)
 0548            {
 0549                throw new BadImageFormatException(SR.Format(SR.UnknownTables, externalTableMask));
 550            }
 551
 0552            externalTableRowCounts = ReadMetadataTableRowCounts(ref reader, externalTableMask);
 553
 0554            debugMetadataHeader = new DebugMetadataHeader(
 0555                ImmutableCollectionsMarshal.AsImmutableArray(pdbId),
 0556                MethodDefinitionHandle.FromRowId(entryPointRowId),
 0557                idStartOffset: pdbStreamOffset);
 0558        }
 559
 560        private const int SmallIndexSize = 2;
 561        private const int LargeIndexSize = 4;
 562
 563        private int GetReferenceSize(int[] rowCounts, TableIndex index)
 0564        {
 0565            return (rowCounts[(int)index] < MetadataStreamConstants.LargeTableRowCount && !IsMinimalDelta) ? SmallIndexS
 0566        }
 567
 568        private void InitializeTableReaders(MemoryBlock metadataTablesMemoryBlock, HeapSizes heapSizes, int[] rowCounts,
 0569        {
 570            // Size of reference tags in each table.
 0571            this.TableRowCounts = rowCounts;
 572
 573            // TODO (https://github.com/dotnet/runtime/issues/14721):
 574            // Shouldn't XxxPtr table be always the same size or smaller than the corresponding Xxx table?
 575
 576            // Compute ref sizes for tables that can have pointer tables
 0577            int fieldRefSizeSorted = GetReferenceSize(rowCounts, TableIndex.FieldPtr) > SmallIndexSize ? LargeIndexSize 
 0578            int methodRefSizeSorted = GetReferenceSize(rowCounts, TableIndex.MethodPtr) > SmallIndexSize ? LargeIndexSiz
 0579            int paramRefSizeSorted = GetReferenceSize(rowCounts, TableIndex.ParamPtr) > SmallIndexSize ? LargeIndexSize 
 0580            int eventRefSizeSorted = GetReferenceSize(rowCounts, TableIndex.EventPtr) > SmallIndexSize ? LargeIndexSize 
 0581            int propertyRefSizeSorted = GetReferenceSize(rowCounts, TableIndex.PropertyPtr) > SmallIndexSize ? LargeInde
 582
 583            // Compute the coded token ref sizes
 0584            int typeDefOrRefRefSize = ComputeCodedTokenSize(TypeDefOrRefTag.LargeRowSize, rowCounts, TypeDefOrRefTag.Tab
 0585            int hasConstantRefSize = ComputeCodedTokenSize(HasConstantTag.LargeRowSize, rowCounts, HasConstantTag.Tables
 0586            int hasCustomAttributeRefSize = ComputeCodedTokenSize(HasCustomAttributeTag.LargeRowSize, rowCounts, HasCust
 0587            int hasFieldMarshalRefSize = ComputeCodedTokenSize(HasFieldMarshalTag.LargeRowSize, rowCounts, HasFieldMarsh
 0588            int hasDeclSecurityRefSize = ComputeCodedTokenSize(HasDeclSecurityTag.LargeRowSize, rowCounts, HasDeclSecuri
 0589            int memberRefParentRefSize = ComputeCodedTokenSize(MemberRefParentTag.LargeRowSize, rowCounts, MemberRefPare
 0590            int hasSemanticsRefSize = ComputeCodedTokenSize(HasSemanticsTag.LargeRowSize, rowCounts, HasSemanticsTag.Tab
 0591            int methodDefOrRefRefSize = ComputeCodedTokenSize(MethodDefOrRefTag.LargeRowSize, rowCounts, MethodDefOrRefT
 0592            int memberForwardedRefSize = ComputeCodedTokenSize(MemberForwardedTag.LargeRowSize, rowCounts, MemberForward
 0593            int implementationRefSize = ComputeCodedTokenSize(ImplementationTag.LargeRowSize, rowCounts, ImplementationT
 0594            int customAttributeTypeRefSize = ComputeCodedTokenSize(CustomAttributeTypeTag.LargeRowSize, rowCounts, Custo
 0595            int resolutionScopeRefSize = ComputeCodedTokenSize(ResolutionScopeTag.LargeRowSize, rowCounts, ResolutionSco
 0596            int typeOrMethodDefRefSize = ComputeCodedTokenSize(TypeOrMethodDefTag.LargeRowSize, rowCounts, TypeOrMethodD
 597
 598            // Compute HeapRef Sizes
 0599            int stringHeapRefSize = (heapSizes & HeapSizes.StringHeapLarge) == HeapSizes.StringHeapLarge ? LargeIndexSiz
 0600            int guidHeapRefSize = (heapSizes & HeapSizes.GuidHeapLarge) == HeapSizes.GuidHeapLarge ? LargeIndexSize : Sm
 0601            int blobHeapRefSize = (heapSizes & HeapSizes.BlobHeapLarge) == HeapSizes.BlobHeapLarge ? LargeIndexSize : Sm
 602
 603            // Populate the Table blocks
 0604            int totalRequiredSize = 0;
 0605            this.ModuleTable = new ModuleTableReader(rowCounts[(int)TableIndex.Module], stringHeapRefSize, guidHeapRefSi
 0606            totalRequiredSize += this.ModuleTable.Block.Length;
 607
 0608            this.TypeRefTable = new TypeRefTableReader(rowCounts[(int)TableIndex.TypeRef], resolutionScopeRefSize, strin
 0609            totalRequiredSize += this.TypeRefTable.Block.Length;
 610
 0611            this.TypeDefTable = new TypeDefTableReader(rowCounts[(int)TableIndex.TypeDef], fieldRefSizeSorted, methodRef
 0612            totalRequiredSize += this.TypeDefTable.Block.Length;
 613
 0614            this.FieldPtrTable = new FieldPtrTableReader(rowCounts[(int)TableIndex.FieldPtr], GetReferenceSize(rowCounts
 0615            totalRequiredSize += this.FieldPtrTable.Block.Length;
 616
 0617            this.FieldTable = new FieldTableReader(rowCounts[(int)TableIndex.Field], stringHeapRefSize, blobHeapRefSize,
 0618            totalRequiredSize += this.FieldTable.Block.Length;
 619
 0620            this.MethodPtrTable = new MethodPtrTableReader(rowCounts[(int)TableIndex.MethodPtr], GetReferenceSize(rowCou
 0621            totalRequiredSize += this.MethodPtrTable.Block.Length;
 622
 0623            this.MethodDefTable = new MethodTableReader(rowCounts[(int)TableIndex.MethodDef], paramRefSizeSorted, string
 0624            totalRequiredSize += this.MethodDefTable.Block.Length;
 625
 0626            this.ParamPtrTable = new ParamPtrTableReader(rowCounts[(int)TableIndex.ParamPtr], GetReferenceSize(rowCounts
 0627            totalRequiredSize += this.ParamPtrTable.Block.Length;
 628
 0629            this.ParamTable = new ParamTableReader(rowCounts[(int)TableIndex.Param], stringHeapRefSize, metadataTablesMe
 0630            totalRequiredSize += this.ParamTable.Block.Length;
 631
 0632            this.InterfaceImplTable = new InterfaceImplTableReader(rowCounts[(int)TableIndex.InterfaceImpl], IsDeclaredS
 0633            totalRequiredSize += this.InterfaceImplTable.Block.Length;
 634
 0635            this.MemberRefTable = new MemberRefTableReader(rowCounts[(int)TableIndex.MemberRef], memberRefParentRefSize,
 0636            totalRequiredSize += this.MemberRefTable.Block.Length;
 637
 0638            this.ConstantTable = new ConstantTableReader(rowCounts[(int)TableIndex.Constant], IsDeclaredSorted(TableMask
 0639            totalRequiredSize += this.ConstantTable.Block.Length;
 640
 0641            this.CustomAttributeTable = new CustomAttributeTableReader(rowCounts[(int)TableIndex.CustomAttribute],
 0642                                                                       IsDeclaredSorted(TableMask.CustomAttribute),
 0643                                                                       hasCustomAttributeRefSize,
 0644                                                                       customAttributeTypeRefSize,
 0645                                                                       blobHeapRefSize,
 0646                                                                       metadataTablesMemoryBlock,
 0647                                                                       totalRequiredSize);
 0648            totalRequiredSize += this.CustomAttributeTable.Block.Length;
 649
 0650            this.FieldMarshalTable = new FieldMarshalTableReader(rowCounts[(int)TableIndex.FieldMarshal], IsDeclaredSort
 0651            totalRequiredSize += this.FieldMarshalTable.Block.Length;
 652
 0653            this.DeclSecurityTable = new DeclSecurityTableReader(rowCounts[(int)TableIndex.DeclSecurity], IsDeclaredSort
 0654            totalRequiredSize += this.DeclSecurityTable.Block.Length;
 655
 0656            this.ClassLayoutTable = new ClassLayoutTableReader(rowCounts[(int)TableIndex.ClassLayout], IsDeclaredSorted(
 0657            totalRequiredSize += this.ClassLayoutTable.Block.Length;
 658
 0659            this.FieldLayoutTable = new FieldLayoutTableReader(rowCounts[(int)TableIndex.FieldLayout], IsDeclaredSorted(
 0660            totalRequiredSize += this.FieldLayoutTable.Block.Length;
 661
 0662            this.StandAloneSigTable = new StandAloneSigTableReader(rowCounts[(int)TableIndex.StandAloneSig], blobHeapRef
 0663            totalRequiredSize += this.StandAloneSigTable.Block.Length;
 664
 0665            this.EventMapTable = new EventMapTableReader(rowCounts[(int)TableIndex.EventMap], GetReferenceSize(rowCounts
 0666            totalRequiredSize += this.EventMapTable.Block.Length;
 667
 0668            this.EventPtrTable = new EventPtrTableReader(rowCounts[(int)TableIndex.EventPtr], GetReferenceSize(rowCounts
 0669            totalRequiredSize += this.EventPtrTable.Block.Length;
 670
 0671            this.EventTable = new EventTableReader(rowCounts[(int)TableIndex.Event], typeDefOrRefRefSize, stringHeapRefS
 0672            totalRequiredSize += this.EventTable.Block.Length;
 673
 0674            this.PropertyMapTable = new PropertyMapTableReader(rowCounts[(int)TableIndex.PropertyMap], GetReferenceSize(
 0675            totalRequiredSize += this.PropertyMapTable.Block.Length;
 676
 0677            this.PropertyPtrTable = new PropertyPtrTableReader(rowCounts[(int)TableIndex.PropertyPtr], GetReferenceSize(
 0678            totalRequiredSize += this.PropertyPtrTable.Block.Length;
 679
 0680            this.PropertyTable = new PropertyTableReader(rowCounts[(int)TableIndex.Property], stringHeapRefSize, blobHea
 0681            totalRequiredSize += this.PropertyTable.Block.Length;
 682
 0683            this.MethodSemanticsTable = new MethodSemanticsTableReader(rowCounts[(int)TableIndex.MethodSemantics], IsDec
 0684            totalRequiredSize += this.MethodSemanticsTable.Block.Length;
 685
 0686            this.MethodImplTable = new MethodImplTableReader(rowCounts[(int)TableIndex.MethodImpl], IsDeclaredSorted(Tab
 0687            totalRequiredSize += this.MethodImplTable.Block.Length;
 688
 0689            this.ModuleRefTable = new ModuleRefTableReader(rowCounts[(int)TableIndex.ModuleRef], stringHeapRefSize, meta
 0690            totalRequiredSize += this.ModuleRefTable.Block.Length;
 691
 0692            this.TypeSpecTable = new TypeSpecTableReader(rowCounts[(int)TableIndex.TypeSpec], blobHeapRefSize, metadataT
 0693            totalRequiredSize += this.TypeSpecTable.Block.Length;
 694
 0695            this.ImplMapTable = new ImplMapTableReader(rowCounts[(int)TableIndex.ImplMap], IsDeclaredSorted(TableMask.Im
 0696            totalRequiredSize += this.ImplMapTable.Block.Length;
 697
 0698            this.FieldRvaTable = new FieldRVATableReader(rowCounts[(int)TableIndex.FieldRva], IsDeclaredSorted(TableMask
 0699            totalRequiredSize += this.FieldRvaTable.Block.Length;
 700
 0701            this.EncLogTable = new EnCLogTableReader(rowCounts[(int)TableIndex.EncLog], metadataTablesMemoryBlock, total
 0702            totalRequiredSize += this.EncLogTable.Block.Length;
 703
 0704            this.EncMapTable = new EnCMapTableReader(rowCounts[(int)TableIndex.EncMap], metadataTablesMemoryBlock, total
 0705            totalRequiredSize += this.EncMapTable.Block.Length;
 706
 0707            this.AssemblyTable = new AssemblyTableReader(rowCounts[(int)TableIndex.Assembly], stringHeapRefSize, blobHea
 0708            totalRequiredSize += this.AssemblyTable.Block.Length;
 709
 0710            this.AssemblyProcessorTable = new AssemblyProcessorTableReader(rowCounts[(int)TableIndex.AssemblyProcessor],
 0711            totalRequiredSize += this.AssemblyProcessorTable.Block.Length;
 712
 0713            this.AssemblyOSTable = new AssemblyOSTableReader(rowCounts[(int)TableIndex.AssemblyOS], metadataTablesMemory
 0714            totalRequiredSize += this.AssemblyOSTable.Block.Length;
 715
 0716            this.AssemblyRefTable = new AssemblyRefTableReader(rowCounts[(int)TableIndex.AssemblyRef], stringHeapRefSize
 0717            totalRequiredSize += this.AssemblyRefTable.Block.Length;
 718
 0719            this.AssemblyRefProcessorTable = new AssemblyRefProcessorTableReader(rowCounts[(int)TableIndex.AssemblyRefPr
 0720            totalRequiredSize += this.AssemblyRefProcessorTable.Block.Length;
 721
 0722            this.AssemblyRefOSTable = new AssemblyRefOSTableReader(rowCounts[(int)TableIndex.AssemblyRefOS], GetReferenc
 0723            totalRequiredSize += this.AssemblyRefOSTable.Block.Length;
 724
 0725            this.FileTable = new FileTableReader(rowCounts[(int)TableIndex.File], stringHeapRefSize, blobHeapRefSize, me
 0726            totalRequiredSize += this.FileTable.Block.Length;
 727
 0728            this.ExportedTypeTable = new ExportedTypeTableReader(rowCounts[(int)TableIndex.ExportedType], implementation
 0729            totalRequiredSize += this.ExportedTypeTable.Block.Length;
 730
 0731            this.ManifestResourceTable = new ManifestResourceTableReader(rowCounts[(int)TableIndex.ManifestResource], im
 0732            totalRequiredSize += this.ManifestResourceTable.Block.Length;
 733
 0734            this.NestedClassTable = new NestedClassTableReader(rowCounts[(int)TableIndex.NestedClass], IsDeclaredSorted(
 0735            totalRequiredSize += this.NestedClassTable.Block.Length;
 736
 0737            this.GenericParamTable = new GenericParamTableReader(rowCounts[(int)TableIndex.GenericParam], IsDeclaredSort
 0738            totalRequiredSize += this.GenericParamTable.Block.Length;
 739
 0740            this.MethodSpecTable = new MethodSpecTableReader(rowCounts[(int)TableIndex.MethodSpec], methodDefOrRefRefSiz
 0741            totalRequiredSize += this.MethodSpecTable.Block.Length;
 742
 0743            this.GenericParamConstraintTable = new GenericParamConstraintTableReader(rowCounts[(int)TableIndex.GenericPa
 0744            totalRequiredSize += this.GenericParamConstraintTable.Block.Length;
 745
 746            // debug tables:
 747            // Type-system metadata tables may be stored in a separate (external) metadata file.
 748            // We need to use the row counts of the external tables when referencing them.
 749            // Debug tables are local to the current metadata image and type system metadata tables are external and pre
 0750            var combinedRowCounts = (externalRowCountsOpt != null) ? CombineRowCounts(rowCounts, externalRowCountsOpt, f
 751
 0752            int methodRefSizeCombined = GetReferenceSize(combinedRowCounts, TableIndex.MethodDef);
 0753            int hasCustomDebugInformationRefSizeCombined = ComputeCodedTokenSize(HasCustomDebugInformationTag.LargeRowSi
 754
 0755            this.DocumentTable = new DocumentTableReader(rowCounts[(int)TableIndex.Document], guidHeapRefSize, blobHeapR
 0756            totalRequiredSize += this.DocumentTable.Block.Length;
 757
 0758            this.MethodDebugInformationTable = new MethodDebugInformationTableReader(rowCounts[(int)TableIndex.MethodDeb
 0759            totalRequiredSize += this.MethodDebugInformationTable.Block.Length;
 760
 0761            this.LocalScopeTable = new LocalScopeTableReader(rowCounts[(int)TableIndex.LocalScope], IsDeclaredSorted(Tab
 0762            totalRequiredSize += this.LocalScopeTable.Block.Length;
 763
 0764            this.LocalVariableTable = new LocalVariableTableReader(rowCounts[(int)TableIndex.LocalVariable], stringHeapR
 0765            totalRequiredSize += this.LocalVariableTable.Block.Length;
 766
 0767            this.LocalConstantTable = new LocalConstantTableReader(rowCounts[(int)TableIndex.LocalConstant], stringHeapR
 0768            totalRequiredSize += this.LocalConstantTable.Block.Length;
 769
 0770            this.ImportScopeTable = new ImportScopeTableReader(rowCounts[(int)TableIndex.ImportScope], GetReferenceSize(
 0771            totalRequiredSize += this.ImportScopeTable.Block.Length;
 772
 0773            this.StateMachineMethodTable = new StateMachineMethodTableReader(rowCounts[(int)TableIndex.StateMachineMetho
 0774            totalRequiredSize += this.StateMachineMethodTable.Block.Length;
 775
 0776            this.CustomDebugInformationTable = new CustomDebugInformationTableReader(rowCounts[(int)TableIndex.CustomDeb
 0777            totalRequiredSize += this.CustomDebugInformationTable.Block.Length;
 778
 0779            if (totalRequiredSize > metadataTablesMemoryBlock.Length)
 0780            {
 0781                throw new BadImageFormatException(SR.MetadataTablesTooSmall);
 782            }
 0783        }
 784
 785        private static int[] CombineRowCounts(int[] local, int[] external, TableIndex firstLocalTableIndex)
 0786        {
 0787            Debug.Assert(local.Length == external.Length);
 788
 0789            var rowCounts = new int[local.Length];
 0790            for (int i = 0; i < (int)firstLocalTableIndex; i++)
 0791            {
 0792                rowCounts[i] = external[i];
 0793            }
 794
 0795            for (int i = (int)firstLocalTableIndex; i < rowCounts.Length; i++)
 0796            {
 0797                rowCounts[i] = local[i];
 0798            }
 799
 0800            return rowCounts;
 0801        }
 802
 803        private int ComputeCodedTokenSize(int largeRowSize, int[] rowCounts, TableMask tablesReferenced)
 0804        {
 0805            if (IsMinimalDelta)
 0806            {
 0807                return LargeIndexSize;
 808            }
 809
 0810            bool isAllReferencedTablesSmall = true;
 0811            ulong tablesReferencedMask = (ulong)tablesReferenced;
 0812            for (int tableIndex = 0; tableIndex < MetadataTokens.TableCount; tableIndex++)
 0813            {
 0814                if ((tablesReferencedMask & 1) != 0)
 0815                {
 0816                    isAllReferencedTablesSmall = isAllReferencedTablesSmall && (rowCounts[tableIndex] < largeRowSize);
 0817                }
 818
 0819                tablesReferencedMask >>= 1;
 0820            }
 821
 0822            return isAllReferencedTablesSmall ? SmallIndexSize : LargeIndexSize;
 0823        }
 824
 825        private bool IsDeclaredSorted(TableMask index)
 0826        {
 0827            return (_sortedTables & index) != 0;
 0828        }
 829
 830        #endregion
 831
 832        #region Helpers
 833
 0834        internal bool UseFieldPtrTable => FieldPtrTable.NumberOfRows > 0;
 0835        internal bool UseMethodPtrTable => MethodPtrTable.NumberOfRows > 0;
 0836        internal bool UseParamPtrTable => ParamPtrTable.NumberOfRows > 0;
 0837        internal bool UseEventPtrTable => EventPtrTable.NumberOfRows > 0;
 0838        internal bool UsePropertyPtrTable => PropertyPtrTable.NumberOfRows > 0;
 839
 840        internal void GetFieldRange(TypeDefinitionHandle typeDef, out int firstFieldRowId, out int lastFieldRowId)
 0841        {
 0842            int typeDefRowId = typeDef.RowId;
 843
 0844            firstFieldRowId = this.TypeDefTable.GetFieldStart(typeDefRowId);
 0845            if (firstFieldRowId == 0)
 0846            {
 0847                firstFieldRowId = 1;
 0848                lastFieldRowId = 0;
 0849            }
 0850            else if (typeDefRowId == this.TypeDefTable.NumberOfRows)
 0851            {
 0852                lastFieldRowId = (this.UseFieldPtrTable) ? this.FieldPtrTable.NumberOfRows : this.FieldTable.NumberOfRow
 0853            }
 854            else
 0855            {
 0856                lastFieldRowId = this.TypeDefTable.GetFieldStart(typeDefRowId + 1) - 1;
 0857            }
 0858        }
 859
 860        internal void GetMethodRange(TypeDefinitionHandle typeDef, out int firstMethodRowId, out int lastMethodRowId)
 0861        {
 0862            int typeDefRowId = typeDef.RowId;
 0863            firstMethodRowId = this.TypeDefTable.GetMethodStart(typeDefRowId);
 0864            if (firstMethodRowId == 0)
 0865            {
 0866                firstMethodRowId = 1;
 0867                lastMethodRowId = 0;
 0868            }
 0869            else if (typeDefRowId == this.TypeDefTable.NumberOfRows)
 0870            {
 0871                lastMethodRowId = (this.UseMethodPtrTable) ? this.MethodPtrTable.NumberOfRows : this.MethodDefTable.Numb
 0872            }
 873            else
 0874            {
 0875                lastMethodRowId = this.TypeDefTable.GetMethodStart(typeDefRowId + 1) - 1;
 0876            }
 0877        }
 878
 879        internal void GetEventRange(TypeDefinitionHandle typeDef, out int firstEventRowId, out int lastEventRowId)
 0880        {
 0881            int eventMapRowId = this.EventMapTable.FindEventMapRowIdFor(typeDef);
 0882            if (eventMapRowId == 0)
 0883            {
 0884                firstEventRowId = 1;
 0885                lastEventRowId = 0;
 0886                return;
 887            }
 888
 0889            firstEventRowId = this.EventMapTable.GetEventListStartFor(eventMapRowId);
 0890            if (eventMapRowId == this.EventMapTable.NumberOfRows)
 0891            {
 0892                lastEventRowId = this.UseEventPtrTable ? this.EventPtrTable.NumberOfRows : this.EventTable.NumberOfRows;
 0893            }
 894            else
 0895            {
 0896                lastEventRowId = this.EventMapTable.GetEventListStartFor(eventMapRowId + 1) - 1;
 0897            }
 0898        }
 899
 900        internal void GetPropertyRange(TypeDefinitionHandle typeDef, out int firstPropertyRowId, out int lastPropertyRow
 0901        {
 0902            int propertyMapRowId = this.PropertyMapTable.FindPropertyMapRowIdFor(typeDef);
 0903            if (propertyMapRowId == 0)
 0904            {
 0905                firstPropertyRowId = 1;
 0906                lastPropertyRowId = 0;
 0907                return;
 908            }
 909
 0910            firstPropertyRowId = this.PropertyMapTable.GetPropertyListStartFor(propertyMapRowId);
 0911            if (propertyMapRowId == this.PropertyMapTable.NumberOfRows)
 0912            {
 0913                lastPropertyRowId = (this.UsePropertyPtrTable) ? this.PropertyPtrTable.NumberOfRows : this.PropertyTable
 0914            }
 915            else
 0916            {
 0917                lastPropertyRowId = this.PropertyMapTable.GetPropertyListStartFor(propertyMapRowId + 1) - 1;
 0918            }
 0919        }
 920
 921        internal void GetParameterRange(MethodDefinitionHandle methodDef, out int firstParamRowId, out int lastParamRowI
 0922        {
 0923            int rid = methodDef.RowId;
 924
 0925            firstParamRowId = this.MethodDefTable.GetParamStart(rid);
 0926            if (firstParamRowId == 0)
 0927            {
 0928                firstParamRowId = 1;
 0929                lastParamRowId = 0;
 0930            }
 0931            else if (rid == this.MethodDefTable.NumberOfRows)
 0932            {
 0933                lastParamRowId = (this.UseParamPtrTable ? this.ParamPtrTable.NumberOfRows : this.ParamTable.NumberOfRows
 0934            }
 935            else
 0936            {
 0937                lastParamRowId = this.MethodDefTable.GetParamStart(rid + 1) - 1;
 0938            }
 0939        }
 940
 941        internal void GetLocalVariableRange(LocalScopeHandle scope, out int firstVariableRowId, out int lastVariableRowI
 0942        {
 0943            int scopeRowId = scope.RowId;
 944
 0945            firstVariableRowId = this.LocalScopeTable.GetVariableStart(scopeRowId);
 0946            if (firstVariableRowId == 0)
 0947            {
 0948                firstVariableRowId = 1;
 0949                lastVariableRowId = 0;
 0950            }
 0951            else if (scopeRowId == this.LocalScopeTable.NumberOfRows)
 0952            {
 0953                lastVariableRowId = this.LocalVariableTable.NumberOfRows;
 0954            }
 955            else
 0956            {
 0957                lastVariableRowId = this.LocalScopeTable.GetVariableStart(scopeRowId + 1) - 1;
 0958            }
 0959        }
 960
 961        internal void GetLocalConstantRange(LocalScopeHandle scope, out int firstConstantRowId, out int lastConstantRowI
 0962        {
 0963            int scopeRowId = scope.RowId;
 964
 0965            firstConstantRowId = this.LocalScopeTable.GetConstantStart(scopeRowId);
 0966            if (firstConstantRowId == 0)
 0967            {
 0968                firstConstantRowId = 1;
 0969                lastConstantRowId = 0;
 0970            }
 0971            else if (scopeRowId == this.LocalScopeTable.NumberOfRows)
 0972            {
 0973                lastConstantRowId = this.LocalConstantTable.NumberOfRows;
 0974            }
 975            else
 0976            {
 0977                lastConstantRowId = this.LocalScopeTable.GetConstantStart(scopeRowId + 1) - 1;
 0978            }
 0979        }
 980
 981        #endregion
 982
 983        #region Public APIs
 984
 985        /// <summary>
 986        /// Pointer to the underlying data.
 987        /// </summary>
 0988        public unsafe byte* MetadataPointer => Block.Pointer;
 989
 990        /// <summary>
 991        /// Length of the underlying data.
 992        /// </summary>
 0993        public int MetadataLength => Block.Length;
 994
 995        /// <summary>
 996        /// Options passed to the constructor.
 997        /// </summary>
 0998        public MetadataReaderOptions Options => _options;
 999
 1000        /// <summary>
 1001        /// Version string read from metadata header.
 1002        /// </summary>
 01003        public string MetadataVersion => _versionString;
 1004
 1005        /// <summary>
 1006        /// Information decoded from #Pdb stream, or null if the stream is not present.
 1007        /// </summary>
 01008        public DebugMetadataHeader? DebugMetadataHeader => _debugMetadataHeader;
 1009
 1010        /// <summary>
 1011        /// The kind of the metadata (plain ECMA335, WinMD, etc.).
 1012        /// </summary>
 01013        public MetadataKind MetadataKind => _metadataKind;
 1014
 1015        /// <summary>
 1016        /// Comparer used to compare strings stored in metadata.
 1017        /// </summary>
 01018        public MetadataStringComparer StringComparer => new MetadataStringComparer(this);
 1019
 1020        /// <summary>
 1021        /// The decoder used by the reader to produce <see cref="string"/> instances from UTF-8 encoded byte sequences.
 1022        /// </summary>
 01023        public MetadataStringDecoder UTF8Decoder { get; }
 1024
 1025        /// <summary>
 1026        /// Returns true if the metadata represent an assembly.
 1027        /// </summary>
 01028        public bool IsAssembly => AssemblyTable.NumberOfRows == 1;
 1029
 01030        public AssemblyReferenceHandleCollection AssemblyReferences => new AssemblyReferenceHandleCollection(this);
 01031        public TypeDefinitionHandleCollection TypeDefinitions => new TypeDefinitionHandleCollection(TypeDefTable.NumberO
 01032        public TypeReferenceHandleCollection TypeReferences => new TypeReferenceHandleCollection(TypeRefTable.NumberOfRo
 01033        public CustomAttributeHandleCollection CustomAttributes => new CustomAttributeHandleCollection(this);
 01034        public DeclarativeSecurityAttributeHandleCollection DeclarativeSecurityAttributes => new DeclarativeSecurityAttr
 01035        public MemberReferenceHandleCollection MemberReferences => new MemberReferenceHandleCollection(MemberRefTable.Nu
 01036        public ManifestResourceHandleCollection ManifestResources => new ManifestResourceHandleCollection(ManifestResour
 01037        public AssemblyFileHandleCollection AssemblyFiles => new AssemblyFileHandleCollection(FileTable.NumberOfRows);
 01038        public ExportedTypeHandleCollection ExportedTypes => new ExportedTypeHandleCollection(ExportedTypeTable.NumberOf
 01039        public MethodDefinitionHandleCollection MethodDefinitions => new MethodDefinitionHandleCollection(this);
 01040        public FieldDefinitionHandleCollection FieldDefinitions => new FieldDefinitionHandleCollection(this);
 01041        public EventDefinitionHandleCollection EventDefinitions => new EventDefinitionHandleCollection(this);
 01042        public PropertyDefinitionHandleCollection PropertyDefinitions => new PropertyDefinitionHandleCollection(this);
 01043        public DocumentHandleCollection Documents => new DocumentHandleCollection(this);
 01044        public MethodDebugInformationHandleCollection MethodDebugInformation => new MethodDebugInformationHandleCollecti
 01045        public LocalScopeHandleCollection LocalScopes => new LocalScopeHandleCollection(this, 0);
 01046        public LocalVariableHandleCollection LocalVariables => new LocalVariableHandleCollection(this, default(LocalScop
 01047        public LocalConstantHandleCollection LocalConstants => new LocalConstantHandleCollection(this, default(LocalScop
 01048        public ImportScopeCollection ImportScopes => new ImportScopeCollection(this);
 01049        public CustomDebugInformationHandleCollection CustomDebugInformation => new CustomDebugInformationHandleCollecti
 1050
 1051        public AssemblyDefinition GetAssemblyDefinition()
 01052        {
 01053            if (!IsAssembly)
 01054            {
 01055                throw new InvalidOperationException(SR.MetadataImageDoesNotRepresentAnAssembly);
 1056            }
 1057
 01058            return new AssemblyDefinition(this);
 01059        }
 1060
 1061        public string GetString(StringHandle handle)
 01062        {
 01063            return StringHeap.GetString(handle, UTF8Decoder);
 01064        }
 1065
 1066        public string GetString(NamespaceDefinitionHandle handle)
 01067        {
 01068            if (handle.HasFullName)
 01069            {
 01070                return StringHeap.GetString(handle.GetFullName(), UTF8Decoder);
 1071            }
 1072
 01073            return NamespaceCache.GetFullName(handle);
 01074        }
 1075
 1076        public byte[] GetBlobBytes(BlobHandle handle)
 01077        {
 01078            return BlobHeap.GetBytes(handle);
 01079        }
 1080
 1081        public ImmutableArray<byte> GetBlobContent(BlobHandle handle)
 01082        {
 01083            byte[]? bytes = BlobHeap.GetBytes(handle, unique: false);
 01084            return ImmutableCollectionsMarshal.AsImmutableArray(bytes);
 01085        }
 1086
 1087        public BlobReader GetBlobReader(BlobHandle handle)
 01088        {
 01089            return BlobHeap.GetBlobReader(handle);
 01090        }
 1091
 1092        public BlobReader GetBlobReader(StringHandle handle)
 01093        {
 01094            return StringHeap.GetBlobReader(handle);
 01095        }
 1096
 1097        public string GetUserString(UserStringHandle handle)
 01098        {
 01099            return UserStringHeap.GetString(handle);
 01100        }
 1101
 1102        public Guid GetGuid(GuidHandle handle)
 01103        {
 01104            return GuidHeap.GetGuid(handle);
 01105        }
 1106
 1107        public ModuleDefinition GetModuleDefinition()
 01108        {
 01109            if (_debugMetadataHeader != null)
 01110            {
 01111                throw new InvalidOperationException(SR.StandaloneDebugMetadataImageDoesNotContainModuleTable);
 1112            }
 1113
 01114            return new ModuleDefinition(this);
 01115        }
 1116
 1117        public AssemblyReference GetAssemblyReference(AssemblyReferenceHandle handle)
 01118        {
 01119            return new AssemblyReference(this, handle.Value);
 01120        }
 1121
 1122        public TypeDefinition GetTypeDefinition(TypeDefinitionHandle handle)
 01123        {
 1124            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01125            return new TypeDefinition(this, GetTypeDefTreatmentAndRowId(handle));
 01126        }
 1127
 1128        public NamespaceDefinition GetNamespaceDefinitionRoot()
 01129        {
 01130            NamespaceData data = NamespaceCache.GetRootNamespace();
 01131            return new NamespaceDefinition(data);
 01132        }
 1133
 1134        public NamespaceDefinition GetNamespaceDefinition(NamespaceDefinitionHandle handle)
 01135        {
 01136            NamespaceData data = NamespaceCache.GetNamespaceData(handle);
 01137            return new NamespaceDefinition(data);
 01138        }
 1139
 1140        private uint GetTypeDefTreatmentAndRowId(TypeDefinitionHandle handle)
 01141        {
 1142            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01143            if (_metadataKind == MetadataKind.Ecma335)
 01144            {
 01145                return (uint)handle.RowId;
 1146            }
 1147
 01148            return CalculateTypeDefTreatmentAndRowId(handle);
 01149        }
 1150
 1151        public TypeReference GetTypeReference(TypeReferenceHandle handle)
 01152        {
 1153            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01154            return new TypeReference(this, GetTypeRefTreatmentAndRowId(handle));
 01155        }
 1156
 1157        private uint GetTypeRefTreatmentAndRowId(TypeReferenceHandle handle)
 01158        {
 1159            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01160            if (_metadataKind == MetadataKind.Ecma335)
 01161            {
 01162                return (uint)handle.RowId;
 1163            }
 1164
 01165            return CalculateTypeRefTreatmentAndRowId(handle);
 01166        }
 1167
 1168        public ExportedType GetExportedType(ExportedTypeHandle handle)
 01169        {
 01170            return new ExportedType(this, handle.RowId);
 01171        }
 1172
 1173        public CustomAttributeHandleCollection GetCustomAttributes(EntityHandle handle)
 01174        {
 01175            return new CustomAttributeHandleCollection(this, handle);
 01176        }
 1177
 1178        public CustomAttribute GetCustomAttribute(CustomAttributeHandle handle)
 01179        {
 1180            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01181            return new CustomAttribute(this, GetCustomAttributeTreatmentAndRowId(handle));
 01182        }
 1183
 1184        private uint GetCustomAttributeTreatmentAndRowId(CustomAttributeHandle handle)
 01185        {
 1186            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01187            if (_metadataKind == MetadataKind.Ecma335)
 01188            {
 01189                return (uint)handle.RowId;
 1190            }
 1191
 01192            return TreatmentAndRowId((byte)CustomAttributeTreatment.WinMD, handle.RowId);
 01193        }
 1194
 1195        public DeclarativeSecurityAttribute GetDeclarativeSecurityAttribute(DeclarativeSecurityAttributeHandle handle)
 01196        {
 1197            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01198            return new DeclarativeSecurityAttribute(this, handle.RowId);
 01199        }
 1200
 1201        public Constant GetConstant(ConstantHandle handle)
 01202        {
 01203            return new Constant(this, handle.RowId);
 01204        }
 1205
 1206        public MethodDefinition GetMethodDefinition(MethodDefinitionHandle handle)
 01207        {
 1208            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01209            return new MethodDefinition(this, GetMethodDefTreatmentAndRowId(handle));
 01210        }
 1211
 1212        private uint GetMethodDefTreatmentAndRowId(MethodDefinitionHandle handle)
 01213        {
 1214            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01215            if (_metadataKind == MetadataKind.Ecma335)
 01216            {
 01217                return (uint)handle.RowId;
 1218            }
 1219
 01220            return CalculateMethodDefTreatmentAndRowId(handle);
 01221        }
 1222
 1223        public FieldDefinition GetFieldDefinition(FieldDefinitionHandle handle)
 01224        {
 1225            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01226            return new FieldDefinition(this, GetFieldDefTreatmentAndRowId(handle));
 01227        }
 1228
 1229        private uint GetFieldDefTreatmentAndRowId(FieldDefinitionHandle handle)
 01230        {
 1231            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01232            if (_metadataKind == MetadataKind.Ecma335)
 01233            {
 01234                return (uint)handle.RowId;
 1235            }
 1236
 01237            return CalculateFieldDefTreatmentAndRowId(handle);
 01238        }
 1239
 1240        public PropertyDefinition GetPropertyDefinition(PropertyDefinitionHandle handle)
 01241        {
 01242            return new PropertyDefinition(this, handle);
 01243        }
 1244
 1245        public EventDefinition GetEventDefinition(EventDefinitionHandle handle)
 01246        {
 01247            return new EventDefinition(this, handle);
 01248        }
 1249
 1250        public MethodImplementation GetMethodImplementation(MethodImplementationHandle handle)
 01251        {
 01252            return new MethodImplementation(this, handle);
 01253        }
 1254
 1255        public MemberReference GetMemberReference(MemberReferenceHandle handle)
 01256        {
 1257            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01258            return new MemberReference(this, GetMemberRefTreatmentAndRowId(handle));
 01259        }
 1260
 1261        private uint GetMemberRefTreatmentAndRowId(MemberReferenceHandle handle)
 01262        {
 1263            // PERF: This code pattern is JIT friendly and results in very efficient code.
 01264            if (_metadataKind == MetadataKind.Ecma335)
 01265            {
 01266                return (uint)handle.RowId;
 1267            }
 1268
 01269            return CalculateMemberRefTreatmentAndRowId(handle);
 01270        }
 1271
 1272        public MethodSpecification GetMethodSpecification(MethodSpecificationHandle handle)
 01273        {
 01274            return new MethodSpecification(this, handle);
 01275        }
 1276
 1277        public Parameter GetParameter(ParameterHandle handle)
 01278        {
 01279            return new Parameter(this, handle);
 01280        }
 1281
 1282        public GenericParameter GetGenericParameter(GenericParameterHandle handle)
 01283        {
 01284            return new GenericParameter(this, handle);
 01285        }
 1286
 1287        public GenericParameterConstraint GetGenericParameterConstraint(GenericParameterConstraintHandle handle)
 01288        {
 01289            return new GenericParameterConstraint(this, handle);
 01290        }
 1291
 1292        public ManifestResource GetManifestResource(ManifestResourceHandle handle)
 01293        {
 01294            return new ManifestResource(this, handle);
 01295        }
 1296
 1297        public AssemblyFile GetAssemblyFile(AssemblyFileHandle handle)
 01298        {
 01299            return new AssemblyFile(this, handle);
 01300        }
 1301
 1302        public StandaloneSignature GetStandaloneSignature(StandaloneSignatureHandle handle)
 01303        {
 01304            return new StandaloneSignature(this, handle);
 01305        }
 1306
 1307        public TypeSpecification GetTypeSpecification(TypeSpecificationHandle handle)
 01308        {
 01309            return new TypeSpecification(this, handle);
 01310        }
 1311
 1312        public ModuleReference GetModuleReference(ModuleReferenceHandle handle)
 01313        {
 01314            return new ModuleReference(this, handle);
 01315        }
 1316
 1317        public InterfaceImplementation GetInterfaceImplementation(InterfaceImplementationHandle handle)
 01318        {
 01319            return new InterfaceImplementation(this, handle);
 01320        }
 1321
 1322        internal TypeDefinitionHandle GetDeclaringType(MethodDefinitionHandle methodDef)
 01323        {
 1324            int methodRowId;
 01325            if (UseMethodPtrTable)
 01326            {
 01327                methodRowId = MethodPtrTable.GetRowIdForMethodDefRow(methodDef.RowId);
 01328            }
 1329            else
 01330            {
 01331                methodRowId = methodDef.RowId;
 01332            }
 1333
 01334            return TypeDefTable.FindTypeContainingMethod(methodRowId, MethodDefTable.NumberOfRows);
 01335        }
 1336
 1337        internal TypeDefinitionHandle GetDeclaringType(FieldDefinitionHandle fieldDef)
 01338        {
 1339            int fieldRowId;
 01340            if (UseFieldPtrTable)
 01341            {
 01342                fieldRowId = FieldPtrTable.GetRowIdForFieldDefRow(fieldDef.RowId);
 01343            }
 1344            else
 01345            {
 01346                fieldRowId = fieldDef.RowId;
 01347            }
 1348
 01349            return TypeDefTable.FindTypeContainingField(fieldRowId, FieldTable.NumberOfRows);
 01350        }
 1351
 1352        internal TypeDefinitionHandle GetDeclaringType(EventDefinitionHandle eventDef)
 01353        {
 01354            if (UseEventPtrTable)
 01355            {
 01356                eventDef = EventPtrTable.GetEventFor(eventDef.RowId);
 01357            }
 1358
 01359            return EventMapTable.FindTypeContainingEvent(eventDef.RowId, EventTable.NumberOfRows);
 01360        }
 1361
 1362        internal TypeDefinitionHandle GetDeclaringType(PropertyDefinitionHandle propertyDef)
 01363        {
 01364            if (UsePropertyPtrTable)
 01365            {
 01366                propertyDef = PropertyPtrTable.GetPropertyFor(propertyDef.RowId);
 01367            }
 1368
 01369            return PropertyMapTable.FindTypeContainingProperty(propertyDef.RowId, PropertyTable.NumberOfRows);
 01370        }
 1371
 1372        public string GetString(DocumentNameBlobHandle handle)
 01373        {
 01374            return BlobHeap.GetDocumentName(handle);
 01375        }
 1376
 1377        public Document GetDocument(DocumentHandle handle)
 01378        {
 01379            return new Document(this, handle);
 01380        }
 1381
 1382        public MethodDebugInformation GetMethodDebugInformation(MethodDebugInformationHandle handle)
 01383        {
 01384            return new MethodDebugInformation(this, handle);
 01385        }
 1386
 1387        public MethodDebugInformation GetMethodDebugInformation(MethodDefinitionHandle handle)
 01388        {
 01389            return new MethodDebugInformation(this, MethodDebugInformationHandle.FromRowId(handle.RowId));
 01390        }
 1391
 1392        public LocalScope GetLocalScope(LocalScopeHandle handle)
 01393        {
 01394            return new LocalScope(this, handle);
 01395        }
 1396
 1397        public LocalVariable GetLocalVariable(LocalVariableHandle handle)
 01398        {
 01399            return new LocalVariable(this, handle);
 01400        }
 1401
 1402        public LocalConstant GetLocalConstant(LocalConstantHandle handle)
 01403        {
 01404            return new LocalConstant(this, handle);
 01405        }
 1406
 1407        public ImportScope GetImportScope(ImportScopeHandle handle)
 01408        {
 01409            return new ImportScope(this, handle);
 01410        }
 1411
 1412        public CustomDebugInformation GetCustomDebugInformation(CustomDebugInformationHandle handle)
 01413        {
 01414            return new CustomDebugInformation(this, handle);
 01415        }
 1416
 1417        public CustomDebugInformationHandleCollection GetCustomDebugInformation(EntityHandle handle)
 01418        {
 01419            return new CustomDebugInformationHandleCollection(this, handle);
 01420        }
 1421
 1422        public LocalScopeHandleCollection GetLocalScopes(MethodDefinitionHandle handle)
 01423        {
 01424            return new LocalScopeHandleCollection(this, handle.RowId);
 01425        }
 1426
 1427        public LocalScopeHandleCollection GetLocalScopes(MethodDebugInformationHandle handle)
 01428        {
 01429            return new LocalScopeHandleCollection(this, handle.RowId);
 01430        }
 1431
 1432        #endregion
 1433
 1434        #region Nested Types
 1435
 1436        private void InitializeNestedTypesMap()
 01437        {
 01438            var groupedNestedTypes = new Dictionary<TypeDefinitionHandle, ImmutableArray<TypeDefinitionHandle>.Builder>(
 1439
 01440            int numberOfNestedTypes = NestedClassTable.NumberOfRows;
 01441            ImmutableArray<TypeDefinitionHandle>.Builder? builder = null;
 01442            TypeDefinitionHandle previousEnclosingClass = default(TypeDefinitionHandle);
 1443
 01444            for (int i = 1; i <= numberOfNestedTypes; i++)
 01445            {
 01446                TypeDefinitionHandle enclosingClass = NestedClassTable.GetEnclosingClass(i);
 1447
 01448                Debug.Assert(!enclosingClass.IsNil);
 1449
 01450                if (enclosingClass != previousEnclosingClass)
 01451                {
 01452                    if (!groupedNestedTypes.TryGetValue(enclosingClass, out builder))
 01453                    {
 01454                        builder = ImmutableArray.CreateBuilder<TypeDefinitionHandle>();
 01455                        groupedNestedTypes.Add(enclosingClass, builder);
 01456                    }
 1457
 01458                    previousEnclosingClass = enclosingClass;
 01459                }
 1460                else
 01461                {
 01462                    Debug.Assert(builder == groupedNestedTypes[enclosingClass]);
 01463                }
 1464
 01465                builder.Add(NestedClassTable.GetNestedClass(i));
 01466            }
 1467
 01468            var nestedTypesMap = new Dictionary<TypeDefinitionHandle, ImmutableArray<TypeDefinitionHandle>>();
 01469            foreach (var group in groupedNestedTypes)
 01470            {
 01471                nestedTypesMap.Add(group.Key, group.Value.ToImmutable());
 01472            }
 1473
 01474            _lazyNestedTypesMap = nestedTypesMap;
 01475        }
 1476
 1477        /// <summary>
 1478        /// Returns an array of types nested in the specified type.
 1479        /// </summary>
 1480        internal ImmutableArray<TypeDefinitionHandle> GetNestedTypes(TypeDefinitionHandle typeDef)
 01481        {
 01482            if (_lazyNestedTypesMap == null)
 01483            {
 01484                InitializeNestedTypesMap();
 01485                Debug.Assert(_lazyNestedTypesMap != null);
 01486            }
 1487
 1488            ImmutableArray<TypeDefinitionHandle> nestedTypes;
 01489            if (_lazyNestedTypesMap.TryGetValue(typeDef, out nestedTypes))
 01490            {
 01491                return nestedTypes;
 1492            }
 1493
 01494            return ImmutableArray<TypeDefinitionHandle>.Empty;
 01495        }
 1496        #endregion
 1497    }
 1498}
 1499

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.netstandard.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Immutable;
 6using System.IO;
 7using System.IO.MemoryMappedFiles;
 8using System.Reflection.PortableExecutable;
 9using Microsoft.Win32.SafeHandles;
 10
 11namespace System.Reflection.Metadata
 12{
 13    public sealed partial class MetadataReader
 14    {
 15        internal AssemblyName GetAssemblyName(StringHandle nameHandle, Version version, StringHandle cultureHandle, Blob
 016        {
 017            string name = GetString(nameHandle);
 18            // compat: normalize Nil culture name to "" to match original behavior of AssemblyName.GetAssemblyName()
 019            string cultureName = (!cultureHandle.IsNil) ? GetString(cultureHandle) : "";
 020            var hashAlgorithm = (Configuration.Assemblies.AssemblyHashAlgorithm)assemblyHashAlgorithm;
 21            // compat: original native implementation used to guarantee that publicKeyOrToken is never null in this scen
 022            byte[]? publicKeyOrToken = !publicKeyOrTokenHandle.IsNil ? GetBlobBytes(publicKeyOrTokenHandle) : Array.Empt
 23
 024            var assemblyName = new AssemblyName()
 025            {
 026                Name = name,
 027                Version = version,
 028                CultureName = cultureName,
 029#pragma warning disable SYSLIB0037 // AssemblyName.HashAlgorithm is obsolete
 030                HashAlgorithm = hashAlgorithm,
 031#pragma warning restore
 032                Flags = GetAssemblyNameFlags(flags),
 033                ContentType = GetContentTypeFromAssemblyFlags(flags)
 034            };
 35
 036            bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
 037            if (hasPublicKey)
 038            {
 039                assemblyName.SetPublicKey(publicKeyOrToken);
 040            }
 41            else
 042            {
 043                assemblyName.SetPublicKeyToken(publicKeyOrToken);
 044            }
 45
 046            return assemblyName;
 047        }
 48
 49        internal AssemblyNameInfo GetAssemblyNameInfo(StringHandle nameHandle, Version version, StringHandle cultureHand
 050        {
 051            string name = GetString(nameHandle);
 052            string? cultureName = !cultureHandle.IsNil ? GetString(cultureHandle) : null;
 053            ImmutableArray<byte> publicKeyOrToken = !publicKeyOrTokenHandle.IsNil ? GetBlobContent(publicKeyOrTokenHandl
 54
 055            return new AssemblyNameInfo(name, version, cultureName, GetAssemblyNameFlags(flags), publicKeyOrToken);
 056        }
 57
 58        /// <summary>
 59        /// Gets the <see cref="AssemblyName"/> for a given file.
 60        /// </summary>
 61        /// <param name="assemblyFile">The path for the assembly which <see cref="AssemblyName"/> is to be returned.</pa
 62        /// <returns>An <see cref="AssemblyName"/> that represents the given <paramref name="assemblyFile"/>.</returns>
 63        /// <exception cref="ArgumentNullException">If <paramref name="assemblyFile"/> is null.</exception>
 64        /// <exception cref="ArgumentException">If <paramref name="assemblyFile"/> is invalid.</exception>
 65        /// <exception cref="FileNotFoundException">If <paramref name="assemblyFile"/> is not found.</exception>
 66        /// <exception cref="BadImageFormatException">If <paramref name="assemblyFile"/> is not a valid assembly.</excep
 67        public static unsafe AssemblyName GetAssemblyName(string assemblyFile)
 068        {
 069            if (assemblyFile is null)
 070            {
 071                Throw.ArgumentNull(nameof(assemblyFile));
 72            }
 73
 074            FileStream? fileStream = null;
 075            MemoryMappedFile? mappedFile = null;
 076            MemoryMappedViewAccessor? accessor = null;
 077            PEReader? peReader = null;
 78
 79            try
 080            {
 81                try
 082                {
 83                    // Create stream because CreateFromFile(string, ...) uses FileShare.None which is too strict
 084                    fileStream = new FileStream(assemblyFile, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize
 085                    if (fileStream.Length == 0)
 086                    {
 087                        throw new BadImageFormatException(SR.PEImageDoesNotHaveMetadata, assemblyFile);
 88                    }
 89
 090                    mappedFile = MemoryMappedFile.CreateFromFile(
 091                        fileStream, null, fileStream.Length, MemoryMappedFileAccess.Read, HandleInheritability.None, tru
 092                    accessor = mappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);
 93
 094                    SafeMemoryMappedViewHandle? safeBuffer = accessor.SafeMemoryMappedViewHandle;
 095                    peReader = new PEReader((byte*)safeBuffer.DangerousGetHandle(), (int)safeBuffer.ByteLength);
 096                    MetadataReader mdReader = peReader.GetMetadataReader(MetadataReaderOptions.None);
 097                    AssemblyName assemblyName = mdReader.GetAssemblyDefinition().GetAssemblyName();
 098                    return assemblyName;
 99                }
 100                finally
 0101                {
 0102                    peReader?.Dispose();
 0103                    accessor?.Dispose();
 0104                    mappedFile?.Dispose();
 0105                    fileStream?.Dispose();
 0106                }
 107            }
 0108            catch (InvalidOperationException ex)
 0109            {
 0110                throw new BadImageFormatException(ex.Message, assemblyFile, ex);
 111            }
 0112        }
 113
 114        private static AssemblyNameFlags GetAssemblyNameFlags(AssemblyFlags flags)
 0115        {
 0116            AssemblyNameFlags assemblyNameFlags = AssemblyNameFlags.None;
 117
 0118            if ((flags & AssemblyFlags.PublicKey) != 0)
 0119                assemblyNameFlags |= AssemblyNameFlags.PublicKey;
 120
 0121            if ((flags & AssemblyFlags.Retargetable) != 0)
 0122                assemblyNameFlags |= AssemblyNameFlags.Retargetable;
 123
 0124            if ((flags & AssemblyFlags.EnableJitCompileTracking) != 0)
 0125                assemblyNameFlags |= AssemblyNameFlags.EnableJITcompileTracking;
 126
 0127            if ((flags & AssemblyFlags.DisableJitCompileOptimizer) != 0)
 0128                assemblyNameFlags |= AssemblyNameFlags.EnableJITcompileOptimizer;
 129
 0130            return assemblyNameFlags;
 0131        }
 132
 133        private static AssemblyContentType GetContentTypeFromAssemblyFlags(AssemblyFlags flags)
 0134        {
 0135            return (AssemblyContentType)(((int)flags & (int)AssemblyFlags.ContentTypeMask) >> 9);
 0136        }
 137    }
 138}
 139

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.WinMD.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics;
 5using System.Reflection.Metadata.Ecma335;
 6using System.Runtime.CompilerServices;
 7
 8namespace System.Reflection.Metadata
 9{
 10    public partial class MetadataReader
 11    {
 12        internal const string ClrPrefix = "<CLR>";
 13
 014        internal static readonly byte[] WinRTPrefix = "<WinRT>"u8.ToArray();
 15
 16        #region Projection Tables
 17
 18        // Maps names of projected types to projection information for each type.
 19        // Both arrays are of the same length and sorted by the type name.
 20        private static string[]? s_projectedTypeNames;
 21        private static ProjectionInfo[]? s_projectionInfos;
 22
 23        private readonly struct ProjectionInfo
 24        {
 25            public readonly string WinRTNamespace;
 26            public readonly StringHandle.VirtualIndex ClrNamespace;
 27            public readonly StringHandle.VirtualIndex ClrName;
 28            public readonly AssemblyReferenceHandle.VirtualIndex AssemblyRef;
 29            public readonly TypeDefTreatment Treatment;
 30            public readonly TypeRefSignatureTreatment SignatureTreatment;
 31            public readonly bool IsIDisposable;
 32
 33            public ProjectionInfo(
 34                string winRtNamespace,
 35                StringHandle.VirtualIndex clrNamespace,
 36                StringHandle.VirtualIndex clrName,
 37                AssemblyReferenceHandle.VirtualIndex clrAssembly,
 38                TypeDefTreatment treatment = TypeDefTreatment.RedirectedToClrType,
 39                TypeRefSignatureTreatment signatureTreatment = TypeRefSignatureTreatment.None,
 40                bool isIDisposable = false)
 041            {
 042                this.WinRTNamespace = winRtNamespace;
 043                this.ClrNamespace = clrNamespace;
 044                this.ClrName = clrName;
 045                this.AssemblyRef = clrAssembly;
 046                this.Treatment = treatment;
 047                this.SignatureTreatment = signatureTreatment;
 048                this.IsIDisposable = isIDisposable;
 049            }
 50        }
 51
 52        private TypeDefTreatment GetWellKnownTypeDefinitionTreatment(TypeDefinitionHandle typeDef)
 053        {
 054            InitializeProjectedTypes();
 55
 056            StringHandle name = TypeDefTable.GetName(typeDef);
 57
 058            int index = StringHeap.BinarySearchRaw(s_projectedTypeNames!, name);
 059            if (index < 0)
 060            {
 061                return TypeDefTreatment.None;
 62            }
 63
 064            StringHandle namespaceName = TypeDefTable.GetNamespace(typeDef);
 065            if (StringHeap.EqualsRaw(namespaceName, StringHeap.GetVirtualString(s_projectionInfos![index].ClrNamespace))
 066            {
 067                return s_projectionInfos[index].Treatment;
 68            }
 69
 70            // TODO: we can avoid this comparison if info.DotNetNamespace == info.WinRtNamespace
 071            if (StringHeap.EqualsRaw(namespaceName, s_projectionInfos[index].WinRTNamespace))
 072            {
 073                return s_projectionInfos[index].Treatment | TypeDefTreatment.MarkInternalFlag;
 74            }
 75
 076            return TypeDefTreatment.None;
 077        }
 78
 79        private int GetProjectionIndexForTypeReference(TypeReferenceHandle typeRef, out bool isIDisposable)
 080        {
 081            InitializeProjectedTypes();
 82
 083            int index = StringHeap.BinarySearchRaw(s_projectedTypeNames!, TypeRefTable.GetName(typeRef));
 084            if (index >= 0 && StringHeap.EqualsRaw(TypeRefTable.GetNamespace(typeRef), s_projectionInfos![index].WinRTNa
 085            {
 086                isIDisposable = s_projectionInfos[index].IsIDisposable;
 087                return index;
 88            }
 89
 090            isIDisposable = false;
 091            return -1;
 092        }
 93
 94        internal static AssemblyReferenceHandle GetProjectedAssemblyRef(int projectionIndex)
 095        {
 096            Debug.Assert(s_projectionInfos != null && projectionIndex >= 0 && projectionIndex < s_projectionInfos.Length
 097            return AssemblyReferenceHandle.FromVirtualIndex(s_projectionInfos[projectionIndex].AssemblyRef);
 098        }
 99
 100        internal static StringHandle GetProjectedName(int projectionIndex)
 0101        {
 0102            Debug.Assert(s_projectionInfos != null && projectionIndex >= 0 && projectionIndex < s_projectionInfos.Length
 0103            return StringHandle.FromVirtualIndex(s_projectionInfos[projectionIndex].ClrName);
 0104        }
 105
 106        internal static StringHandle GetProjectedNamespace(int projectionIndex)
 0107        {
 0108            Debug.Assert(s_projectionInfos != null && projectionIndex >= 0 && projectionIndex < s_projectionInfos.Length
 0109            return StringHandle.FromVirtualIndex(s_projectionInfos[projectionIndex].ClrNamespace);
 0110        }
 111
 112        internal static TypeRefSignatureTreatment GetProjectedSignatureTreatment(int projectionIndex)
 0113        {
 0114            Debug.Assert(s_projectionInfos != null && projectionIndex >= 0 && projectionIndex < s_projectionInfos.Length
 0115            return s_projectionInfos[projectionIndex].SignatureTreatment;
 0116        }
 117
 118        private static void InitializeProjectedTypes()
 0119        {
 0120            if (s_projectedTypeNames == null || s_projectionInfos == null)
 0121            {
 0122                var systemRuntimeWindowsRuntime = AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime;
 0123                var systemRuntime = AssemblyReferenceHandle.VirtualIndex.System_Runtime;
 0124                var systemObjectModel = AssemblyReferenceHandle.VirtualIndex.System_ObjectModel;
 0125                var systemRuntimeWindowsUiXaml = AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime_UI_X
 0126                var systemRuntimeInterop = AssemblyReferenceHandle.VirtualIndex.System_Runtime_InteropServices_WindowsRu
 0127                var systemNumericsVectors = AssemblyReferenceHandle.VirtualIndex.System_Numerics_Vectors;
 128
 129                // sorted by name
 0130                var keys = new string[50];
 0131                var values = new ProjectionInfo[50];
 0132                int k = 0, v = 0;
 133
 134                // WARNING: Keys must be sorted by name and must only contain ASCII characters. WinRTNamespace must also
 135
 0136                keys[k++] = "AttributeTargets"; values[v++] = new ProjectionInfo("Windows.Foundation.Metadata", StringHa
 0137                keys[k++] = "AttributeUsageAttribute"; values[v++] = new ProjectionInfo("Windows.Foundation.Metadata", S
 0138                keys[k++] = "Color"; values[v++] = new ProjectionInfo("Windows.UI", StringHandle.VirtualIndex.Windows_UI
 0139                keys[k++] = "CornerRadius"; values[v++] = new ProjectionInfo("Windows.UI.Xaml", StringHandle.VirtualInde
 0140                keys[k++] = "DateTime"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualIndex
 0141                keys[k++] = "Duration"; values[v++] = new ProjectionInfo("Windows.UI.Xaml", StringHandle.VirtualIndex.Wi
 0142                keys[k++] = "DurationType"; values[v++] = new ProjectionInfo("Windows.UI.Xaml", StringHandle.VirtualInde
 0143                keys[k++] = "EventHandler`1"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.Virtua
 0144                keys[k++] = "EventRegistrationToken"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandl
 0145                keys[k++] = "GeneratorPosition"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Controls.Primitives",
 0146                keys[k++] = "GridLength"; values[v++] = new ProjectionInfo("Windows.UI.Xaml", StringHandle.VirtualIndex.
 0147                keys[k++] = "GridUnitType"; values[v++] = new ProjectionInfo("Windows.UI.Xaml", StringHandle.VirtualInde
 0148                keys[k++] = "HResult"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualIndex.
 0149                keys[k++] = "IBindableIterable"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Interop", StringHandl
 0150                keys[k++] = "IBindableVector"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Interop", StringHandle.
 0151                keys[k++] = "IClosable"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualInde
 0152                keys[k++] = "ICommand"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Input", StringHandle.VirtualIn
 0153                keys[k++] = "IIterable`1"; values[v++] = new ProjectionInfo("Windows.Foundation.Collections", StringHand
 0154                keys[k++] = "IKeyValuePair`2"; values[v++] = new ProjectionInfo("Windows.Foundation.Collections", String
 0155                keys[k++] = "IMapView`2"; values[v++] = new ProjectionInfo("Windows.Foundation.Collections", StringHandl
 0156                keys[k++] = "IMap`2"; values[v++] = new ProjectionInfo("Windows.Foundation.Collections", StringHandle.Vi
 0157                keys[k++] = "INotifyCollectionChanged"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Interop", Stri
 0158                keys[k++] = "INotifyPropertyChanged"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Data", StringHan
 0159                keys[k++] = "IReference`1"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualI
 0160                keys[k++] = "IVectorView`1"; values[v++] = new ProjectionInfo("Windows.Foundation.Collections", StringHa
 0161                keys[k++] = "IVector`1"; values[v++] = new ProjectionInfo("Windows.Foundation.Collections", StringHandle
 0162                keys[k++] = "KeyTime"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Media.Animation", StringHandle.
 0163                keys[k++] = "Matrix"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Media", StringHandle.VirtualInde
 0164                keys[k++] = "Matrix3D"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Media.Media3D", StringHandle.V
 0165                keys[k++] = "Matrix3x2"; values[v++] = new ProjectionInfo("Windows.Foundation.Numerics", StringHandle.Vi
 0166                keys[k++] = "Matrix4x4"; values[v++] = new ProjectionInfo("Windows.Foundation.Numerics", StringHandle.Vi
 0167                keys[k++] = "NotifyCollectionChangedAction"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Interop",
 0168                keys[k++] = "NotifyCollectionChangedEventArgs"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Intero
 0169                keys[k++] = "NotifyCollectionChangedEventHandler"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Int
 0170                keys[k++] = "Plane"; values[v++] = new ProjectionInfo("Windows.Foundation.Numerics", StringHandle.Virtua
 0171                keys[k++] = "Point"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualIndex.Wi
 0172                keys[k++] = "PropertyChangedEventArgs"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Data", StringH
 0173                keys[k++] = "PropertyChangedEventHandler"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Data", Stri
 0174                keys[k++] = "Quaternion"; values[v++] = new ProjectionInfo("Windows.Foundation.Numerics", StringHandle.V
 0175                keys[k++] = "Rect"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualIndex.Win
 0176                keys[k++] = "RepeatBehavior"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Media.Animation", String
 0177                keys[k++] = "RepeatBehaviorType"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Media.Animation", St
 0178                keys[k++] = "Size"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualIndex.Win
 0179                keys[k++] = "Thickness"; values[v++] = new ProjectionInfo("Windows.UI.Xaml", StringHandle.VirtualIndex.W
 0180                keys[k++] = "TimeSpan"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualIndex
 0181                keys[k++] = "TypeName"; values[v++] = new ProjectionInfo("Windows.UI.Xaml.Interop", StringHandle.Virtual
 0182                keys[k++] = "Uri"; values[v++] = new ProjectionInfo("Windows.Foundation", StringHandle.VirtualIndex.Syst
 0183                keys[k++] = "Vector2"; values[v++] = new ProjectionInfo("Windows.Foundation.Numerics", StringHandle.Virt
 0184                keys[k++] = "Vector3"; values[v++] = new ProjectionInfo("Windows.Foundation.Numerics", StringHandle.Virt
 0185                keys[k++] = "Vector4"; values[v++] = new ProjectionInfo("Windows.Foundation.Numerics", StringHandle.Virt
 186
 0187                Debug.Assert(k == keys.Length && v == keys.Length && k == v);
 0188                AssertSorted(keys);
 189
 0190                s_projectedTypeNames = keys;
 0191                s_projectionInfos = values;
 0192            }
 0193        }
 194
 195        [Conditional("DEBUG")]
 196        private static void AssertSorted(string[] keys)
 0197        {
 0198            for (int i = 0; i < keys.Length - 1; i++)
 0199            {
 0200                Debug.Assert(string.CompareOrdinal(keys[i], keys[i + 1]) < 0);
 0201            }
 0202        }
 203
 204        // test only
 205        internal static string[] GetProjectedTypeNames()
 0206        {
 0207            InitializeProjectedTypes();
 0208            return s_projectedTypeNames!;
 0209        }
 210
 211        #endregion
 212
 213        private static uint TreatmentAndRowId(byte treatment, int rowId)
 0214        {
 0215            return ((uint)treatment << TokenTypeIds.RowIdBitCount) | (uint)rowId;
 0216        }
 217
 218        #region TypeDef
 219
 220        [MethodImpl(MethodImplOptions.NoInlining)]
 221        internal uint CalculateTypeDefTreatmentAndRowId(TypeDefinitionHandle handle)
 0222        {
 0223            Debug.Assert(_metadataKind != MetadataKind.Ecma335);
 224
 225            TypeDefTreatment treatment;
 226
 0227            TypeAttributes flags = TypeDefTable.GetFlags(handle);
 0228            EntityHandle extends = TypeDefTable.GetExtends(handle);
 229
 0230            if ((flags & TypeAttributes.WindowsRuntime) != 0)
 0231            {
 0232                if (_metadataKind == MetadataKind.WindowsMetadata)
 0233                {
 0234                    treatment = GetWellKnownTypeDefinitionTreatment(handle);
 0235                    if (treatment != TypeDefTreatment.None)
 0236                    {
 0237                        return TreatmentAndRowId((byte)treatment, handle.RowId);
 238                    }
 239
 240                    // Is this an attribute?
 0241                    if (extends.Kind == HandleKind.TypeReference && IsSystemAttribute((TypeReferenceHandle)extends))
 0242                    {
 0243                        treatment = TypeDefTreatment.NormalAttribute;
 0244                    }
 245                    else
 0246                    {
 0247                        treatment = TypeDefTreatment.NormalNonAttribute;
 0248                    }
 0249                }
 0250                else if (_metadataKind == MetadataKind.ManagedWindowsMetadata && NeedsWinRTPrefix(flags, extends))
 0251                {
 252                    // WinMDExp emits two versions of RuntimeClasses and Enums:
 253                    //
 254                    //    public class Foo {}            // the WinRT reference class
 255                    //    internal class <CLR>Foo {}     // the implementation class that we want WinRT consumers to ign
 256                    //
 257                    // The adapter's job is to undo WinMDExp's transformations. I.e. turn the above into:
 258                    //
 259                    //    internal class <WinRT>Foo {}   // the WinRT reference class that we want CLR consumers to igno
 260                    //    public class Foo {}            // the implementation class
 261                    //
 262                    // We only add the <WinRT> prefix here since the WinRT view is the only view that is marked WindowsR
 263                    // De-mangling the CLR name is done below.
 264
 265
 266                    // tomat: The CLR adapter implements a back-compat quirk: Enums exported with an older WinMDExp have
 267                    // not marked with tdSpecialName. These enums should *not* be mangled and flipped to private.
 268                    // We don't implement this flag since the WinMDs produced by the older WinMDExp are not used in the 
 269
 0270                    treatment = TypeDefTreatment.PrefixWinRTName;
 0271                }
 272                else
 0273                {
 0274                    treatment = TypeDefTreatment.None;
 0275                }
 276
 277                // Scan through Custom Attributes on type, looking for interesting bits. We only
 278                // need to do this for RuntimeClasses
 0279                if ((treatment == TypeDefTreatment.PrefixWinRTName || treatment == TypeDefTreatment.NormalNonAttribute))
 0280                {
 0281                    if ((flags & TypeAttributes.Interface) == 0
 0282                        && HasAttribute(handle, "Windows.UI.Xaml", "TreatAsAbstractComposableClassAttribute"))
 0283                    {
 0284                        treatment |= TypeDefTreatment.MarkAbstractFlag;
 0285                    }
 0286                }
 0287            }
 0288            else if (_metadataKind == MetadataKind.ManagedWindowsMetadata && IsClrImplementationType(handle))
 0289            {
 290                // <CLR> implementation classes are not marked WindowsRuntime, but still need to be modified
 291                // by the adapter.
 0292                treatment = TypeDefTreatment.UnmangleWinRTName;
 0293            }
 294            else
 0295            {
 0296                treatment = TypeDefTreatment.None;
 0297            }
 298
 0299            return TreatmentAndRowId((byte)treatment, handle.RowId);
 0300        }
 301
 302        private bool IsClrImplementationType(TypeDefinitionHandle typeDef)
 0303        {
 0304            var attrs = TypeDefTable.GetFlags(typeDef);
 305
 0306            if ((attrs & (TypeAttributes.VisibilityMask | TypeAttributes.SpecialName)) != TypeAttributes.SpecialName)
 0307            {
 0308                return false;
 309            }
 310
 0311            return StringHeap.StartsWithRaw(TypeDefTable.GetName(typeDef), ClrPrefix);
 0312        }
 313
 314        #endregion
 315
 316        #region TypeRef
 317
 318        internal uint CalculateTypeRefTreatmentAndRowId(TypeReferenceHandle handle)
 0319        {
 0320            Debug.Assert(_metadataKind != MetadataKind.Ecma335);
 321
 0322            int projectionIndex = GetProjectionIndexForTypeReference(handle, out _);
 0323            if (projectionIndex >= 0)
 0324            {
 0325                return TreatmentAndRowId((byte)TypeRefTreatment.UseProjectionInfo, projectionIndex);
 326            }
 327            else
 0328            {
 0329                return TreatmentAndRowId((byte)GetSpecialTypeRefTreatment(handle), handle.RowId);
 330            }
 0331        }
 332
 333        private TypeRefTreatment GetSpecialTypeRefTreatment(TypeReferenceHandle handle)
 0334        {
 0335            if (StringHeap.EqualsRaw(TypeRefTable.GetNamespace(handle), "System"))
 0336            {
 0337                StringHandle name = TypeRefTable.GetName(handle);
 338
 0339                if (StringHeap.EqualsRaw(name, "MulticastDelegate"))
 0340                {
 0341                    return TypeRefTreatment.SystemDelegate;
 342                }
 343
 0344                if (StringHeap.EqualsRaw(name, "Attribute"))
 0345                {
 0346                    return TypeRefTreatment.SystemAttribute;
 347                }
 0348            }
 349
 0350            return TypeRefTreatment.None;
 0351        }
 352
 353        private bool IsSystemAttribute(TypeReferenceHandle handle)
 0354        {
 0355            return StringHeap.EqualsRaw(TypeRefTable.GetNamespace(handle), "System") &&
 0356                   StringHeap.EqualsRaw(TypeRefTable.GetName(handle), "Attribute");
 0357        }
 358
 359        private bool NeedsWinRTPrefix(TypeAttributes flags, EntityHandle extends)
 0360        {
 0361            if ((flags & (TypeAttributes.VisibilityMask | TypeAttributes.Interface)) != TypeAttributes.Public)
 0362            {
 0363                return false;
 364            }
 365
 0366            if (extends.Kind != HandleKind.TypeReference)
 0367            {
 0368                return false;
 369            }
 370
 371            // Check if the type is a delegate, struct, or attribute
 0372            TypeReferenceHandle extendsRefHandle = (TypeReferenceHandle)extends;
 0373            if (StringHeap.EqualsRaw(TypeRefTable.GetNamespace(extendsRefHandle), "System"))
 0374            {
 0375                StringHandle nameHandle = TypeRefTable.GetName(extendsRefHandle);
 0376                if (StringHeap.EqualsRaw(nameHandle, "MulticastDelegate")
 0377                    || StringHeap.EqualsRaw(nameHandle, "ValueType")
 0378                    || StringHeap.EqualsRaw(nameHandle, "Attribute"))
 0379                {
 0380                    return false;
 381                }
 0382            }
 0383            return true;
 0384        }
 385
 386        #endregion
 387
 388        #region MethodDef
 389
 390        private uint CalculateMethodDefTreatmentAndRowId(MethodDefinitionHandle methodDef)
 0391        {
 0392            MethodDefTreatment treatment = MethodDefTreatment.Implementation;
 393
 0394            TypeDefinitionHandle parentTypeDef = GetDeclaringType(methodDef);
 0395            TypeAttributes parentFlags = TypeDefTable.GetFlags(parentTypeDef);
 396
 0397            if ((parentFlags & TypeAttributes.WindowsRuntime) != 0)
 0398            {
 0399                if (IsClrImplementationType(parentTypeDef))
 0400                {
 0401                    treatment = MethodDefTreatment.Implementation;
 0402                }
 0403                else if (parentFlags.IsNested())
 0404                {
 0405                    treatment = MethodDefTreatment.Implementation;
 0406                }
 0407                else if ((parentFlags & TypeAttributes.Interface) != 0)
 0408                {
 0409                    treatment = MethodDefTreatment.InterfaceMethod;
 0410                }
 0411                else if (_metadataKind == MetadataKind.ManagedWindowsMetadata && (parentFlags & TypeAttributes.Public) =
 0412                {
 0413                    treatment = MethodDefTreatment.Implementation;
 0414                }
 415                else
 0416                {
 0417                    treatment = MethodDefTreatment.Other;
 418
 0419                    var parentBaseType = TypeDefTable.GetExtends(parentTypeDef);
 0420                    if (parentBaseType.Kind == HandleKind.TypeReference)
 0421                    {
 0422                        switch (GetSpecialTypeRefTreatment((TypeReferenceHandle)parentBaseType))
 423                        {
 424                            case TypeRefTreatment.SystemAttribute:
 0425                                treatment = MethodDefTreatment.AttributeMethod;
 0426                                break;
 427
 428                            case TypeRefTreatment.SystemDelegate:
 0429                                treatment = MethodDefTreatment.DelegateMethod | MethodDefTreatment.MarkPublicFlag;
 0430                                break;
 431                        }
 0432                    }
 0433                }
 0434            }
 435
 0436            if (treatment == MethodDefTreatment.Other)
 0437            {
 438                // we want to hide the method if it implements
 439                // only redirected interfaces
 440                // We also want to check if the methodImpl is IClosable.Close,
 441                // so we can change the name
 0442                bool seenRedirectedInterfaces = false;
 0443                bool seenNonRedirectedInterfaces = false;
 444
 0445                bool isIClosableClose = false;
 446
 0447                foreach (var methodImplHandle in new MethodImplementationHandleCollection(this, parentTypeDef))
 0448                {
 0449                    MethodImplementation methodImpl = GetMethodImplementation(methodImplHandle);
 0450                    if (methodImpl.MethodBody == methodDef)
 0451                    {
 0452                        EntityHandle declaration = methodImpl.MethodDeclaration;
 453
 454                        // See if this MethodImpl implements a redirected interface
 455                        // In WinMD, MethodImpl will always use MemberRef and TypeRefs to refer to redirected interfaces
 456                        // even if they are in the same module.
 0457                        if (declaration.Kind == HandleKind.MemberReference &&
 0458                            ImplementsRedirectedInterface((MemberReferenceHandle)declaration, out isIClosableClose))
 0459                        {
 0460                            seenRedirectedInterfaces = true;
 0461                            if (isIClosableClose)
 0462                            {
 463                                // This method implements IClosable.Close
 464                                // Let's rename to IDisposable later
 465                                // Once we know this implements IClosable.Close, we are done
 466                                // looking
 0467                                break;
 468                            }
 0469                        }
 470                        else
 0471                        {
 472                            // Now we know this implements a non-redirected interface
 473                            // But we need to keep looking, just in case we got a methodimpl that
 474                            // implements the IClosable.Close method and needs to be renamed
 0475                            seenNonRedirectedInterfaces = true;
 0476                        }
 0477                    }
 0478                }
 479
 0480                if (isIClosableClose)
 0481                {
 0482                    treatment = MethodDefTreatment.DisposeMethod;
 0483                }
 0484                else if (seenRedirectedInterfaces && !seenNonRedirectedInterfaces)
 0485                {
 486                    // Only hide if all the interfaces implemented are redirected
 0487                    treatment = MethodDefTreatment.HiddenInterfaceImplementation;
 0488                }
 0489            }
 490
 491            // If treatment is other, then this is a non-managed WinRT runtime class definition
 492            // Find out about various bits that we apply via attributes and name parsing
 0493            if (treatment == MethodDefTreatment.Other)
 0494            {
 0495                treatment |= GetMethodTreatmentFromCustomAttributes(methodDef);
 0496            }
 497
 0498            return TreatmentAndRowId((byte)treatment, methodDef.RowId);
 0499        }
 500
 501        private MethodDefTreatment GetMethodTreatmentFromCustomAttributes(MethodDefinitionHandle methodDef)
 0502        {
 0503            MethodDefTreatment treatment = 0;
 504
 0505            foreach (var caHandle in GetCustomAttributes(methodDef))
 0506            {
 507                StringHandle namespaceHandle, nameHandle;
 0508                if (!GetAttributeTypeNameRaw(caHandle, out namespaceHandle, out nameHandle))
 0509                {
 0510                    continue;
 511                }
 512
 0513                Debug.Assert(!namespaceHandle.IsVirtual && !nameHandle.IsVirtual);
 514
 0515                if (StringHeap.EqualsRaw(namespaceHandle, "Windows.UI.Xaml"))
 0516                {
 0517                    if (StringHeap.EqualsRaw(nameHandle, "TreatAsPublicMethodAttribute"))
 0518                    {
 0519                        treatment |= MethodDefTreatment.MarkPublicFlag;
 0520                    }
 521
 0522                    if (StringHeap.EqualsRaw(nameHandle, "TreatAsAbstractMethodAttribute"))
 0523                    {
 0524                        treatment |= MethodDefTreatment.MarkAbstractFlag;
 0525                    }
 0526                }
 0527            }
 528
 0529            return treatment;
 0530        }
 531
 532        #endregion
 533
 534        #region FieldDef
 535
 536        /// <summary>
 537        /// The backing field of a WinRT enumeration type is not public although the backing fields
 538        /// of managed enumerations are. To allow managed languages to directly access this field,
 539        /// it is made public by the metadata adapter.
 540        /// </summary>
 541        private uint CalculateFieldDefTreatmentAndRowId(FieldDefinitionHandle handle)
 0542        {
 0543            var flags = FieldTable.GetFlags(handle);
 0544            FieldDefTreatment treatment = FieldDefTreatment.None;
 545
 0546            if ((flags & FieldAttributes.RTSpecialName) != 0 && StringHeap.EqualsRaw(FieldTable.GetName(handle), "value_
 0547            {
 0548                TypeDefinitionHandle typeDef = GetDeclaringType(handle);
 549
 0550                EntityHandle baseTypeHandle = TypeDefTable.GetExtends(typeDef);
 0551                if (baseTypeHandle.Kind == HandleKind.TypeReference)
 0552                {
 0553                    var typeRef = (TypeReferenceHandle)baseTypeHandle;
 554
 0555                    if (StringHeap.EqualsRaw(TypeRefTable.GetName(typeRef), "Enum") &&
 0556                        StringHeap.EqualsRaw(TypeRefTable.GetNamespace(typeRef), "System"))
 0557                    {
 0558                        treatment = FieldDefTreatment.EnumValue;
 0559                    }
 0560                }
 0561            }
 562
 0563            return TreatmentAndRowId((byte)treatment, handle.RowId);
 0564        }
 565
 566        #endregion
 567
 568        #region MemberRef
 569
 570        private uint CalculateMemberRefTreatmentAndRowId(MemberReferenceHandle handle)
 0571        {
 572            MemberRefTreatment treatment;
 573
 574            // We need to rename the MemberRef for IClosable.Close as well
 575            // so that the MethodImpl for the Dispose method can be correctly shown
 576            // as IDisposable.Dispose instead of IDisposable.Close
 577            bool isIDisposable;
 0578            if (ImplementsRedirectedInterface(handle, out isIDisposable) && isIDisposable)
 0579            {
 0580                treatment = MemberRefTreatment.Dispose;
 0581            }
 582            else
 0583            {
 0584                treatment = MemberRefTreatment.None;
 0585            }
 586
 0587            return TreatmentAndRowId((byte)treatment, handle.RowId);
 0588        }
 589
 590        /// <summary>
 591        /// We want to know if a given method implements a redirected interface.
 592        /// For example, if we are given the method RemoveAt on a class "A"
 593        /// which implements the IVector interface (which is redirected
 594        /// to IList in .NET) then this method would return true. The most
 595        /// likely reason why we would want to know this is that we wish to hide
 596        /// (mark private) all methods which implement methods on a redirected
 597        /// interface.
 598        /// </summary>
 599        /// <param name="memberRef">The declaration token for the method</param>
 600        /// <param name="isIDisposable">
 601        /// Returns true if the redirected interface is <see cref="IDisposable"/>.
 602        /// </param>
 603        /// <returns>True if the method implements a method on a redirected interface.
 604        /// False otherwise.</returns>
 605        private bool ImplementsRedirectedInterface(MemberReferenceHandle memberRef, out bool isIDisposable)
 0606        {
 0607            isIDisposable = false;
 608
 0609            EntityHandle parent = MemberRefTable.GetClass(memberRef);
 610
 611            TypeReferenceHandle typeRef;
 0612            if (parent.Kind == HandleKind.TypeReference)
 0613            {
 0614                typeRef = (TypeReferenceHandle)parent;
 0615            }
 0616            else if (parent.Kind == HandleKind.TypeSpecification)
 0617            {
 0618                BlobHandle blob = TypeSpecTable.GetSignature((TypeSpecificationHandle)parent);
 0619                BlobReader sig = new BlobReader(BlobHeap.GetMemoryBlock(blob));
 620
 0621                if (sig.Length < 2 ||
 0622                    sig.ReadByte() != (byte)CorElementType.ELEMENT_TYPE_GENERICINST ||
 0623                    sig.ReadByte() != (byte)CorElementType.ELEMENT_TYPE_CLASS)
 0624                {
 0625                    return false;
 626                }
 627
 0628                EntityHandle token = sig.ReadTypeHandle();
 0629                if (token.Kind != HandleKind.TypeReference)
 0630                {
 0631                    return false;
 632                }
 633
 0634                typeRef = (TypeReferenceHandle)token;
 0635            }
 636            else
 0637            {
 0638                return false;
 639            }
 640
 0641            return GetProjectionIndexForTypeReference(typeRef, out isIDisposable) >= 0;
 0642        }
 643
 644        #endregion
 645
 646        #region AssemblyRef
 647
 648        private int FindMscorlibAssemblyRefNoProjection()
 0649        {
 0650            for (int i = 1; i <= AssemblyRefTable.NumberOfNonVirtualRows; i++)
 0651            {
 0652                if (StringHeap.EqualsRaw(AssemblyRefTable.GetName(i), "mscorlib"))
 0653                {
 0654                    return i;
 655                }
 0656            }
 657
 0658            throw new BadImageFormatException(SR.WinMDMissingMscorlibRef);
 0659        }
 660
 661        #endregion
 662
 663        #region CustomAttribute
 664
 665        internal CustomAttributeValueTreatment CalculateCustomAttributeValueTreatment(CustomAttributeHandle handle)
 0666        {
 0667            Debug.Assert(_metadataKind != MetadataKind.Ecma335);
 668
 0669            var parent = CustomAttributeTable.GetParent(handle);
 670
 671            // Check for Windows.Foundation.Metadata.AttributeUsageAttribute.
 672            // WinMD rules:
 673            //   - The attribute is only applicable on TypeDefs.
 674            //   - Constructor must be a MemberRef with TypeRef.
 0675            if (!IsWindowsAttributeUsageAttribute(parent, handle))
 0676            {
 0677                return CustomAttributeValueTreatment.None;
 678            }
 679
 0680            var targetTypeDef = (TypeDefinitionHandle)parent;
 0681            if (StringHeap.EqualsRaw(TypeDefTable.GetNamespace(targetTypeDef), "Windows.Foundation.Metadata"))
 0682            {
 0683                if (StringHeap.EqualsRaw(TypeDefTable.GetName(targetTypeDef), "VersionAttribute"))
 0684                {
 0685                    return CustomAttributeValueTreatment.AttributeUsageVersionAttribute;
 686                }
 687
 0688                if (StringHeap.EqualsRaw(TypeDefTable.GetName(targetTypeDef), "DeprecatedAttribute"))
 0689                {
 0690                    return CustomAttributeValueTreatment.AttributeUsageDeprecatedAttribute;
 691                }
 0692            }
 693
 0694            bool allowMultiple = HasAttribute(targetTypeDef, "Windows.Foundation.Metadata", "AllowMultipleAttribute");
 0695            return allowMultiple ? CustomAttributeValueTreatment.AttributeUsageAllowMultiple : CustomAttributeValueTreat
 0696        }
 697
 698        private bool IsWindowsAttributeUsageAttribute(EntityHandle targetType, CustomAttributeHandle attributeHandle)
 0699        {
 700            // Check for Windows.Foundation.Metadata.AttributeUsageAttribute.
 701            // WinMD rules:
 702            //   - The attribute is only applicable on TypeDefs.
 703            //   - Constructor must be a MemberRef with TypeRef.
 704
 0705            if (targetType.Kind != HandleKind.TypeDefinition)
 0706            {
 0707                return false;
 708            }
 709
 0710            var attributeCtor = CustomAttributeTable.GetConstructor(attributeHandle);
 0711            if (attributeCtor.Kind != HandleKind.MemberReference)
 0712            {
 0713                return false;
 714            }
 715
 0716            var attributeType = MemberRefTable.GetClass((MemberReferenceHandle)attributeCtor);
 0717            if (attributeType.Kind != HandleKind.TypeReference)
 0718            {
 0719                return false;
 720            }
 721
 0722            var attributeTypeRef = (TypeReferenceHandle)attributeType;
 0723            return StringHeap.EqualsRaw(TypeRefTable.GetName(attributeTypeRef), "AttributeUsageAttribute") &&
 0724                   StringHeap.EqualsRaw(TypeRefTable.GetNamespace(attributeTypeRef), "Windows.Foundation.Metadata");
 0725        }
 726
 727        private bool HasAttribute(EntityHandle token, string asciiNamespaceName, string asciiTypeName)
 0728        {
 0729            foreach (var caHandle in GetCustomAttributes(token))
 0730            {
 731                StringHandle namespaceName, typeName;
 0732                if (GetAttributeTypeNameRaw(caHandle, out namespaceName, out typeName) &&
 0733                    StringHeap.EqualsRaw(typeName, asciiTypeName) &&
 0734                    StringHeap.EqualsRaw(namespaceName, asciiNamespaceName))
 0735                {
 0736                    return true;
 737                }
 0738            }
 739
 0740            return false;
 0741        }
 742
 743        private bool GetAttributeTypeNameRaw(CustomAttributeHandle caHandle, out StringHandle namespaceName, out StringH
 0744        {
 0745            namespaceName = typeName = default(StringHandle);
 746
 0747            EntityHandle typeDefOrRef = GetAttributeTypeRaw(caHandle);
 0748            if (typeDefOrRef.IsNil)
 0749            {
 0750                return false;
 751            }
 752
 0753            if (typeDefOrRef.Kind == HandleKind.TypeReference)
 0754            {
 0755                TypeReferenceHandle typeRef = (TypeReferenceHandle)typeDefOrRef;
 0756                var resolutionScope = TypeRefTable.GetResolutionScope(typeRef);
 757
 0758                if (!resolutionScope.IsNil && resolutionScope.Kind == HandleKind.TypeReference)
 0759                {
 760                    // we don't need to handle nested types
 0761                    return false;
 762                }
 763
 764                // other resolution scopes don't affect full name
 765
 0766                typeName = TypeRefTable.GetName(typeRef);
 0767                namespaceName = TypeRefTable.GetNamespace(typeRef);
 0768            }
 0769            else if (typeDefOrRef.Kind == HandleKind.TypeDefinition)
 0770            {
 0771                TypeDefinitionHandle typeDef = (TypeDefinitionHandle)typeDefOrRef;
 772
 0773                if (TypeDefTable.GetFlags(typeDef).IsNested())
 0774                {
 775                    // we don't need to handle nested types
 0776                    return false;
 777                }
 778
 0779                typeName = TypeDefTable.GetName(typeDef);
 0780                namespaceName = TypeDefTable.GetNamespace(typeDef);
 0781            }
 782            else
 0783            {
 784                // invalid metadata
 0785                return false;
 786            }
 787
 0788            return true;
 0789        }
 790
 791        /// <summary>
 792        /// Returns the type definition or reference handle of the attribute type.
 793        /// </summary>
 794        /// <returns><see cref="TypeDefinitionHandle"/> or <see cref="TypeReferenceHandle"/> or nil token if the metadat
 795        private EntityHandle GetAttributeTypeRaw(CustomAttributeHandle handle)
 0796        {
 0797            var ctor = CustomAttributeTable.GetConstructor(handle);
 798
 0799            if (ctor.Kind == HandleKind.MethodDefinition)
 0800            {
 0801                return GetDeclaringType((MethodDefinitionHandle)ctor);
 802            }
 803
 0804            if (ctor.Kind == HandleKind.MemberReference)
 0805            {
 806                // In general the parent can be MethodDef, ModuleRef, TypeDef, TypeRef, or TypeSpec.
 807                // For attributes only TypeDef and TypeRef are applicable.
 0808                EntityHandle typeDefOrRef = MemberRefTable.GetClass((MemberReferenceHandle)ctor);
 0809                HandleKind handleType = typeDefOrRef.Kind;
 810
 0811                if (handleType == HandleKind.TypeReference || handleType == HandleKind.TypeDefinition)
 0812                {
 0813                    return typeDefOrRef;
 814                }
 0815            }
 816
 0817            return default(EntityHandle);
 0818        }
 819        #endregion
 820    }
 821}
 822

Methods/Properties

.ctor(System.Byte*,System.Int32)
.ctor(System.Byte*,System.Int32,System.Reflection.Metadata.MetadataReaderOptions)
.ctor(System.Byte*,System.Int32,System.Reflection.Metadata.MetadataReaderOptions,System.Reflection.Metadata.MetadataStringDecoder)
.ctor(System.Byte*,System.Int32,System.Reflection.Metadata.MetadataReaderOptions,System.Reflection.Metadata.MetadataStringDecoder,System.Object)
ReadMetadataHeader(System.Reflection.Metadata.BlobReader&,System.String&)
GetMetadataKind(System.String)
ReadStreamHeaders(System.Reflection.Metadata.BlobReader&)
InitializeStreamReaders(System.Reflection.Internal.MemoryBlock&,System.Reflection.Metadata.Ecma335.StreamHeader[],System.Reflection.Metadata.Ecma335.MetadataStreamKind&,System.Reflection.Internal.MemoryBlock&,System.Reflection.Internal.MemoryBlock&)
ReadMetadataTableHeader(System.Reflection.Metadata.BlobReader&,System.Reflection.Metadata.Ecma335.HeapSizes&,System.Int32[]&,System.Reflection.Metadata.Ecma335.TableMask&)
ReadMetadataTableRowCounts(System.Reflection.Metadata.BlobReader&,System.UInt64)
ReadStandalonePortablePdbStream(System.Reflection.Internal.MemoryBlock,System.Int32,System.Reflection.Metadata.DebugMetadataHeader&,System.Int32[]&)
GetReferenceSize(System.Int32[],System.Reflection.Metadata.Ecma335.TableIndex)
InitializeTableReaders(System.Reflection.Internal.MemoryBlock,System.Reflection.Metadata.Ecma335.HeapSizes,System.Int32[],System.Int32[])
CombineRowCounts(System.Int32[],System.Int32[],System.Reflection.Metadata.Ecma335.TableIndex)
ComputeCodedTokenSize(System.Int32,System.Int32[],System.Reflection.Metadata.Ecma335.TableMask)
IsDeclaredSorted(System.Reflection.Metadata.Ecma335.TableMask)
UseFieldPtrTable()
UseMethodPtrTable()
UseParamPtrTable()
UseEventPtrTable()
UsePropertyPtrTable()
GetFieldRange(System.Reflection.Metadata.TypeDefinitionHandle,System.Int32&,System.Int32&)
GetMethodRange(System.Reflection.Metadata.TypeDefinitionHandle,System.Int32&,System.Int32&)
GetEventRange(System.Reflection.Metadata.TypeDefinitionHandle,System.Int32&,System.Int32&)
GetPropertyRange(System.Reflection.Metadata.TypeDefinitionHandle,System.Int32&,System.Int32&)
GetParameterRange(System.Reflection.Metadata.MethodDefinitionHandle,System.Int32&,System.Int32&)
GetLocalVariableRange(System.Reflection.Metadata.LocalScopeHandle,System.Int32&,System.Int32&)
GetLocalConstantRange(System.Reflection.Metadata.LocalScopeHandle,System.Int32&,System.Int32&)
MetadataPointer()
MetadataLength()
Options()
MetadataVersion()
DebugMetadataHeader()
MetadataKind()
StringComparer()
UTF8Decoder()
IsAssembly()
AssemblyReferences()
TypeDefinitions()
TypeReferences()
CustomAttributes()
DeclarativeSecurityAttributes()
MemberReferences()
ManifestResources()
AssemblyFiles()
ExportedTypes()
MethodDefinitions()
FieldDefinitions()
EventDefinitions()
PropertyDefinitions()
Documents()
MethodDebugInformation()
LocalScopes()
LocalVariables()
LocalConstants()
ImportScopes()
CustomDebugInformation()
GetAssemblyDefinition()
GetString(System.Reflection.Metadata.StringHandle)
GetString(System.Reflection.Metadata.NamespaceDefinitionHandle)
GetBlobBytes(System.Reflection.Metadata.BlobHandle)
GetBlobContent(System.Reflection.Metadata.BlobHandle)
GetBlobReader(System.Reflection.Metadata.BlobHandle)
GetBlobReader(System.Reflection.Metadata.StringHandle)
GetUserString(System.Reflection.Metadata.UserStringHandle)
GetGuid(System.Reflection.Metadata.GuidHandle)
GetModuleDefinition()
GetAssemblyReference(System.Reflection.Metadata.AssemblyReferenceHandle)
GetTypeDefinition(System.Reflection.Metadata.TypeDefinitionHandle)
GetNamespaceDefinitionRoot()
GetNamespaceDefinition(System.Reflection.Metadata.NamespaceDefinitionHandle)
GetTypeDefTreatmentAndRowId(System.Reflection.Metadata.TypeDefinitionHandle)
GetTypeReference(System.Reflection.Metadata.TypeReferenceHandle)
GetTypeRefTreatmentAndRowId(System.Reflection.Metadata.TypeReferenceHandle)
GetExportedType(System.Reflection.Metadata.ExportedTypeHandle)
GetCustomAttributes(System.Reflection.Metadata.EntityHandle)
GetCustomAttribute(System.Reflection.Metadata.CustomAttributeHandle)
GetCustomAttributeTreatmentAndRowId(System.Reflection.Metadata.CustomAttributeHandle)
GetDeclarativeSecurityAttribute(System.Reflection.Metadata.DeclarativeSecurityAttributeHandle)
GetConstant(System.Reflection.Metadata.ConstantHandle)
GetMethodDefinition(System.Reflection.Metadata.MethodDefinitionHandle)
GetMethodDefTreatmentAndRowId(System.Reflection.Metadata.MethodDefinitionHandle)
GetFieldDefinition(System.Reflection.Metadata.FieldDefinitionHandle)
GetFieldDefTreatmentAndRowId(System.Reflection.Metadata.FieldDefinitionHandle)
GetPropertyDefinition(System.Reflection.Metadata.PropertyDefinitionHandle)
GetEventDefinition(System.Reflection.Metadata.EventDefinitionHandle)
GetMethodImplementation(System.Reflection.Metadata.MethodImplementationHandle)
GetMemberReference(System.Reflection.Metadata.MemberReferenceHandle)
GetMemberRefTreatmentAndRowId(System.Reflection.Metadata.MemberReferenceHandle)
GetMethodSpecification(System.Reflection.Metadata.MethodSpecificationHandle)
GetParameter(System.Reflection.Metadata.ParameterHandle)
GetGenericParameter(System.Reflection.Metadata.GenericParameterHandle)
GetGenericParameterConstraint(System.Reflection.Metadata.GenericParameterConstraintHandle)
GetManifestResource(System.Reflection.Metadata.ManifestResourceHandle)
GetAssemblyFile(System.Reflection.Metadata.AssemblyFileHandle)
GetStandaloneSignature(System.Reflection.Metadata.StandaloneSignatureHandle)
GetTypeSpecification(System.Reflection.Metadata.TypeSpecificationHandle)
GetModuleReference(System.Reflection.Metadata.ModuleReferenceHandle)
GetInterfaceImplementation(System.Reflection.Metadata.InterfaceImplementationHandle)
GetDeclaringType(System.Reflection.Metadata.MethodDefinitionHandle)
GetDeclaringType(System.Reflection.Metadata.FieldDefinitionHandle)
GetDeclaringType(System.Reflection.Metadata.EventDefinitionHandle)
GetDeclaringType(System.Reflection.Metadata.PropertyDefinitionHandle)
GetString(System.Reflection.Metadata.DocumentNameBlobHandle)
GetDocument(System.Reflection.Metadata.DocumentHandle)
GetMethodDebugInformation(System.Reflection.Metadata.MethodDebugInformationHandle)
GetMethodDebugInformation(System.Reflection.Metadata.MethodDefinitionHandle)
GetLocalScope(System.Reflection.Metadata.LocalScopeHandle)
GetLocalVariable(System.Reflection.Metadata.LocalVariableHandle)
GetLocalConstant(System.Reflection.Metadata.LocalConstantHandle)
GetImportScope(System.Reflection.Metadata.ImportScopeHandle)
GetCustomDebugInformation(System.Reflection.Metadata.CustomDebugInformationHandle)
GetCustomDebugInformation(System.Reflection.Metadata.EntityHandle)
GetLocalScopes(System.Reflection.Metadata.MethodDefinitionHandle)
GetLocalScopes(System.Reflection.Metadata.MethodDebugInformationHandle)
InitializeNestedTypesMap()
GetNestedTypes(System.Reflection.Metadata.TypeDefinitionHandle)
GetAssemblyName(System.Reflection.Metadata.StringHandle,System.Version,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle,System.Reflection.AssemblyHashAlgorithm,System.Reflection.AssemblyFlags)
GetAssemblyNameInfo(System.Reflection.Metadata.StringHandle,System.Version,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle,System.Reflection.AssemblyFlags)
GetAssemblyName(System.String)
GetAssemblyNameFlags(System.Reflection.AssemblyFlags)
GetContentTypeFromAssemblyFlags(System.Reflection.AssemblyFlags)
.cctor()
.ctor(System.String,System.Reflection.Metadata.StringHandle/VirtualIndex,System.Reflection.Metadata.StringHandle/VirtualIndex,System.Reflection.Metadata.AssemblyReferenceHandle/VirtualIndex,System.Reflection.Metadata.Ecma335.TypeDefTreatment,System.Reflection.Metadata.Ecma335.TypeRefSignatureTreatment,System.Boolean)
GetWellKnownTypeDefinitionTreatment(System.Reflection.Metadata.TypeDefinitionHandle)
GetProjectionIndexForTypeReference(System.Reflection.Metadata.TypeReferenceHandle,System.Boolean&)
GetProjectedAssemblyRef(System.Int32)
GetProjectedName(System.Int32)
GetProjectedNamespace(System.Int32)
GetProjectedSignatureTreatment(System.Int32)
InitializeProjectedTypes()
AssertSorted(System.String[])
GetProjectedTypeNames()
TreatmentAndRowId(System.Byte,System.Int32)
CalculateTypeDefTreatmentAndRowId(System.Reflection.Metadata.TypeDefinitionHandle)
IsClrImplementationType(System.Reflection.Metadata.TypeDefinitionHandle)
CalculateTypeRefTreatmentAndRowId(System.Reflection.Metadata.TypeReferenceHandle)
GetSpecialTypeRefTreatment(System.Reflection.Metadata.TypeReferenceHandle)
IsSystemAttribute(System.Reflection.Metadata.TypeReferenceHandle)
NeedsWinRTPrefix(System.Reflection.TypeAttributes,System.Reflection.Metadata.EntityHandle)
CalculateMethodDefTreatmentAndRowId(System.Reflection.Metadata.MethodDefinitionHandle)
GetMethodTreatmentFromCustomAttributes(System.Reflection.Metadata.MethodDefinitionHandle)
CalculateFieldDefTreatmentAndRowId(System.Reflection.Metadata.FieldDefinitionHandle)
CalculateMemberRefTreatmentAndRowId(System.Reflection.Metadata.MemberReferenceHandle)
ImplementsRedirectedInterface(System.Reflection.Metadata.MemberReferenceHandle,System.Boolean&)
FindMscorlibAssemblyRefNoProjection()
CalculateCustomAttributeValueTreatment(System.Reflection.Metadata.CustomAttributeHandle)
IsWindowsAttributeUsageAttribute(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.CustomAttributeHandle)
HasAttribute(System.Reflection.Metadata.EntityHandle,System.String,System.String)
GetAttributeTypeNameRaw(System.Reflection.Metadata.CustomAttributeHandle,System.Reflection.Metadata.StringHandle&,System.Reflection.Metadata.StringHandle&)
GetAttributeTypeRaw(System.Reflection.Metadata.CustomAttributeHandle)