private AQName CalculateQualifiedTypeNameRecursive(
            TypeReferenceHandle handle,
            Dictionary <string, EntityHandle> nameToHandle,
            Dictionary <EntityHandle, AQName> handleToName)
        {
            AQName name;

            if (handleToName.TryGetValue(handle, out name))
            {
                return(name);
            }

            var typeRef = Reader.GetTypeReference(handle);

            // we have alread calculated all other names earlier:
            Debug.Assert(typeRef.ResolutionScope.Kind == HandleKind.TypeReference);

            var declaringTypeAssemblyQualifiedName = CalculateQualifiedTypeNameRecursive((TypeReferenceHandle)typeRef.ResolutionScope, nameToHandle, handleToName);
            var qualifiedName         = MakeNestedTypeName(declaringTypeAssemblyQualifiedName.TypeName, Reader.GetString(typeRef.Name));
            var assemblyQualifiedName = MakeAssemblyQualifiedName(qualifiedName, GetAssemblyDisplayName(declaringTypeAssemblyQualifiedName.AssemblyRef));

            var result = new AQName(qualifiedName, declaringTypeAssemblyQualifiedName.AssemblyRef);

            handleToName[handle] = result;
            nameToHandle[assemblyQualifiedName] = handle;
            return(result);
        }
        private bool TryCalculateQualifiedTypeSpecificationName(BlobReader sigReader, Dictionary <EntityHandle, AQName> handleToName, out AQName name)
        {
            var builder = new ImportTypeSpecNameBuilder(handleToName, _lazyAssemblyRefMap.Value.Item2);
            var decoder = new SignatureDecoder <AQName, object>(builder, metadataReader: null, genericContext: null);

            name = decoder.DecodeType(ref sigReader);
            return(builder.IsSupported);
        }
        private Dictionary <string, EntityHandle> BuildTypeMap()
        {
            var nameToHandle = new Dictionary <string, EntityHandle>();
            var handleToName = new Dictionary <EntityHandle, AQName>();

            foreach (var handle in Reader.TypeDefinitions)
            {
                var typeDef = Reader.GetTypeDefinition(handle);

                string name       = Reader.GetString(typeDef.Name);
                var    visibility = (typeDef.Attributes & TypeAttributes.VisibilityMask);

                string qualifiedName;

                TypeDefinitionHandle declaringType;
                if (visibility != TypeAttributes.Public &&
                    visibility != TypeAttributes.NotPublic &&
                    !(declaringType = typeDef.GetDeclaringType()).IsNil)
                {
                    // Spec:
                    //   Finally, the TypeDef table has a special ordering constraint:
                    //   the definition of an enclosing class shall precede the definition of all classes it encloses.
                    //
                    // Hence we alrady have calculated the name of the declaring type.
                    qualifiedName = MakeNestedTypeName(handleToName[declaringType].TypeName, name);
                }
                else
                {
                    qualifiedName = MakeNamespaceTypeName(Reader.GetString(typeDef.Namespace), name);
                }

                nameToHandle.Add(qualifiedName, handle);
                handleToName.Add(handle, new AQName(qualifiedName, default(AssemblyReferenceHandle)));
            }

            foreach (var handle in Reader.TypeReferences)
            {
                var typeRef = Reader.GetTypeReference(handle);

                if (typeRef.ResolutionScope.Kind == HandleKind.TypeReference)
                {
                    // defer nested types
                    continue;
                }

                string qualifiedName = MakeNamespaceTypeName(Reader.GetString(typeRef.Namespace), Reader.GetString(typeRef.Name));

                var assemblyRef = (typeRef.ResolutionScope.Kind == HandleKind.AssemblyReference) ?
                                  (AssemblyReferenceHandle)typeRef.ResolutionScope :
                                  default(AssemblyReferenceHandle);

                var assemblyQualifiedName = MakeAssemblyQualifiedName(qualifiedName, GetAssemblyDisplayName(assemblyRef));

                nameToHandle[assemblyQualifiedName] = handle;
                handleToName[handle] = new AQName(qualifiedName, assemblyRef);
            }

            foreach (var handle in Reader.TypeReferences)
            {
                CalculateQualifiedTypeNameRecursive(handle, nameToHandle, handleToName);
            }

            for (int rowId = 0; rowId <= Reader.GetTableRowCount(TableIndex.TypeSpec); rowId++)
            {
                var handle    = MetadataTokens.TypeSpecificationHandle(rowId);
                var signature = Reader.GetTypeSpecification(handle).Signature;
                var sigReader = Reader.GetBlobReader(signature);

                AQName assemblyQualifiedName;
                if (TryCalculateQualifiedTypeSpecificationName(sigReader, handleToName, out assemblyQualifiedName))
                {
                    nameToHandle[assemblyQualifiedName.TypeName] = handle;
                    handleToName[handle] = assemblyQualifiedName;
                }
            }

            return(nameToHandle);
        }