private MetadataTypeReference GetTypeReferenceForForwardedType(NameSpec fullName) { if (assemblyReferencesByForwardedType == null) { assemblyReferencesByForwardedType = new Dictionary <NameSpec, AssemblyReferenceHandle>(); foreach (var handle in reader.ExportedTypes) { var exportedType = reader.GetExportedType(handle); if (!exportedType.IsForwarder) { continue; } if (exportedType.Implementation.Kind != HandleKind.AssemblyReference) { throw new NotImplementedException(exportedType.Implementation.Kind.ToString()); } assemblyReferencesByForwardedType.Add( new NameSpec( reader.GetString(exportedType.Namespace), reader.GetString(exportedType.Name), nestedNames: null), (AssemblyReferenceHandle)exportedType.Implementation); } } if (assemblyReferencesByForwardedType.TryGetValue(new NameSpec(fullName.Namespace, fullName.TopLevelName, null), out var assemblyReferenceHandle)) { var current = (MetadataTypeReference) new TopLevelTypeReference( reader .GetAssemblyReference(assemblyReferenceHandle) .GetAssemblyName(reader), fullName.Namespace, fullName.TopLevelName); if (fullName.NestedNames != null) { foreach (var nestedName in fullName.NestedNames) { current = new NestedTypeReference(current, nestedName); } } return(current); } return(null); }
public bool TryGetInfo(NameSpec name, MetadataReaderReferenceResolver forwardedTypeResolver, out CachedInfo info) { if (cache.TryGetValue(name, out info)) { return(true); } if (entirelyLoaded) { return(false); } var forwardedReference = GetTypeReferenceForForwardedType(name); if (forwardedReference != null && forwardedTypeResolver.TryGetCachedInfo(forwardedReference, out info)) { cache.Add(name, info); return(true); } while (enumerator.MoveNext()) { var definition = reader.GetTypeDefinition(enumerator.Current); var currentName = GetNameSpec(definition); // Internals may be visible if ((definition.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate) { if (currentName == name) { info = default; return(false); } continue; } var currentInfo = GetInfo(definition); cache.Add(currentName, currentInfo); if (name == currentName) { info = currentInfo; return(true); } } peReader.Dispose(); entirelyLoaded = true; return(false); }
private bool TryGetCachedInfo(MetadataTypeReference typeReference, out CachedInfo cachedInfo) { var(assemblyReference, typeName) = NameSpec.FromMetadataTypeReference(typeReference); if (assemblyReference == null) { if (currentAssemblyLoader == null) { currentAssemblyLoader = new AssemblyLazyLoader(currentAssemblyStreamFactory.Invoke()); } if (currentAssemblyLoader.TryGetInfo(typeName, this, out cachedInfo)) { return(true); } // Attribute values containing enum type references serialize the string. // So far all mscorlib enum references I've seen include the assembly name, // but this is just in case. if (currentAssemblyMscorlibReference == null) { currentAssemblyMscorlibReference = GetMscorlibReference(currentAssemblyStreamFactory.Invoke()); } assemblyReference = currentAssemblyMscorlibReference; } var fullName = assemblyReference.FullName; if (!assemblyLoadersByFullName.TryGetValue(fullName, out var loader)) { loader = assemblyResolver.TryGetAssemblyPath(assemblyReference, out var path) ? new AssemblyLazyLoader(File.OpenRead(path)) : null; assemblyLoadersByFullName.Add(fullName, loader); } if (loader == null) { // We couldn't locate the assembly. cachedInfo = default; return(false); } return(loader.TryGetInfo(typeName, this, out cachedInfo)); }