File: FindSymbols\SymbolTree\SymbolTreeInfo.FirstEntityHandleProvider.cs
Web Access
Project: src\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections.Immutable;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
 
namespace Microsoft.CodeAnalysis.FindSymbols;
 
internal partial class SymbolTreeInfo
{
    /// <summary>
    /// Used to produce the simple-full-name components of a type from metadata.
    /// The name is 'simple' in that it does not contain things like backticks,
    /// generic arguments, or nested type + separators.  Instead just hte name
    /// of the type, any containing types, and the component parts of its namespace
    /// are added.  For example, for the type "X.Y.O`1.I`2, we will produce [X, Y, O, I]
    /// 
    /// </summary>
    private class FirstEntityHandleProvider : ISignatureTypeProvider<EntityHandle, object?>
    {
        public static readonly FirstEntityHandleProvider Instance = new();
 
        public EntityHandle GetTypeFromSpecification(MetadataReader reader, TypeSpecificationHandle handle)
        {
            // Create a decoder to process the type specification (which happens with
            // instantiated generics).  It will call back into us to get the first handle
            // for the type def or type ref that the specification starts with.
            var sigReader = reader.GetBlobReader(reader.GetTypeSpecification(handle).Signature);
            return new SignatureDecoder<EntityHandle, object?>(this, reader, genericContext: null).DecodeType(ref sigReader);
        }
 
        public EntityHandle GetTypeFromSpecification(MetadataReader reader, object? genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
            => GetTypeFromSpecification(reader, handle);
 
        public EntityHandle GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) => handle;
        public EntityHandle GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) => handle;
 
        // We want the first handle as is, without any handles for the generic args.
        public EntityHandle GetGenericInstantiation(EntityHandle genericType, ImmutableArray<EntityHandle> typeArguments) => genericType;
 
        // All the signature elements that would normally augment the passed in type will
        // just pass it along unchanged.
        public EntityHandle GetModifiedType(EntityHandle modifier, EntityHandle unmodifiedType, bool isRequired) => unmodifiedType;
        public EntityHandle GetPinnedType(EntityHandle elementType) => elementType;
        public EntityHandle GetArrayType(EntityHandle elementType, ArrayShape shape) => elementType;
        public EntityHandle GetByReferenceType(EntityHandle elementType) => elementType;
        public EntityHandle GetPointerType(EntityHandle elementType) => elementType;
        public EntityHandle GetSZArrayType(EntityHandle elementType) => elementType;
 
        // We'll never get function pointer types in any types we care about, so we can
        // just return the empty string.  Similarly, as we never construct generics,
        // there is no need to provide anything for the generic parameter names.
        public EntityHandle GetFunctionPointerType(MethodSignature<EntityHandle> signature) => default;
        public EntityHandle GetGenericMethodParameter(object? genericContext, int index) => default;
        public EntityHandle GetGenericTypeParameter(object? genericContext, int index) => default;
 
        public EntityHandle GetPrimitiveType(PrimitiveTypeCode typeCode) => default;
    }
}