public ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName) { var typeDefHandle = PEFile.GetTypeDefinition(topLevelTypeName); if (typeDefHandle.IsNil) { var forwarderHandle = PEFile.GetTypeForwarder(topLevelTypeName); if (!forwarderHandle.IsNil) { var forwarder = metadata.GetExportedType(forwarderHandle); return(ResolveForwardedType(forwarder).GetDefinition()); } } return(GetDefinition(typeDefHandle)); }
private Object ResolveExportedType(ExportedTypeHandle handle) { ExportedType exportedType = _metadataReader.GetExportedType(handle); var implementation = GetObject(exportedType.Implementation, NotFoundBehavior.ReturnResolutionFailure); if (implementation is ModuleDesc) { var module = (ModuleDesc)implementation; string nameSpace = _metadataReader.GetString(exportedType.Namespace); string name = _metadataReader.GetString(exportedType.Name); return(module.GetType(nameSpace, name, NotFoundBehavior.ReturnResolutionFailure)); } else if (implementation is MetadataType) { var type = (MetadataType)implementation; string name = _metadataReader.GetString(exportedType.Name); var nestedType = type.GetNestedType(name); if (nestedType == null) { return(ResolutionFailure.GetTypeLoadResolutionFailure(name, this)); } return(nestedType); } else if (implementation is ResolutionFailure) { return(implementation); } else { ThrowHelper.ThrowBadImageFormatException(); return(null); } }
public static AssemblyReference GetAssemblyReferenceForExportedType(MetadataReader metaReader, ExportedType exportedType) { if (exportedType.Implementation.Kind == HandleKind.AssemblyReference) { return(metaReader.GetAssemblyReference((AssemblyReferenceHandle)exportedType.Implementation)); } else if (exportedType.Implementation.Kind == HandleKind.ExportedType) { // this means we have an exported nested type. /* * .class extern forwarder System.TimeZoneInfo * { * .assembly extern mscorlib * } * .class extern AdjustmentRule * { * .class extern System.TimeZoneInfo * } */ return(GetAssemblyReferenceForExportedType(metaReader, metaReader.GetExportedType(((ExportedTypeHandle)exportedType.Implementation)))); } return(default(AssemblyReference)); }
private static IEnumerable <string> GetPublicVisibleTypes(string assembly, bool includeTypeForwards = false) { using (var peReader = new PEReader(new FileStream(assembly, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read))) { if (peReader.HasMetadata) { MetadataReader reader = peReader.GetMetadataReader(); // Enumerating typeDefinatons foreach (var typeDefinationHandle in reader.TypeDefinitions) { TypeDefinition typeDefination = reader.GetTypeDefinition(typeDefinationHandle); // Ignoring Nested types if (!typeDefination.IsNested && IsPublic(typeDefination)) { yield return(GetTypeName(typeDefination.Namespace, typeDefination.Name, reader)); } } if (includeTypeForwards) { // Enumerating typeforwards foreach (var exportedTypeHandle in reader.ExportedTypes) { ExportedType exportedType = reader.GetExportedType(exportedTypeHandle); if (exportedType.IsForwarder) { yield return(GetTypeName(exportedType.Namespace, exportedType.Name, reader)); } } } } } }
public IReadOnlyList <string> GetExportedTypeNames() { // Force load System.Design into the appdomain DesignSurface designSurface = new(); IDesigner designer = designSurface.CreateDesigner(new Control(), true); Assert.NotNull(designer); Assembly systemDesign = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "System.Design"); using var fs = new FileStream(systemDesign.Location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using var peReader = new PEReader(fs); MetadataReader metadataReader = peReader.GetMetadataReader(); List <string> typeNames = new(); foreach (ExportedTypeHandle typeHandle in metadataReader.ExportedTypes) { ExportedType type = metadataReader.GetExportedType(typeHandle); string ns = metadataReader.GetString(type.Namespace); string name = metadataReader.GetString(type.Name); typeNames.Add($"{ns}.{name}"); } return(typeNames); }
public sealed override MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true) { var stringComparer = _metadataReader.StringComparer; // TODO: More efficient implementation? foreach (var typeDefinitionHandle in _metadataReader.TypeDefinitions) { var typeDefinition = _metadataReader.GetTypeDefinition(typeDefinitionHandle); if (stringComparer.Equals(typeDefinition.Name, name) && stringComparer.Equals(typeDefinition.Namespace, nameSpace)) { return((MetadataType)GetType((EntityHandle)typeDefinitionHandle)); } } foreach (var exportedTypeHandle in _metadataReader.ExportedTypes) { var exportedType = _metadataReader.GetExportedType(exportedTypeHandle); if (stringComparer.Equals(exportedType.Name, name) && stringComparer.Equals(exportedType.Namespace, nameSpace)) { if (exportedType.IsForwarder) { Object implementation = GetObject(exportedType.Implementation); if (implementation is ModuleDesc) { return(((ModuleDesc)(implementation)).GetType(nameSpace, name)); } // TODO throw new NotImplementedException(); } // TODO: throw new NotImplementedException(); } } if (throwIfNotFound) { throw new TypeSystemException.TypeLoadException(nameSpace, name, this); } return(null); }
internal static IEnumerable <string> GetExportedTypesFullNames(MetadataReader metadataReader) { foreach (var typeDefHandle in metadataReader.ExportedTypes) { var typeDef = metadataReader.GetExportedType(typeDefHandle); var ns = metadataReader.GetString(typeDef.Namespace); var name = metadataReader.GetString(typeDef.Name); yield return((ns.Length == 0) ? name : (ns + "." + name)); } }
private static string GetAssemblyName(MetadataReader reader, ExportedType type) { Debug.Assert(type.IsForwarder); if (type.Implementation.Kind == HandleKind.AssemblyReference) { return(reader.GetString(reader.GetAssemblyReference((AssemblyReferenceHandle)type.Implementation).Name)); } if (type.Implementation.Kind == HandleKind.ExportedType) { return(GetAssemblyName(reader, reader.GetExportedType((ExportedTypeHandle)type.Implementation))); } throw new NotSupportedException(type.Implementation.Kind.ToString()); }
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 static string GetTypeName(MetadataReader metaReader, ExportedType expTp) { string name = metaReader.GetString(expTp.Name); string ns = metaReader.GetString(expTp.Namespace); string id = string.IsNullOrEmpty(ns) ? name : $"{ns}.{name}"; if (expTp.Implementation.Kind == HandleKind.ExportedType) { // we need to get the type of the parent as well. return(GetTypeName(metaReader, metaReader.GetExportedType(((ExportedTypeHandle)expTp.Implementation))) + "." + id); } return(id); }
bool ModuleForwardsScopeType(MetadataReader metadata, string typeScopeName, string typeScopeNamespace) { bool hasForward = false; foreach (var h in metadata.ExportedTypes) { var exportedType = metadata.GetExportedType(h); if (exportedType.IsForwarder && metadata.StringComparer.Equals(exportedType.Name, typeScopeName) && metadata.StringComparer.Equals(exportedType.Namespace, typeScopeNamespace)) { hasForward = true; break; } } return(hasForward); }
public static FullTypeName GetFullTypeName(this ExportedType type, MetadataReader metadata) { string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(type.Name), out int typeParameterCount); if (type.Implementation.Kind == HandleKind.ExportedType) { var outerType = metadata.GetExportedType((ExportedTypeHandle)type.Implementation); return(outerType.GetFullTypeName(metadata).NestedType(name, typeParameterCount)); } else { string ns = type.Namespace.IsNil ? "" : metadata.GetString(type.Namespace); return(new TopLevelTypeName(ns, name, typeParameterCount)); } }
/// <summary> /// Get the full name of an ExportedType, including namespace /// </summary> private static string GetExportedTypeFullName(MetadataReader mdReader, ExportedTypeHandle handle) { string typeNamespace = ""; string typeStr = ""; try { ExportedType exportedType = mdReader.GetExportedType(handle); typeStr = "." + mdReader.GetString(exportedType.Name) + typeStr; typeNamespace = mdReader.GetString(exportedType.Namespace); } catch (BadImageFormatException) { return(null); } return(typeNamespace + typeStr); }
private static string GetFullName(MetadataReader reader, ExportedType type) { Debug.Assert(type.IsForwarder); if (type.Implementation.Kind == HandleKind.AssemblyReference) { var name = reader.GetString(type.Name); var ns = type.Namespace.IsNil ? null : reader.GetString(type.Namespace); var fullName = string.IsNullOrEmpty(ns) ? name : ns + "." + name; return(fullName); } if (type.Implementation.Kind == HandleKind.ExportedType) { var name = reader.GetString(type.Name); Debug.Assert(type.Namespace.IsNil); return(GetFullName(reader, reader.GetExportedType((ExportedTypeHandle)type.Implementation)) + "." + name); } throw new NotSupportedException(type.Implementation.Kind.ToString()); }
public string GetTypeForwards() { // Don't generate type forwards for netstandard if (this.ShortTfm.StartsWith("netstandard")) { return(""); } string result = ""; string typeForwardDecl = "[assembly: TypeForwardedTo(typeof({0}))]\n"; using (var fileStream = new FileStream(this.DllPath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read)) { try { using (PEReader pereader = new PEReader(fileStream, PEStreamOptions.LeaveOpen)) { if (pereader.HasMetadata) { MetadataReader reader = pereader.GetMetadataReader(); if (reader.IsAssembly) { foreach (var exportedTypeHandle in reader.ExportedTypes) { var exportedType = reader.GetExportedType(exportedTypeHandle); if (exportedType.IsForwarder) { var typeName = reader.GetString(exportedType.Name); var ns = reader.GetString(exportedType.Namespace); typeName = typeName == "Void" ? "void" : ns + "." + ConvertGeneric(typeName); result += string.Format(typeForwardDecl, typeName); } } } } } } catch (BadImageFormatException) { throw new ArgumentException($"Assembly {this.DllPath} has incorrect format", nameof(this.DllPath)); } } return(result); }
public List <string> GetAdditionalUsings() { List <string> result = new List <string>(); string usingDecl = "using {0};"; using (var fileStream = new FileStream(this.DllPath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read)) { try { using (PEReader pereader = new PEReader(fileStream, PEStreamOptions.LeaveOpen)) { if (pereader.HasMetadata) { MetadataReader reader = pereader.GetMetadataReader(); if (reader.IsAssembly) { foreach (var exportedTypeHandle in reader.ExportedTypes) { var exportedType = reader.GetExportedType(exportedTypeHandle); if (exportedType.IsForwarder) { result.Add(string.Format(usingDecl, reader.GetString(exportedType.Namespace))); } } } } } } catch (BadImageFormatException) { throw new ArgumentException($"Assembly {this.DllPath} has incorrect format", nameof(this.DllPath)); } } return(result); }
protected sealed override void IterateTypeForwards(TypeForwardHandler handler) { MetadataReader reader = Reader; foreach (ExportedTypeHandle exportedTypeHandle in reader.ExportedTypes) { ExportedType exportedType = reader.GetExportedType(exportedTypeHandle); if (!exportedType.IsForwarder) { continue; } EntityHandle implementation = exportedType.Implementation; if (implementation.Kind != HandleKind.AssemblyReference) // This check also weeds out nested types. This is intentional. { continue; } RoAssembly redirectedAssembly = ((AssemblyReferenceHandle)implementation).ResolveToAssemblyOrExceptionAssembly(GetEcmaManifestModule()); ReadOnlySpan <byte> ns = exportedType.Namespace.AsReadOnlySpan(reader); ReadOnlySpan <byte> name = exportedType.Name.AsReadOnlySpan(reader); handler(redirectedAssembly, ns, name); } }
/// <summary> /// Helper method that will validate that a NamespaceDefinition (and all NamespaceDefinitions considered children /// of it) report correct values for their child namespaces, types, etc. All namespaces in the module are expected /// to be listed in the allNamespaces array. Additionally, the global namespace is expected to have type definitions /// for GlobalClassA, GlobalClassB, and Module. No type forwarder declarations are expected. /// /// All namespaces that aren't the global NS are expected to have type definitions equal to the array /// @namespaceName.Split('.') /// So, ns1.Ns2.NS3 is expected to have type definitions /// {"ns1", "Ns2", "NS3"}. /// /// definitionExceptions and forwarderExceptions may be used to override the default expectations. Pass in /// namespace (key) and what is expected (list of strings) for each exception. /// </summary> private void ValidateNamespaceChildren( MetadataReader reader, NamespaceDefinitionHandle initHandle, string[] allNamespaces, IReadOnlyDictionary<string, IList<string>> definitionExceptions = null, IReadOnlyDictionary<string, IList<string>> forwarderExceptions = null) { // Don't want to have to deal with null. if (definitionExceptions == null) { definitionExceptions = new Dictionary<string, IList<string>>(); } if (forwarderExceptions == null) { forwarderExceptions = new Dictionary<string, IList<string>>(); } var rootNamespaceDefinition = reader.GetNamespaceDefinition(initHandle); string rootNamespaceName = reader.GetString(initHandle); // We need to be in the table of all namespaces... Assert.Contains(rootNamespaceName, allNamespaces); // Cool. Now check to make sure that .Name only returns the last bit of our namespace name. var expNamespaceNameSegment = rootNamespaceName.Split('.').Last(); var rootNamespaceNameSegment = reader.GetString(rootNamespaceDefinition.Name); Assert.Equal(expNamespaceNameSegment, rootNamespaceNameSegment); bool isGlobalNamespace = rootNamespaceName.Length == 0; string[] expTypeDefinitions = null; // Special case: Global NS has GlobalClassA, GlobalClassB. Others just have autogenerated classes. if (definitionExceptions.ContainsKey(rootNamespaceName)) { expTypeDefinitions = definitionExceptions[rootNamespaceName].ToArray(); } else if (isGlobalNamespace) { expTypeDefinitions = new[] { "GlobalClassA", "GlobalClassB", "<Module>" }; } else { expTypeDefinitions = rootNamespaceName.Split('.'); } // Validating type definitions inside the namespace... int numberOfTypeDefinitions = 0; foreach (var definitionHandle in rootNamespaceDefinition.TypeDefinitions) { var definition = reader.GetTypeDefinition(definitionHandle); var definitionName = reader.GetString(definition.Name); var definitionFullNamespaceName = reader.GetString(definition.Namespace); Assert.Equal(rootNamespaceName, definitionFullNamespaceName); Assert.Contains(definitionName, expTypeDefinitions); numberOfTypeDefinitions += 1; } // Guarantee that there are no extra unexpected members... Assert.Equal(numberOfTypeDefinitions, expTypeDefinitions.Length); string[] expTypeForwarders = null; if (forwarderExceptions.ContainsKey(rootNamespaceName)) { expTypeForwarders = forwarderExceptions[rootNamespaceName].ToArray(); } else { expTypeForwarders = new string[] { }; } int numberOfTypeForwarders = 0; foreach (var forwarderHandle in rootNamespaceDefinition.ExportedTypes) { var forwarder = reader.GetExportedType(forwarderHandle); Assert.True(reader.StringComparer.Equals(forwarder.Namespace, rootNamespaceName)); var forwarderName = reader.GetString(forwarder.Name); Assert.Contains(forwarderName, expTypeForwarders); numberOfTypeForwarders += 1; } Assert.Equal(expTypeForwarders.Length, numberOfTypeForwarders); // Validate sub-namespaces // If the last index of '.' in a namespace name is == the current name's length, then // that ns is a direct child of the current one! IList<String> expChildren = null; // Special case: Global NS's children won't have .s in them. if (isGlobalNamespace) { expChildren = allNamespaces.Where(ns => !String.IsNullOrEmpty(ns) && !ns.Contains('.')).ToList(); } else { expChildren = allNamespaces .Where(ns => ns.StartsWith(rootNamespaceName) && ns.LastIndexOf('.') == rootNamespaceName.Length) .ToList(); } int numberOfSubNamespaces = 0; foreach (var subNamespaceHandle in rootNamespaceDefinition.NamespaceDefinitions) { Assert.False(subNamespaceHandle.IsNil); string subNamespaceFullName = reader.GetString(subNamespaceHandle); NamespaceDefinition subNamespace = reader.GetNamespaceDefinition(subNamespaceHandle); string subNamespaceName = subNamespaceFullName.Split('.').Last(); Assert.Equal(subNamespaceName, reader.GetString(subNamespace.Name)); Assert.True(reader.StringComparer.Equals(subNamespace.Name, subNamespaceName)); Assert.True(reader.StringComparer.StartsWith(subNamespace.Name, subNamespaceName)); Assert.True(reader.StringComparer.StartsWith(subNamespace.Name, subNamespaceName.Substring(0, subNamespaceName.Length - 1))); Assert.Equal(subNamespace.Parent, initHandle); Assert.Contains(subNamespaceFullName, expChildren); ValidateNamespaceChildren(reader, subNamespaceHandle, allNamespaces, definitionExceptions, forwarderExceptions); numberOfSubNamespaces += 1; } // Guarantee no extra unexpected namespaces... Assert.Equal(expChildren.Count, numberOfSubNamespaces); }
public sealed override MetadataType GetType(string nameSpace, string name, NotFoundBehavior notFoundBehavior) { var stringComparer = _metadataReader.StringComparer; // TODO: More efficient implementation? foreach (var typeDefinitionHandle in _metadataReader.TypeDefinitions) { var typeDefinition = _metadataReader.GetTypeDefinition(typeDefinitionHandle); if (stringComparer.Equals(typeDefinition.Name, name) && stringComparer.Equals(typeDefinition.Namespace, nameSpace)) { return((MetadataType)GetType((EntityHandle)typeDefinitionHandle)); } } foreach (var exportedTypeHandle in _metadataReader.ExportedTypes) { var exportedType = _metadataReader.GetExportedType(exportedTypeHandle); if (stringComparer.Equals(exportedType.Name, name) && stringComparer.Equals(exportedType.Namespace, nameSpace)) { if (exportedType.IsForwarder) { Object implementation = GetObject(exportedType.Implementation, notFoundBehavior); if (implementation == null) { return(null); } if (implementation is ModuleDesc) { return(((ModuleDesc)(implementation)).GetType(nameSpace, name)); } else if (implementation is ResolutionFailure failure) { ModuleDesc.GetTypeResolutionFailure = failure; return(null); } // TODO throw new NotImplementedException(); } // TODO: throw new NotImplementedException(); } } if (notFoundBehavior != NotFoundBehavior.ReturnNull) { var failure = ResolutionFailure.GetTypeLoadResolutionFailure(nameSpace, name, this); if (notFoundBehavior == NotFoundBehavior.Throw) { failure.Throw(); } ModuleDesc.GetTypeResolutionFailure = failure; return(null); } return(null); }
public static ExportedType GetExportedType(this ExportedTypeHandle handle, MetadataReader reader) => reader.GetExportedType(handle);
public static string ToString(this MetadataReader reader, ExportedTypeHandle x) => reader.ToString(reader.GetExportedType(x));