Example #1
0
            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);
            }
Example #2
0
            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));
        }