diff --git a/docs/guides/dotnet/importing.md b/docs/guides/dotnet/importing.md index e9cc3a14b..c12780c72 100644 --- a/docs/guides/dotnet/importing.md +++ b/docs/guides/dotnet/importing.md @@ -1,55 +1,119 @@ -# Reference Importing +# References to External Metadata -.NET modules use entries in the TypeRef or MemberRef tables to reference -types or members from external assemblies. Importing references into the -current module, therefore, form a key role when creating new- or -modifying existing .NET modules. When a member is not imported into the -current module, a `MemberNotImportedException` will be thrown when you -are trying to create a PE image or write the module to the disk. +Next to metadata symbols defined in the current module (see [The Member Tree](./member-tree.md)), .NET modules can also reference metadata defined in external assemblies using the `AssemblyRef`, `TypeRef` and `MemberRef` tables. +Thus, when you want to use a type, field or method defined in a different assembly, it is required to turn these definitions into the appropriate references first. -AsmResolver provides the `ReferenceImporter` class that does most of the -heavy lifting. Obtaining an instance of `ReferenceImporter` can be done -in two ways. +Below an overview of how AsmResolver represents definitions and their corresponding reference type. -Either instantiate one yourself: +| Definition | Reference | +|----------------------|--------------------------------------------| +| `AssemblyDefinition` | `AssemblyReference` | +| `TypeDefinition` | `TypeReference` | +| `MethodDefinition` | `MemberReference` with a `MethodSignature` | +| `FieldDefinition` | `MemberReference` with a `FieldSignature` | + +> [!NOTE] +> While there also exists both a `ModuleDefinition` and `ModuleReference`, these two are unrelated. `ModuleDefinition` defines a module in a .NET assembly manifest, while `ModuleReference` is used to reference native modules such as `kernel32.dll` or `libc.so` + + +## Resolution scopes + +The root scope of any external reference is an `IResolutionScope`. + +Typically, resolution scopes are references to external assemblies, which are represented by an `AssemblyReference`. +All assemblies imported by a module are stored in `ModuleDefinition::AssemblyReferences`: + +```csharp +ModuleDefinition module = ...; +foreach (var assembly in module.AssemblyReferences) + Console.WriteLine(assembly); +``` + +You can add new `AssemblyReference`s to this list, but the preferred way of adding a new assembly reference to is by using an importer: + +```csharp +ModuleDefinition module = ...; +var systemConsole = new AssemblyReference( + "System.Console", + new Version(8, 0, 0, 0) + ).ImportWith(module.DefaultImporter); +``` + +You can also import existing `AssemblyDefinition`s and turn them into `AssemblyReference`s: + +```csharp +ModuleDefinition module = ...; +AssemblyDefinition otherAssembly = ...; +var otherAssemblyRef = otherAssembly.ImportWith(module.DefaultImporter); +``` + +`ModuleDefinition` also provides a default corlib assembly scope that the module targets: + +```csharp +ModuleDefinition module = ...; +var corlib = module.CorLibTypeFactory.CorLibScope; +``` + +In most cases this will return an `AssemblyReference` to either `mscorlib`, `netstandard`, `System.Runtime` or `System.Private.Corlib`. +In case `module` is a corlib assembly itself, it will reference itself instead. + + +## Type and member references + +Similar to assembly references, external types and members are represented using `TypeReference` and +`MemberReference`. + +To create new references, use the fluent factory methods `CreateTypeReference` and `CreateMemberReference` on any `IResolutionScope` or `ITypeDescriptor`. +Below is an example of how to create a fully imported reference to +`void System.Console.WriteLine(string)`: + +``` csharp +var method = factory.CorLibScope + .CreateTypeReference("System", "Console") + .CreateMemberReference("WriteLine", MethodSignature.CreateStatic( + factory.Void, factory.String)); + +// importedMethod now references "void System.Console.WriteLine(string)" +``` + +Generic type instantiations can also be created using +`MakeGenericInstanceType`: ``` csharp ModuleDefinition module = ... -var importer = new ReferenceImporter(module); + +var factory = module.CorLibTypeFactory; +var importedMethod = factory.CorLibScope + .CreateTypeReference("System.Collections.Generic", "List`1") + .MakeGenericInstanceType(factory.Int32) + .ToTypeDefOrRef() + .CreateMemberReference("Add", MethodSignature.CreateInstance( + factory.Void, + new GenericParameterSignature(GenericParameterType.Type, 0))); + +// importedMethod now references "System.Collections.Generic.List`1.Add(!0)" ``` -Or obtain the default instance that comes with every `ModuleDefinition` -object. This avoids allocating new reference importers every time. +Similarly, generic method instantiations can be constructed using +`MakeGenericInstanceMethod`: ``` csharp ModuleDefinition module = ... -var importer = module.DefaultImporter; + +var factory = module.CorLibTypeFactory; +var importedMethod = factory.CorLibScope + .CreateTypeReference("System", "Array") + .CreateMemberReference("Empty", MethodSignature.CreateStatic( + new GenericParameterSignature(GenericParameterType.Method, 0).MakeSzArrayType(), 1)) + .MakeGenericInstanceMethod(factory.String); + +// importedMethod now references "!0[] System.Array.Empty()" ``` -The example snippets that will follow in this article assume that there -is such a `ReferenceImporter` object instantiated using either of these -two methods, and is stored in an `importer` variable. - -## Importing existing members - -Metadata members from external modules can be imported using the -`ReferenceImporter` class using one of the following members: - -|Member type to import |Method to use | Result type | -|----------------------|----------------| ---------------------| -|`IResolutionScope` |`ImportScope` | `IResolutionScope` | -|`AssemblyReference` |`ImportScope` | `IResolutionScope` | -|`AssemblyDefinition` |`ImportScope` | `IResolutionScope` | -|`ModuleReference` |`ImportScope` | `IResolutionScope` | -|`ITypeDefOrRef` |`ImportType` | `ITypeDefOrRef` | -|`TypeDefinition` |`ImportType` | `ITypeDefOrRef` | -|`TypeReference` |`ImportType` | `ITypeDefOrRef` | -|`TypeSpecification` |`ImportType` | `ITypeDefOrRef` | -|`IMethodDefOrRef` |`ImportMethod` | `IMethodDefOrRef` | -|`MethodDefinition` |`ImportMethod` | `IMethodDefOrRef` | -|`MethodSpecification` |`ImportMethod` | `IMethodDefOrRef` | -|`IFieldDescriptor` |`ImportField` | `IFieldDescriptor` | -|`FieldDefinition` |`ImportField` | `IFieldDescriptor` | + +## Importing existing metadata definitions + +References to existing metadata definitions can also be automatically converted to their appropriate reference type using an importer. Below an example of how to import a type definition called `SomeType`: @@ -60,8 +124,8 @@ TypeDefinition typeToImport = externalModule.TopLevelTypes.First(t => t.Name == ITypeDefOrRef importedType = importer.ImportType(typeToImport); ``` -These types also implement the `IImportable` interface. This means you -can also use the `member.ImportWith` method instead: +Most metadata definitions also implement the `IImportable` interface. +This means you can also use the `member.ImportWith` method instead: ``` csharp ModuleDefinition externalModule = ModuleDefinition.FromFile(...); @@ -70,9 +134,10 @@ TypeDefinition typeToImport = externalModule.TopLevelTypes.First(t => t.Name == ITypeDefOrRef importedType = typeToImport.ImportWith(importer); ``` + ## Importing existing type signatures -Type signatures can also be imported using the `ReferenceImporter` +Type signatures can also be imported using a reference importer. class, but these should be imported using the `ImportTypeSignature` method instead. @@ -119,62 +184,6 @@ imported through reflection include: Instantiations of generic methods are also supported. -## Creating new references - -Member references can also be created and imported without having direct -access to its member definition or `System.Reflection` instance. It is -possible to create new instances of `TypeReference` and -`MemberReference` using the constructors, but the preferred way is to -use the factory methods that allow for a more fluent syntax. Below is an -example of how to create a fully imported reference to -`void System.Console.WriteLine(string)`: - -``` csharp -var factory = module.CorLibTypeFactory; -var importedMethod = factory.CorLibScope - .CreateTypeReference("System", "Console") - .CreateMemberReference("WriteLine", MethodSignature.CreateStatic( - factory.Void, factory.String)) - .ImportWith(importer); - -// importedMethod now references "void System.Console.WriteLine(string)" -``` - -Generic type instantiations can also be created using -`MakeGenericInstanceType`: - -``` csharp -ModuleDefinition module = ... - -var factory = module.CorLibTypeFactory; -var importedMethod = factory.CorLibScope - .CreateTypeReference("System.Collections.Generic", "List`1") - .MakeGenericInstanceType(factory.Int32) - .ToTypeDefOrRef() - .CreateMemberReference("Add", MethodSignature.CreateInstance( - factory.Void, - new GenericParameterSignature(GenericParameterType.Type, 0))) - .ImportWith(importer); - -// importedMethod now references "System.Collections.Generic.List`1.Add(!0)" -``` - -Similarly, generic method instantiations can be constructed using -`MakeGenericInstanceMethod`: - -``` csharp -ModuleDefinition module = ... - -var factory = module.CorLibTypeFactory; -var importedMethod = factory.CorLibScope - .CreateTypeReference("System", "Array") - .CreateMemberReference("Empty", MethodSignature.CreateStatic( - new GenericParameterSignature(GenericParameterType.Method, 0).MakeSzArrayType(), 1)) - .MakeGenericInstanceMethod(factory.String) - .ImportWith(importer); - -// importedMethod now references "!0[] System.Array.Empty()" -``` ## Common Caveats using the Importer diff --git a/src/AsmResolver.DotNet.Dynamic/DynamicMethodDefinition.cs b/src/AsmResolver.DotNet.Dynamic/DynamicMethodDefinition.cs index 549409b1f..9136bc8b5 100644 --- a/src/AsmResolver.DotNet.Dynamic/DynamicMethodDefinition.cs +++ b/src/AsmResolver.DotNet.Dynamic/DynamicMethodDefinition.cs @@ -32,7 +32,7 @@ public DynamicMethodDefinition(ModuleDefinition module, object dynamicMethodObj) "Could not get the underlying method base in the provided dynamic method object."); } - Module = module; + DeclaringModule = module; Name = methodBase.Name; Attributes = (MethodAttributes)methodBase.Attributes; Signature = module.DefaultImporter.ImportMethodSignature(ResolveSig(methodBase, module)); @@ -45,7 +45,7 @@ public DynamicMethodDefinition(ModuleDefinition module, object dynamicMethodObj) public static bool IsSupported => DynamicTypeSignatureResolver.IsSupported; /// - public override ModuleDefinition Module { get; } + public override ModuleDefinition DeclaringModule { get; } private MethodSignature ResolveSig(MethodBase methodBase, ModuleDefinition module) { @@ -73,7 +73,7 @@ private MethodSignature ResolveSig(MethodBase methodBase, ModuleDefinition modul /// The method body. private static CilMethodBody CreateDynamicMethodBody(DynamicMethodDefinition method, object dynamicMethodObj) { - if (method.Module is not SerializedModuleDefinition module) + if (method.DeclaringModule is not SerializedModuleDefinition module) throw new ArgumentException("Method body should reference a serialized module."); var result = new CilMethodBody(); diff --git a/src/AsmResolver.DotNet.Dynamic/DynamicMethodHelper.cs b/src/AsmResolver.DotNet.Dynamic/DynamicMethodHelper.cs index ea0bbab4d..3a56ccf13 100644 --- a/src/AsmResolver.DotNet.Dynamic/DynamicMethodHelper.cs +++ b/src/AsmResolver.DotNet.Dynamic/DynamicMethodHelper.cs @@ -15,7 +15,7 @@ internal static class DynamicMethodHelper { public static void ReadLocalVariables(CilMethodBody methodBody, MethodDefinition method, byte[] localSig) { - if (method.Module is not SerializedModuleDefinition module) + if (method.DeclaringModule is not SerializedModuleDefinition module) throw new ArgumentException("Method body should reference a serialized module."); var reader = new BinaryStreamReader(localSig); diff --git a/src/AsmResolver.DotNet/AssemblyDefinition.cs b/src/AsmResolver.DotNet/AssemblyDefinition.cs index 9e2be3aef..8b24c3c9b 100644 --- a/src/AsmResolver.DotNet/AssemblyDefinition.cs +++ b/src/AsmResolver.DotNet/AssemblyDefinition.cs @@ -188,7 +188,9 @@ public AssemblyHashAlgorithm HashAlgorithm /// public ModuleDefinition? ManifestModule => Modules.Count > 0 ? Modules[0] : null; - ModuleDefinition? IModuleProvider.Module => ManifestModule; + ModuleDefinition? IMetadataDefinition.DeclaringModule => ManifestModule; + + ModuleDefinition? IModuleProvider.ContextModule => ManifestModule; /// /// Gets a collection of modules that this .NET assembly defines. diff --git a/src/AsmResolver.DotNet/AssemblyReference.cs b/src/AsmResolver.DotNet/AssemblyReference.cs index c50eae927..648578c91 100644 --- a/src/AsmResolver.DotNet/AssemblyReference.cs +++ b/src/AsmResolver.DotNet/AssemblyReference.cs @@ -1,5 +1,4 @@ using System; -using System.Threading; using AsmResolver.Collections; using AsmResolver.PE.DotNet.Metadata.Tables; @@ -81,7 +80,7 @@ public AssemblyReference(AssemblyDescriptor descriptor) } /// - public ModuleDefinition? Module + public ModuleDefinition? ContextModule { get; private set; @@ -90,8 +89,8 @@ public ModuleDefinition? Module /// ModuleDefinition? IOwnedCollectionElement.Owner { - get => Module; - set => Module = value; + get => ContextModule; + set => ContextModule = value; } /// @@ -159,14 +158,14 @@ public byte[]? HashValue protected virtual byte[]? GetHashValue() => null; /// - public override bool IsImportedInModule(ModuleDefinition module) => Module == module; + public override bool IsImportedInModule(ModuleDefinition module) => ContextModule == module; /// public override AssemblyReference ImportWith(ReferenceImporter importer) => (AssemblyReference) importer.ImportScope(this); /// - public override AssemblyDefinition? Resolve() => Module?.MetadataResolver.AssemblyResolver.Resolve(this); + public override AssemblyDefinition? Resolve() => ContextModule?.MetadataResolver.AssemblyResolver.Resolve(this); AssemblyDescriptor IResolutionScope.GetAssembly() => this; } diff --git a/src/AsmResolver.DotNet/Builder/Discovery/MemberDiscoverer.cs b/src/AsmResolver.DotNet/Builder/Discovery/MemberDiscoverer.cs index 41317a332..9c101b337 100644 --- a/src/AsmResolver.DotNet/Builder/Discovery/MemberDiscoverer.cs +++ b/src/AsmResolver.DotNet/Builder/Discovery/MemberDiscoverer.cs @@ -154,7 +154,7 @@ private void CollectMembersFromTable(TableIndex tableIndex) var token = new MetadataToken(tableIndex, rid); var definition = (TMember) _module.LookupMember(token); - if (definition.Module == _module) + if (definition.ContextModule == _module) { // Member is still present in the module. resultingList.Add(definition); diff --git a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.CodedIndices.cs b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.CodedIndices.cs index 17bc8380c..6e23f88f6 100644 --- a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.CodedIndices.cs +++ b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.CodedIndices.cs @@ -32,13 +32,13 @@ private void AddCustomAttribute(MetadataToken ownerToken, CustomAttribute attrib private uint AddResolutionScope(IResolutionScope? scope, bool allowDuplicates, bool preserveRid, object? diagnosticSource = null) { - if (!AssertIsImported(scope, diagnosticSource)) + if (scope is null) return 0; var token = scope.MetadataToken.Table switch { TableIndex.AssemblyRef => AddAssemblyReference(scope as AssemblyReference, allowDuplicates, preserveRid, diagnosticSource), - TableIndex.TypeRef => AddTypeReference(scope as TypeReference, allowDuplicates, preserveRid, diagnosticSource), + TableIndex.TypeRef => AddTypeReference(scope as TypeReference, allowDuplicates, preserveRid), TableIndex.ModuleRef => AddModuleReference(scope as ModuleReference, allowDuplicates, preserveRid, diagnosticSource), TableIndex.Module => new MetadataToken(TableIndex.Module, 1), _ => throw new ArgumentOutOfRangeException(nameof(scope)) @@ -52,7 +52,7 @@ private uint AddResolutionScope(IResolutionScope? scope, bool allowDuplicates, b /// public uint GetTypeDefOrRefIndex(ITypeDefOrRef? type, object? diagnosticSource = null) { - if (!AssertIsImported(type, diagnosticSource)) + if (type is null) return 0; var token = type.MetadataToken.Table switch @@ -70,7 +70,7 @@ public uint GetTypeDefOrRefIndex(ITypeDefOrRef? type, object? diagnosticSource = private uint AddMemberRefParent(IMemberRefParent? parent, object? diagnosticSource = null) { - if (!AssertIsImported(parent, diagnosticSource)) + if (parent is null) return 0; var token = parent.MetadataToken.Table switch @@ -90,7 +90,7 @@ private uint AddMemberRefParent(IMemberRefParent? parent, object? diagnosticSour private uint AddMethodDefOrRef(IMethodDefOrRef? method, object? diagnosticSource = null) { - if (!AssertIsImported(method, diagnosticSource)) + if (method is null) return 0; var token = method.MetadataToken.Table switch @@ -107,7 +107,7 @@ private uint AddMethodDefOrRef(IMethodDefOrRef? method, object? diagnosticSource private uint AddCustomAttributeType(ICustomAttributeType? constructor, object? diagnosticSource = null) { - if (!AssertIsImported(constructor, diagnosticSource)) + if (constructor is null) return 0; var token = constructor.MetadataToken.Table switch @@ -157,14 +157,14 @@ private void AddImplementationMap(MetadataToken ownerToken, ImplementationMap? i private uint AddImplementation(IImplementation? implementation, object? diagnosticSource = null) { - if (implementation is null || !AssertIsImported(implementation, diagnosticSource)) + if (implementation is null) return 0; var token = implementation switch { AssemblyReference assemblyReference => GetAssemblyReferenceToken(assemblyReference, diagnosticSource), - ExportedType exportedType => AddExportedType(exportedType, diagnosticSource), - FileReference fileReference => AddFileReference(fileReference, diagnosticSource), + ExportedType exportedType => AddExportedType(exportedType), + FileReference fileReference => AddFileReference(fileReference), _ => throw new ArgumentOutOfRangeException(nameof(implementation)) }; diff --git a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.MemberTree.cs b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.MemberTree.cs index b078d4b48..57d08e9db 100644 --- a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.MemberTree.cs +++ b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.MemberTree.cs @@ -629,14 +629,11 @@ private void AddFieldLayout(MetadataToken ownerToken, FieldDefinition field) private void AddExportedTypesInModule(ModuleDefinition module) { for (int i = 0; i < module.ExportedTypes.Count; i++) - AddExportedType(module.ExportedTypes[i], module); + AddExportedType(module.ExportedTypes[i]); } - private MetadataToken AddExportedType(ExportedType exportedType, object? diagnosticSource = null) + private MetadataToken AddExportedType(ExportedType exportedType) { - if (!AssertIsImported(exportedType, diagnosticSource)) - return MetadataToken.Zero; - var table = Metadata.TablesStream.GetTable(TableIndex.ExportedType); var row = new ExportedTypeRow( @@ -656,14 +653,11 @@ private MetadataToken AddExportedType(ExportedType exportedType, object? diagnos private void AddFileReferencesInModule(ModuleDefinition module) { for (int i = 0; i < module.FileReferences.Count; i++) - AddFileReference(module.FileReferences[i], module); + AddFileReference(module.FileReferences[i]); } - private MetadataToken AddFileReference(FileReference fileReference, object? diagnosticSource = null) + private MetadataToken AddFileReference(FileReference fileReference) { - if (!AssertIsImported(fileReference, diagnosticSource)) - return MetadataToken.Zero; - var table = Metadata.TablesStream.GetTable(TableIndex.File); var row = new FileReferenceRow( diff --git a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.TokenProvider.cs b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.TokenProvider.cs index 46471dab4..978aae068 100644 --- a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.TokenProvider.cs +++ b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.TokenProvider.cs @@ -11,7 +11,7 @@ public partial class DotNetDirectoryBuffer : IMetadataTokenProvider /// public MetadataToken GetTypeReferenceToken(TypeReference? type, object? diagnosticSource = null) { - return AddTypeReference(type, false, false, diagnosticSource); + return AddTypeReference(type, false, false); } /// @@ -25,18 +25,18 @@ public MetadataToken GetTypeReferenceToken(TypeReference? type, object? diagnost /// /// true if the metadata token of the type should be preserved, false otherwise. /// - /// The object that referenced the type. /// The newly assigned metadata token. - public MetadataToken AddTypeReference(TypeReference? type, bool allowDuplicates, bool preserveRid, object? diagnosticSource = null) + public MetadataToken AddTypeReference(TypeReference? type, bool allowDuplicates, bool preserveRid) { - if (!AssertIsImported(type, diagnosticSource)) + if (type is null) return MetadataToken.Zero; var table = Metadata.TablesStream.GetDistinctTable(TableIndex.TypeRef); var row = new TypeReferenceRow( AddResolutionScope(type.Scope, allowDuplicates, preserveRid, type), Metadata.StringsStream.GetStringIndex(type.Name), - Metadata.StringsStream.GetStringIndex(type.Namespace)); + Metadata.StringsStream.GetStringIndex(type.Namespace) + ); var token = preserveRid && type.MetadataToken.Rid != 0 ? table.Insert(type.MetadataToken.Rid, row, allowDuplicates) @@ -50,7 +50,7 @@ public MetadataToken AddTypeReference(TypeReference? type, bool allowDuplicates, /// public MetadataToken GetTypeDefinitionToken(TypeDefinition? type, object? diagnosticSource = null) { - return AssertIsImported(type, diagnosticSource) + return AssertIsInSameModule(type, diagnosticSource) ? _tokenMapping[type] : MetadataToken.Zero; } @@ -58,7 +58,7 @@ public MetadataToken GetTypeDefinitionToken(TypeDefinition? type, object? diagno /// public MetadataToken GetFieldDefinitionToken(FieldDefinition? field, object? diagnosticSource = null) { - return AssertIsImported(field, diagnosticSource) + return AssertIsInSameModule(field, diagnosticSource) ? _tokenMapping[field] : MetadataToken.Zero; } @@ -66,7 +66,7 @@ public MetadataToken GetFieldDefinitionToken(FieldDefinition? field, object? dia /// public MetadataToken GetMethodDefinitionToken(MethodDefinition? method, object? diagnosticSource = null) { - return AssertIsImported(method, diagnosticSource) + return AssertIsInSameModule(method, diagnosticSource) ? _tokenMapping[method] : MetadataToken.Zero; } @@ -79,7 +79,7 @@ public MetadataToken GetMethodDefinitionToken(MethodDefinition? method, object? /// The metadata token of the added parameter definition. public MetadataToken GetParameterDefinitionToken(ParameterDefinition? parameter) { - return AssertIsImported(parameter, parameter?.Method) + return AssertIsInSameModule(parameter, parameter?.Method) ? _tokenMapping[parameter] : MetadataToken.Zero; } @@ -91,7 +91,7 @@ public MetadataToken GetParameterDefinitionToken(ParameterDefinition? parameter) /// The metadata token of the added property definition. public MetadataToken GetPropertyDefinitionToken(PropertyDefinition? property) { - return AssertIsImported(property, property?.DeclaringType) + return AssertIsInSameModule(property, property?.DeclaringType) ? _tokenMapping[property] : MetadataToken.Zero; } @@ -103,7 +103,7 @@ public MetadataToken GetPropertyDefinitionToken(PropertyDefinition? property) /// The metadata token of the added event definition. public MetadataToken GetEventDefinitionToken(EventDefinition? @event) { - return AssertIsImported(@event, @event?.DeclaringType) + return AssertIsInSameModule(@event, @event?.DeclaringType) ? _tokenMapping[@event] : MetadataToken.Zero; } @@ -126,14 +126,15 @@ public MetadataToken GetMemberReferenceToken(MemberReference? member, object? di /// The newly assigned metadata token. public MetadataToken AddMemberReference(MemberReference? member, bool allowDuplicates, object? diagnosticSource = null) { - if (!AssertIsImported(member, diagnosticSource)) + if (member is null) return MetadataToken.Zero; var table = Metadata.TablesStream.GetDistinctTable(TableIndex.MemberRef); var row = new MemberReferenceRow( AddMemberRefParent(member.Parent, member), Metadata.StringsStream.GetStringIndex(member.Name), - Metadata.BlobStream.GetBlobIndex(this, member.Signature, ErrorListener, diagnosticSource)); + Metadata.BlobStream.GetBlobIndex(this, member.Signature, ErrorListener, diagnosticSource) + ); var token = table.Add(row, allowDuplicates); _tokenMapping.Register(member, token); @@ -164,7 +165,8 @@ public MetadataToken AddStandAloneSignature(StandAloneSignature? signature, bool var table = Metadata.TablesStream.GetDistinctTable(TableIndex.StandAloneSig); var row = new StandAloneSignatureRow( - Metadata.BlobStream.GetBlobIndex(this, signature.Signature, ErrorListener, diagnosticSource)); + Metadata.BlobStream.GetBlobIndex(this, signature.Signature, ErrorListener, diagnosticSource) + ); var token = table.Add(row, allowDuplicates); _tokenMapping.Register(signature, token); @@ -193,12 +195,13 @@ public MetadataToken GetAssemblyReferenceToken(AssemblyReference? assembly, obje /// The newly assigned metadata token. public MetadataToken AddAssemblyReference(AssemblyReference? assembly, bool allowDuplicates, bool preserveRid, object? diagnosticSource = null) { - if (assembly is null || !AssertIsImported(assembly, diagnosticSource)) + if (assembly is null) return MetadataToken.Zero; var table = Metadata.TablesStream.GetDistinctTable(TableIndex.AssemblyRef); - var row = new AssemblyReferenceRow((ushort) assembly.Version.Major, + var row = new AssemblyReferenceRow( + (ushort) assembly.Version.Major, (ushort) assembly.Version.Minor, (ushort) assembly.Version.Build, (ushort) assembly.Version.Revision, @@ -206,7 +209,8 @@ public MetadataToken AddAssemblyReference(AssemblyReference? assembly, bool allo Metadata.BlobStream.GetBlobIndex(assembly.PublicKeyOrToken), Metadata.StringsStream.GetStringIndex(assembly.Name), Metadata.StringsStream.GetStringIndex(assembly.Culture), - Metadata.BlobStream.GetBlobIndex(assembly.HashValue)); + Metadata.BlobStream.GetBlobIndex(assembly.HashValue) + ); var token = preserveRid && assembly.MetadataToken.Rid != 0 ? table.Insert(assembly.MetadataToken.Rid, row, allowDuplicates) @@ -230,7 +234,7 @@ public MetadataToken GetModuleReferenceToken(ModuleReference? reference, object? /// /// Adds a module reference to the buffer. /// - /// The reference to add. + /// The reference to add. /// /// true if the row is always to be added to the end of the buffer, false if a duplicated row /// is supposed to be removed and the token of the original should be returned instead. @@ -240,19 +244,19 @@ public MetadataToken GetModuleReferenceToken(ModuleReference? reference, object? /// /// The object that referenced the module. /// The newly assigned metadata token. - public MetadataToken AddModuleReference(ModuleReference? reference, bool allowDuplicates, bool preserveRid, object? diagnosticSource = null) + public MetadataToken AddModuleReference(ModuleReference? module, bool allowDuplicates, bool preserveRid, object? diagnosticSource = null) { - if (!AssertIsImported(reference, diagnosticSource)) + if (module is null) return MetadataToken.Zero; var table = Metadata.TablesStream.GetDistinctTable(TableIndex.ModuleRef); - var row = new ModuleReferenceRow(Metadata.StringsStream.GetStringIndex(reference.Name)); - var token = preserveRid && reference.MetadataToken.Rid != 0 - ? table.Insert(reference.MetadataToken.Rid, row, allowDuplicates) + var row = new ModuleReferenceRow(Metadata.StringsStream.GetStringIndex(module.Name)); + var token = preserveRid && module.MetadataToken.Rid != 0 + ? table.Insert(module.MetadataToken.Rid, row, allowDuplicates) : table.Add(row, allowDuplicates); - AddCustomAttributes(token, reference); + AddCustomAttributes(token, module); return token; } @@ -274,7 +278,7 @@ public MetadataToken GetTypeSpecificationToken(TypeSpecification? type, object? /// The newly assigned metadata token. public MetadataToken AddTypeSpecification(TypeSpecification? type, bool allowDuplicates, object? diagnosticSource = null) { - if (!AssertIsImported(type, diagnosticSource)) + if (type is null) return MetadataToken.Zero; var table = Metadata.TablesStream.GetDistinctTable(TableIndex.TypeSpec); @@ -306,7 +310,7 @@ public MetadataToken GetMethodSpecificationToken(MethodSpecification? method, ob /// The newly assigned metadata token. public MetadataToken AddMethodSpecification(MethodSpecification? method, bool allowDuplicates, object? diagnosticSource = null) { - if (!AssertIsImported(method, diagnosticSource)) + if (method is null) return MetadataToken.Zero; var table = Metadata.TablesStream.GetDistinctTable(TableIndex.MethodSpec); diff --git a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.cs b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.cs index 2f345cd68..094ed6cfc 100644 --- a/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.cs +++ b/src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.cs @@ -110,12 +110,12 @@ public VTableFixupsBuffer VTableFixups get; } - private bool AssertIsImported([NotNullWhen(true)] IModuleProvider? member, object? diagnosticSource) + private bool AssertIsInSameModule([NotNullWhen(true)] IModuleProvider? member, object? diagnosticSource) { if (member is null) return false; - if (member.Module != Module) + if (member.ContextModule != Module) { ErrorListener.RegisterException(new MemberNotImportedException((IMetadataMember) member, diagnosticSource)); return false; @@ -164,7 +164,7 @@ private DotNetEntryPoint GetEntryPoint() break; case TableIndex.File: - entryPointToken = AddFileReference((FileReference) Module.ManagedEntryPoint, Module); + entryPointToken = AddFileReference((FileReference) Module.ManagedEntryPoint); break; default: @@ -233,9 +233,6 @@ private void DefineGenericParameters(MetadataToken ownerToken, IHasGenericParame private void DefineGenericParameter(MetadataToken ownerToken, GenericParameter parameter) { - if (!AssertIsImported(parameter, parameter.Owner)) - return; - var table = Metadata.TablesStream.GetSortedTable(TableIndex.GenericParam); var encoder = Metadata.TablesStream.GetIndexEncoder(CodedIndex.TypeOrMethodDef); diff --git a/src/AsmResolver.DotNet/Code/Cil/CilMethodBody.cs b/src/AsmResolver.DotNet/Code/Cil/CilMethodBody.cs index e79a55cc0..482f93313 100644 --- a/src/AsmResolver.DotNet/Code/Cil/CilMethodBody.cs +++ b/src/AsmResolver.DotNet/Code/Cil/CilMethodBody.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Runtime.CompilerServices; using AsmResolver.DotNet.Serialized; using AsmResolver.DotNet.Signatures; using AsmResolver.IO; @@ -233,7 +232,7 @@ private static void ReadExceptionHandlers( while (reader.CanRead(size)) { - var handler = CilExceptionHandler.FromReader(method.Module!, result, ref reader, section.IsFat); + var handler = CilExceptionHandler.FromReader(method.DeclaringModule!, result, ref reader, section.IsFat); result.ExceptionHandlers.Add(handler); } } diff --git a/src/AsmResolver.DotNet/Code/Cil/OriginalMetadataTokenProvider.cs b/src/AsmResolver.DotNet/Code/Cil/OriginalMetadataTokenProvider.cs index c8333f0c1..8bb2dd3ee 100644 --- a/src/AsmResolver.DotNet/Code/Cil/OriginalMetadataTokenProvider.cs +++ b/src/AsmResolver.DotNet/Code/Cil/OriginalMetadataTokenProvider.cs @@ -26,7 +26,7 @@ public OriginalMetadataTokenProvider(ModuleDefinition? module) private MetadataToken GetToken(IMetadataMember member, object? diagnosticSource) { - if (_module is not null && member is IModuleProvider provider && provider.Module != _module) + if (_module is not null && member is IModuleProvider provider && provider.ContextModule != _module) throw new MemberNotImportedException(member, diagnosticSource); return member.MetadataToken; diff --git a/src/AsmResolver.DotNet/Collections/ParameterCollection.cs b/src/AsmResolver.DotNet/Collections/ParameterCollection.cs index 3fade3b1a..dcb6bee5e 100644 --- a/src/AsmResolver.DotNet/Collections/ParameterCollection.cs +++ b/src/AsmResolver.DotNet/Collections/ParameterCollection.cs @@ -135,7 +135,7 @@ private void UpdateParameterTypes() { var genArgs = new TypeSignature[declaringType.GenericParameters.Count]; for (int i = 0; i < genArgs.Length; i++) - genArgs[i] = new GenericParameterSignature(_owner.Module, GenericParameterType.Type, i); + genArgs[i] = new GenericParameterSignature(_owner.DeclaringModule, GenericParameterType.Type, i); result = declaringType.MakeGenericInstanceType(genArgs); } else diff --git a/src/AsmResolver.DotNet/DefaultMetadataResolver.cs b/src/AsmResolver.DotNet/DefaultMetadataResolver.cs index da6c33788..2dc7e44c6 100644 --- a/src/AsmResolver.DotNet/DefaultMetadataResolver.cs +++ b/src/AsmResolver.DotNet/DefaultMetadataResolver.cs @@ -136,10 +136,6 @@ public IAssemblyResolver AssemblyResolver if (declaringType is null) return null; - var name = field is MemberReference member - ? member.Name - : (Utf8String?) field.Name; - for (int i = 0; i < declaringType.Fields.Count; i++) { var candidate = declaringType.Fields[i]; @@ -168,7 +164,7 @@ public TypeResolution(IAssemblyResolver resolver) if (reference is null) return null; - var scope = reference.Scope ?? reference.Module; + var scope = reference.Scope ?? reference.ContextModule; if (reference.Name is null || scope is null || _scopeStack.Contains(scope)) return null; _scopeStack.Push(scope); @@ -176,11 +172,11 @@ public TypeResolution(IAssemblyResolver resolver) switch (scope.MetadataToken.Table) { case TableIndex.AssemblyRef: - if (reference.Module?.Assembly is { } assembly) + if (reference.ContextModule?.Assembly is { } assembly) { // Are we referencing the current assembly the reference was declared in? if (SignatureComparer.Default.Equals(scope.GetAssembly(), assembly)) - return FindTypeInModule(reference.Module, reference.Namespace, reference.Name); + return FindTypeInModule(reference.ContextModule, reference.Namespace, reference.Name); } var assemblyDefScope = _assemblyResolver.Resolve((AssemblyReference) scope); @@ -218,7 +214,7 @@ public TypeResolution(IAssemblyResolver resolver) : null; case TableIndex.File when !string.IsNullOrEmpty(implementation.Name): - var module = FindModuleInAssembly(exportedType.Module!.Assembly!, implementation.Name!); + var module = FindModuleInAssembly(exportedType.ContextModule!.Assembly!, implementation.Name!); return module is not null ? FindTypeInModule(module, exportedType.Namespace, exportedType.Name) : null; diff --git a/src/AsmResolver.DotNet/DotNetFrameworkAssemblyResolver.cs b/src/AsmResolver.DotNet/DotNetFrameworkAssemblyResolver.cs index c93e1451b..218369c62 100644 --- a/src/AsmResolver.DotNet/DotNetFrameworkAssemblyResolver.cs +++ b/src/AsmResolver.DotNet/DotNetFrameworkAssemblyResolver.cs @@ -117,7 +117,7 @@ private void AddGacDirectories(string windowsGac, string? prefix) bool is32BitRequired; // Try infer from declaring module which GAC directory would be preferred. - if (assembly is IModuleProvider {Module: { } module}) + if (assembly is IModuleProvider {ContextModule: { } module}) { is32BitPreferred = module.IsBit32Preferred; is32BitRequired = module.IsBit32Required; diff --git a/src/AsmResolver.DotNet/EventDefinition.cs b/src/AsmResolver.DotNet/EventDefinition.cs index d293e2524..79fdbba8c 100644 --- a/src/AsmResolver.DotNet/EventDefinition.cs +++ b/src/AsmResolver.DotNet/EventDefinition.cs @@ -105,7 +105,9 @@ public ITypeDefOrRef? EventType } /// - public ModuleDefinition? Module => DeclaringType?.Module; + public ModuleDefinition? DeclaringModule => DeclaringType?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// /// Gets the type that defines the property. @@ -196,11 +198,12 @@ public bool IsAccessibleFromType(TypeDefinition type) => IMemberDefinition IMemberDescriptor.Resolve() => this; + IMemberDefinition IMemberDescriptor.Resolve(ModuleDefinition context) => this; + /// public bool IsImportedInModule(ModuleDefinition module) { - return Module == module - && (EventType?.IsImportedInModule(module) ?? false); + return DeclaringModule == module && (EventType?.IsImportedInModule(module) ?? false); } /// diff --git a/src/AsmResolver.DotNet/ExportedType.cs b/src/AsmResolver.DotNet/ExportedType.cs index 0820e00d4..387d7e7ed 100644 --- a/src/AsmResolver.DotNet/ExportedType.cs +++ b/src/AsmResolver.DotNet/ExportedType.cs @@ -96,7 +96,7 @@ public Utf8String? Namespace public string FullName => MemberNameGenerator.GetTypeFullName(this); /// - public ModuleDefinition? Module + public ModuleDefinition? ContextModule { get; private set; @@ -104,8 +104,8 @@ public ModuleDefinition? Module ModuleDefinition? IOwnedCollectionElement.Owner { - get => Module; - set => Module = value; + get => ContextModule; + set => ContextModule = value; } /// @@ -125,7 +125,7 @@ public IImplementation? Implementation ITypeDescriptor? IMemberDescriptor.DeclaringType => DeclaringType; /// - public IResolutionScope? Scope => Module; + public IResolutionScope? Scope => ContextModule; /// public IList CustomAttributes @@ -142,13 +142,19 @@ public IList CustomAttributes public bool IsValueType => Resolve()?.IsValueType ?? false; /// - public TypeDefinition? Resolve() => Module?.MetadataResolver.ResolveType(this); + public TypeDefinition? Resolve() => ContextModule is { } context ? Resolve(context) : null; + + /// + public TypeDefinition? Resolve(ModuleDefinition context) => context.MetadataResolver.ResolveType(this); + + IMemberDefinition? IMemberDescriptor.Resolve() => Resolve(); + + IMemberDefinition? IMemberDescriptor.Resolve(ModuleDefinition context) => Resolve(context); /// public bool IsImportedInModule(ModuleDefinition module) { - return Module == module - && (Implementation?.IsImportedInModule(module) ?? false); + return ContextModule == module && (Implementation?.IsImportedInModule(module) ?? false); } /// @@ -161,10 +167,8 @@ public bool IsImportedInModule(ModuleDefinition module) /// IImportable IImportable.ImportWith(ReferenceImporter importer) => ImportWith(importer); - IMemberDefinition? IMemberDescriptor.Resolve() => Resolve(); - /// - public ITypeDefOrRef ToTypeDefOrRef() => new TypeReference(Module, Scope, Namespace, Name); + public ITypeDefOrRef ToTypeDefOrRef() => new TypeReference(ContextModule, Scope, Namespace, Name); /// public TypeSignature ToTypeSignature() => new TypeDefOrRefSignature(ToTypeDefOrRef()); diff --git a/src/AsmResolver.DotNet/FieldDefinition.cs b/src/AsmResolver.DotNet/FieldDefinition.cs index ce00529ab..f81652c1f 100644 --- a/src/AsmResolver.DotNet/FieldDefinition.cs +++ b/src/AsmResolver.DotNet/FieldDefinition.cs @@ -298,7 +298,9 @@ public bool HasFieldRva } /// - public ModuleDefinition? Module => DeclaringType?.Module; + public ModuleDefinition? DeclaringModule => DeclaringType?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// /// Gets the type that defines the field. @@ -383,11 +385,16 @@ public int? FieldOffset FieldDefinition IFieldDescriptor.Resolve() => this; + FieldDefinition IFieldDescriptor.Resolve(ModuleDefinition context) => this; + + IMemberDefinition IMemberDescriptor.Resolve() => this; + + IMemberDefinition IMemberDescriptor.Resolve(ModuleDefinition context) => this; + /// public bool IsImportedInModule(ModuleDefinition module) { - return Module == module - && (Signature?.IsImportedInModule(module) ?? false); + return DeclaringModule == module && (Signature?.IsImportedInModule(module) ?? false); } /// @@ -400,8 +407,6 @@ public bool IsImportedInModule(ModuleDefinition module) /// IImportable IImportable.ImportWith(ReferenceImporter importer) => ImportWith(importer); - IMemberDefinition IMemberDescriptor.Resolve() => this; - /// public bool IsAccessibleFromType(TypeDefinition type) { @@ -422,7 +427,7 @@ public bool IsAccessibleFromType(TypeDefinition type) type1 = type1.DeclaringType; } - bool isInSameAssembly = SignatureComparer.Default.Equals(declaringType.Module, type.Module); + bool isInSameAssembly = SignatureComparer.Default.Equals(declaringType.DeclaringModule, type.DeclaringModule); // Assembly (internal in C#) fields are accessible by types in the same assembly. if (IsAssembly || IsFamilyOrAssembly) diff --git a/src/AsmResolver.DotNet/FileReference.cs b/src/AsmResolver.DotNet/FileReference.cs index c6d8e4cde..74250f699 100644 --- a/src/AsmResolver.DotNet/FileReference.cs +++ b/src/AsmResolver.DotNet/FileReference.cs @@ -87,7 +87,7 @@ public Utf8String? Name public string FullName => Name ?? NullName; /// - public ModuleDefinition? Module + public ModuleDefinition? ContextModule { get; private set; @@ -95,8 +95,8 @@ public ModuleDefinition? Module ModuleDefinition? IOwnedCollectionElement.Owner { - get => Module; - set => Module = value; + get => ContextModule; + set => ContextModule = value; } /// @@ -120,7 +120,7 @@ public IList CustomAttributes } /// - public bool IsImportedInModule(ModuleDefinition module) => Module == module; + public bool IsImportedInModule(ModuleDefinition module) => ContextModule == module; /// /// Imports the file using the provided reference importer object. diff --git a/src/AsmResolver.DotNet/GenericParameter.cs b/src/AsmResolver.DotNet/GenericParameter.cs index 566ae44ca..657dd5b0c 100644 --- a/src/AsmResolver.DotNet/GenericParameter.cs +++ b/src/AsmResolver.DotNet/GenericParameter.cs @@ -13,6 +13,7 @@ public class GenericParameter : INameProvider, IHasCustomAttribute, IModuleProvider, + IMetadataDefinition, IOwnedCollectionElement { private readonly LazyVariable _name; @@ -171,7 +172,9 @@ public bool HasAllowByRefLike public ushort Number => Owner is null ? (ushort) 0 : (ushort) Owner.GenericParameters.IndexOf(this); /// - public ModuleDefinition? Module => Owner?.Module; + public ModuleDefinition? DeclaringModule => Owner?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// /// Gets a collection of constraints put on the generic parameter. diff --git a/src/AsmResolver.DotNet/GenericParameterConstraint.cs b/src/AsmResolver.DotNet/GenericParameterConstraint.cs index b1ee65d6d..319176725 100644 --- a/src/AsmResolver.DotNet/GenericParameterConstraint.cs +++ b/src/AsmResolver.DotNet/GenericParameterConstraint.cs @@ -65,7 +65,9 @@ public ITypeDefOrRef? Constraint } /// - public ModuleDefinition? Module => Owner?.Module; + public ModuleDefinition? DeclaringModule => Owner?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// public IList CustomAttributes diff --git a/src/AsmResolver.DotNet/IFieldDescriptor.cs b/src/AsmResolver.DotNet/IFieldDescriptor.cs index 233b45d02..358266003 100644 --- a/src/AsmResolver.DotNet/IFieldDescriptor.cs +++ b/src/AsmResolver.DotNet/IFieldDescriptor.cs @@ -28,8 +28,15 @@ public interface IFieldDescriptor : IMemberDescriptor, IMetadataMember /// /// The resolved field definition, or null if the field could not be resolved. /// - /// This method can only be invoked if the reference was added to a module. + /// This method assumes the context module as the resolution context. /// new FieldDefinition? Resolve(); + + /// + /// Resolves the reference to a field definition, assuming the provided module as resolution context. + /// + /// The module to assume as resolution context. + /// The resolved field definition, or null if the field could not be resolved. + new FieldDefinition? Resolve(ModuleDefinition context); } } diff --git a/src/AsmResolver.DotNet/IHasConstant.cs b/src/AsmResolver.DotNet/IHasConstant.cs index b44fab572..1a64e9fe9 100644 --- a/src/AsmResolver.DotNet/IHasConstant.cs +++ b/src/AsmResolver.DotNet/IHasConstant.cs @@ -3,7 +3,7 @@ namespace AsmResolver.DotNet /// /// Represents a member that can be assigned a constant value, and can be referenced by a HasConstant coded index. /// - public interface IHasConstant : IMetadataMember, INameProvider, IModuleProvider + public interface IHasConstant : IMetadataDefinition { /// /// Gets or sets a constant that is assigned to the member. @@ -18,4 +18,4 @@ public interface IHasConstant : IMetadataMember, INameProvider, IModuleProvider set; } } -} \ No newline at end of file +} diff --git a/src/AsmResolver.DotNet/IHasCustomAttribute.cs b/src/AsmResolver.DotNet/IHasCustomAttribute.cs index d88db72d4..be5d0cbd4 100644 --- a/src/AsmResolver.DotNet/IHasCustomAttribute.cs +++ b/src/AsmResolver.DotNet/IHasCustomAttribute.cs @@ -12,4 +12,4 @@ public interface IHasCustomAttribute : IMetadataMember /// IList CustomAttributes { get; } } -} \ No newline at end of file +} diff --git a/src/AsmResolver.DotNet/IHasFieldMarshal.cs b/src/AsmResolver.DotNet/IHasFieldMarshal.cs index 9ce8c4f09..1c5300507 100644 --- a/src/AsmResolver.DotNet/IHasFieldMarshal.cs +++ b/src/AsmResolver.DotNet/IHasFieldMarshal.cs @@ -6,7 +6,7 @@ namespace AsmResolver.DotNet /// Represents a member that can be assigned a field marshal descriptor, and can be referenced by a HasFieldMarshal /// coded index. /// - public interface IHasFieldMarshal : IMetadataMember, INameProvider, IModuleProvider + public interface IHasFieldMarshal : IMetadataDefinition { /// /// Gets or sets the description on how a specific value needs to be marshaled upon calling to or from unmanaged @@ -18,4 +18,4 @@ public interface IHasFieldMarshal : IMetadataMember, INameProvider, IModuleProvi set; } } -} \ No newline at end of file +} diff --git a/src/AsmResolver.DotNet/IHasGenericParameters.cs b/src/AsmResolver.DotNet/IHasGenericParameters.cs index 8634e1560..00524fd64 100644 --- a/src/AsmResolver.DotNet/IHasGenericParameters.cs +++ b/src/AsmResolver.DotNet/IHasGenericParameters.cs @@ -5,7 +5,7 @@ namespace AsmResolver.DotNet /// /// Represents a member that can be referenced by a TypeOrMethod coded index, and exposes generic parameters. /// - public interface IHasGenericParameters : IMetadataMember, IMemberDescriptor + public interface IHasGenericParameters : IMemberDefinition { /// /// Gets a collection of generic parameters this member defines. @@ -15,4 +15,4 @@ IList GenericParameters get; } } -} \ No newline at end of file +} diff --git a/src/AsmResolver.DotNet/IHasSecurityDeclaration.cs b/src/AsmResolver.DotNet/IHasSecurityDeclaration.cs index 9a1f6529f..959cf14d0 100644 --- a/src/AsmResolver.DotNet/IHasSecurityDeclaration.cs +++ b/src/AsmResolver.DotNet/IHasSecurityDeclaration.cs @@ -6,7 +6,7 @@ namespace AsmResolver.DotNet /// Represents a member that can be assigned security declarations, and can be referenced by a HasDeclSecurity /// coded index. /// - public interface IHasSecurityDeclaration : IMetadataMember + public interface IHasSecurityDeclaration : IMetadataDefinition { /// /// Gets a collection of security declarations assigned to the member. @@ -16,4 +16,4 @@ IList SecurityDeclarations get; } } -} \ No newline at end of file +} diff --git a/src/AsmResolver.DotNet/IHasSemantics.cs b/src/AsmResolver.DotNet/IHasSemantics.cs index 7ad536647..2506d8e24 100644 --- a/src/AsmResolver.DotNet/IHasSemantics.cs +++ b/src/AsmResolver.DotNet/IHasSemantics.cs @@ -5,14 +5,14 @@ namespace AsmResolver.DotNet /// /// Represents a member that can be referenced by a HasSemantics coded index. /// - public interface IHasSemantics : IMetadataMember, IMemberDefinition + public interface IHasSemantics : IMemberDefinition { /// - /// Gets a collection of methods that are associated with this member through special semantics. + /// Gets a collection of methods that are associated with this member through special semantics. /// IList Semantics { get; } } -} \ No newline at end of file +} diff --git a/src/AsmResolver.DotNet/IImplementation.cs b/src/AsmResolver.DotNet/IImplementation.cs index 7d99282d7..a79869288 100644 --- a/src/AsmResolver.DotNet/IImplementation.cs +++ b/src/AsmResolver.DotNet/IImplementation.cs @@ -4,7 +4,7 @@ namespace AsmResolver.DotNet /// Represents a member that is either a reference to an external file, assembly or type, and can be referenced by /// an Implementation coded index. /// - public interface IImplementation : IFullNameProvider, IModuleProvider, IHasCustomAttribute, IImportable + public interface IImplementation : IFullNameProvider, IHasCustomAttribute, IImportable { } } diff --git a/src/AsmResolver.DotNet/IManagedEntryPoint.cs b/src/AsmResolver.DotNet/IManagedEntryPoint.cs index 3b23ab1bd..9bf08cf9c 100644 --- a/src/AsmResolver.DotNet/IManagedEntryPoint.cs +++ b/src/AsmResolver.DotNet/IManagedEntryPoint.cs @@ -4,7 +4,5 @@ /// Represents a member that is either a method definition or a reference to an external file, that can be used to /// indicate the managed entry point of a .NET module. /// - public interface IManagedEntryPoint : IMetadataMember - { - } + public interface IManagedEntryPoint : IMetadataMember, INameProvider; } diff --git a/src/AsmResolver.DotNet/IMemberDefinition.cs b/src/AsmResolver.DotNet/IMemberDefinition.cs index c31de19ec..04ada94a3 100644 --- a/src/AsmResolver.DotNet/IMemberDefinition.cs +++ b/src/AsmResolver.DotNet/IMemberDefinition.cs @@ -3,7 +3,7 @@ namespace AsmResolver.DotNet /// /// Represents an accessible member defined in a metadata image. /// - public interface IMemberDefinition : IMemberDescriptor, IMetadataMember + public interface IMemberDefinition : IMetadataDefinition, IMemberDescriptor { /// /// Gets the type that declares the member (if available). diff --git a/src/AsmResolver.DotNet/IMemberDescriptor.cs b/src/AsmResolver.DotNet/IMemberDescriptor.cs index e837e453b..8058dada0 100644 --- a/src/AsmResolver.DotNet/IMemberDescriptor.cs +++ b/src/AsmResolver.DotNet/IMemberDescriptor.cs @@ -18,8 +18,15 @@ public interface IMemberDescriptor : IFullNameProvider, IModuleProvider, IImport /// /// The resolved member definition, or null if the member could not be resolved. /// - /// This method can only be invoked if the reference was added to a module. + /// This method assumes the context module as the resolution context. /// IMemberDefinition? Resolve(); + + /// + /// Resolves the reference to a member definition, assuming the provided module as resolution context. + /// + /// The module to assume as resolution context. + /// The resolved member definition, or null if the member could not be resolved. + IMemberDefinition? Resolve(ModuleDefinition context); } } diff --git a/src/AsmResolver.DotNet/IMemberForwarded.cs b/src/AsmResolver.DotNet/IMemberForwarded.cs index af101bfe6..05d172632 100644 --- a/src/AsmResolver.DotNet/IMemberForwarded.cs +++ b/src/AsmResolver.DotNet/IMemberForwarded.cs @@ -4,7 +4,7 @@ namespace AsmResolver.DotNet /// Represents a member that can be assigned Platform Invoke (P/Invoke) implementation mappings, and can be indexed /// using a MemberForwarded coded index. /// - public interface IMemberForwarded : IMetadataMember, IMemberDescriptor + public interface IMemberForwarded : IMemberDefinition { /// /// Gets or sets the Platform Invoke (P/Invoke) implementation mapping of this member (if available). diff --git a/src/AsmResolver.DotNet/IMetadataDefinition.cs b/src/AsmResolver.DotNet/IMetadataDefinition.cs new file mode 100644 index 000000000..14cf43e7c --- /dev/null +++ b/src/AsmResolver.DotNet/IMetadataDefinition.cs @@ -0,0 +1,15 @@ +namespace AsmResolver.DotNet; + +/// +/// Represents a named metadata object that introduces a new definition in a module. +/// +public interface IMetadataDefinition : IMetadataMember, INameProvider +{ + /// + /// Gets the enclosing module that declares the object. + /// + ModuleDefinition? DeclaringModule + { + get; + } +} diff --git a/src/AsmResolver.DotNet/IMethodDescriptor.cs b/src/AsmResolver.DotNet/IMethodDescriptor.cs index 80b4485d0..01f194179 100644 --- a/src/AsmResolver.DotNet/IMethodDescriptor.cs +++ b/src/AsmResolver.DotNet/IMethodDescriptor.cs @@ -22,13 +22,21 @@ public interface IMethodDescriptor : IMemberDescriptor, IMetadataMember { get; } + /// /// Resolves the reference to a method definition. /// /// The resolved method definition, or null if the method could not be resolved. /// - /// This method can only be invoked if the reference was added to a module. + /// This method assumes the context module as the resolution context. /// new MethodDefinition? Resolve(); + + /// + /// Resolves the reference to a method definition, assuming the provided module as resolution context. + /// + /// The module to assume as resolution context. + /// The resolved method definition, or null if the method could not be resolved. + new MethodDefinition? Resolve(ModuleDefinition context); } } diff --git a/src/AsmResolver.DotNet/IModuleProvider.cs b/src/AsmResolver.DotNet/IModuleProvider.cs index 4dac498e0..4103b92ae 100644 --- a/src/AsmResolver.DotNet/IModuleProvider.cs +++ b/src/AsmResolver.DotNet/IModuleProvider.cs @@ -9,12 +9,12 @@ public interface IModuleProvider /// Gets the module that defines the member definition or reference. /// /// - /// For member references, this does not obtain the module definition that the member is defined in. + /// For member references, this does not obtain the module definition that the member is defined in. /// Rather, it obtains the module definition that references this reference. /// - ModuleDefinition? Module + ModuleDefinition? ContextModule { get; } } -} \ No newline at end of file +} diff --git a/src/AsmResolver.DotNet/ITypeDescriptor.cs b/src/AsmResolver.DotNet/ITypeDescriptor.cs index bdbcce05a..cb0042395 100644 --- a/src/AsmResolver.DotNet/ITypeDescriptor.cs +++ b/src/AsmResolver.DotNet/ITypeDescriptor.cs @@ -36,10 +36,17 @@ bool IsValueType /// /// The resolved type definition, or null if the type could not be resolved. /// - /// This method can only be invoked if the reference was added to a module. + /// This method assumes the context module as the resolution context. /// new TypeDefinition? Resolve(); + /// + /// Resolves the reference to a method definition, assuming the provided module as resolution context. + /// + /// The module to assume as resolution context. + /// The resolved method definition, or null if the method could not be resolved. + new TypeDefinition? Resolve(ModuleDefinition context); + /// /// Transforms the type descriptor to an instance of a , which can be referenced by /// a metadata token. diff --git a/src/AsmResolver.DotNet/InterfaceImplementation.cs b/src/AsmResolver.DotNet/InterfaceImplementation.cs index f34351608..8ec758a97 100644 --- a/src/AsmResolver.DotNet/InterfaceImplementation.cs +++ b/src/AsmResolver.DotNet/InterfaceImplementation.cs @@ -65,7 +65,9 @@ public ITypeDefOrRef? Interface } /// - public ModuleDefinition? Module => Class?.Module; + public ModuleDefinition? DeclaringModule => Class?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// public IList CustomAttributes diff --git a/src/AsmResolver.DotNet/InvalidTypeDefOrRef.cs b/src/AsmResolver.DotNet/InvalidTypeDefOrRef.cs index 00057aed5..78139a80e 100644 --- a/src/AsmResolver.DotNet/InvalidTypeDefOrRef.cs +++ b/src/AsmResolver.DotNet/InvalidTypeDefOrRef.cs @@ -41,7 +41,7 @@ public InvalidTypeSignatureError Error string IFullNameProvider.FullName => ((IFullNameProvider) this).Name!; - ModuleDefinition? IModuleProvider.Module => null; + ModuleDefinition? IModuleProvider.ContextModule => null; IResolutionScope? ITypeDescriptor.Scope => null; @@ -84,8 +84,12 @@ public static InvalidTypeDefOrRef Get(InvalidTypeSignatureError error) IMemberDefinition? IMemberDescriptor.Resolve() => null; + IMemberDefinition? IMemberDescriptor.Resolve(ModuleDefinition context) => null; + TypeDefinition? ITypeDescriptor.Resolve() => null; + TypeDefinition? ITypeDescriptor.Resolve(ModuleDefinition context) => null; + ITypeDefOrRef ITypeDescriptor.ToTypeDefOrRef() => this; TypeSignature ITypeDescriptor.ToTypeSignature() => throw new InvalidOperationException(); diff --git a/src/AsmResolver.DotNet/ManifestResource.cs b/src/AsmResolver.DotNet/ManifestResource.cs index f10c9e4cf..800345dd4 100644 --- a/src/AsmResolver.DotNet/ManifestResource.cs +++ b/src/AsmResolver.DotNet/ManifestResource.cs @@ -13,8 +13,9 @@ namespace AsmResolver.DotNet /// public class ManifestResource : MetadataMember, - INameProvider, IHasCustomAttribute, + IModuleProvider, + IMetadataDefinition, IOwnedCollectionElement { private readonly LazyVariable _name; @@ -141,17 +142,19 @@ public ISegment? EmbeddedDataSegment /// /// Gets the module that this manifest resource reference is stored in. /// - public ModuleDefinition? Module + public ModuleDefinition? DeclaringModule { get; private set; } + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; + /// ModuleDefinition? IOwnedCollectionElement.Owner { - get => Module; - set => Module = value; + get => DeclaringModule; + set => DeclaringModule = value; } /// diff --git a/src/AsmResolver.DotNet/MemberReference.cs b/src/AsmResolver.DotNet/MemberReference.cs index 313ea0b1b..c578ea3e1 100644 --- a/src/AsmResolver.DotNet/MemberReference.cs +++ b/src/AsmResolver.DotNet/MemberReference.cs @@ -112,7 +112,7 @@ public string FullName } /// - public ModuleDefinition? Module => Parent?.Module; + public ModuleDefinition? ContextModule => Parent?.ContextModule; /// /// Gets the type that declares the referenced member, if available. @@ -137,28 +137,27 @@ public IList CustomAttributes } } + /// + public IMemberDefinition? Resolve() => ContextModule is { } context ? Resolve(context) : null; + /// /// Resolves the reference to a member definition. /// /// The resolved member definition, or null if the member could not be resolved. /// Occurs when the member reference has an invalid signature. - /// - /// This method can only be invoked if the reference was added to a module. - /// - public IMemberDefinition? Resolve() + public IMemberDefinition? Resolve(ModuleDefinition context) { if (IsMethod) - return ((IMethodDescriptor) this).Resolve(); + return ((IMethodDescriptor) this).Resolve(context); if (IsField) - return ((IFieldDescriptor) this).Resolve(); + return ((IFieldDescriptor) this).Resolve(context); throw new ArgumentOutOfRangeException(); } /// public bool IsImportedInModule(ModuleDefinition module) { - return Module == module - && (Signature?.IsImportedInModule(module) ?? false); + return ContextModule == module && (Signature?.IsImportedInModule(module) ?? false); } /// @@ -173,18 +172,26 @@ public MemberReference ImportWith(ReferenceImporter importer) => IsMethod /// IImportable IImportable.ImportWith(ReferenceImporter importer) => ImportWith(importer); - FieldDefinition? IFieldDescriptor.Resolve() + FieldDefinition? IFieldDescriptor.Resolve() => ContextModule is { } context + ? ((IFieldDescriptor) this).Resolve(context) + : null; + + FieldDefinition? IFieldDescriptor.Resolve(ModuleDefinition context) { - if (!IsField) - throw new InvalidOperationException("Member reference must reference a field."); - return Module?.MetadataResolver.ResolveField(this); + return IsField + ? context.MetadataResolver.ResolveField(this) + : throw new InvalidOperationException("Member reference must reference a field."); } - MethodDefinition? IMethodDescriptor.Resolve() + MethodDefinition? IMethodDescriptor.Resolve() => ContextModule is { } context + ? ((IMethodDescriptor) this).Resolve(context) + : null; + + MethodDefinition? IMethodDescriptor.Resolve(ModuleDefinition context) { - if (!IsMethod) - throw new InvalidOperationException("Member reference must reference a method."); - return Module?.MetadataResolver.ResolveMethod(this); + return IsMethod + ? context.MetadataResolver.ResolveMethod(this) + : throw new InvalidOperationException("Member reference must reference a method."); } /// diff --git a/src/AsmResolver.DotNet/MethodDefinition.cs b/src/AsmResolver.DotNet/MethodDefinition.cs index 861f9367a..5451b61de 100644 --- a/src/AsmResolver.DotNet/MethodDefinition.cs +++ b/src/AsmResolver.DotNet/MethodDefinition.cs @@ -47,8 +47,8 @@ public class MethodDefinition : protected MethodDefinition(MetadataToken token) : base(token) { - _name = new LazyVariable(x => GetName()); - _declaringType = new LazyVariable(x => GetDeclaringType()); + _name = new LazyVariable(x => x.GetName()); + _declaringType = new LazyVariable(x => x.GetDeclaringType()); _signature = new LazyVariable(x => x.GetSignature()); _methodBody = new LazyVariable(static x => { @@ -551,7 +551,9 @@ public bool HasSecurityMitigations } /// - public virtual ModuleDefinition? Module => DeclaringType?.Module; + public virtual ModuleDefinition? DeclaringModule => DeclaringType?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// /// Gets the type that defines the method. @@ -843,11 +845,16 @@ public static MethodDefinition CreateConstructor(ModuleDefinition module, params MethodDefinition IMethodDescriptor.Resolve() => this; + MethodDefinition IMethodDescriptor.Resolve(ModuleDefinition context) => this; + + IMemberDefinition IMemberDescriptor.Resolve() => this; + + IMemberDefinition IMemberDescriptor.Resolve(ModuleDefinition context) => this; + /// public bool IsImportedInModule(ModuleDefinition module) { - return Module == module - && (Signature?.IsImportedInModule(module) ?? false); + return DeclaringModule == module && (Signature?.IsImportedInModule(module) ?? false); } /// @@ -860,8 +867,6 @@ public bool IsImportedInModule(ModuleDefinition module) /// IImportable IImportable.ImportWith(ReferenceImporter importer) => ImportWith(importer); - IMemberDefinition IMemberDescriptor.Resolve() => this; - /// /// Determines whether the provided definition can be accessed by the method. /// @@ -898,7 +903,7 @@ public bool IsAccessibleFromType(TypeDefinition type) type1 = type1.DeclaringType; } - bool isInSameAssembly = SignatureComparer.Default.Equals(declaringType.Module, type.Module); + bool isInSameAssembly = SignatureComparer.Default.Equals(declaringType.DeclaringModule, type.DeclaringModule); // Assembly (internal in C#) methods are accessible by types in the same assembly. if (IsAssembly || IsFamilyOrAssembly) diff --git a/src/AsmResolver.DotNet/MethodSpecification.cs b/src/AsmResolver.DotNet/MethodSpecification.cs index a01257405..3f8797cfc 100644 --- a/src/AsmResolver.DotNet/MethodSpecification.cs +++ b/src/AsmResolver.DotNet/MethodSpecification.cs @@ -70,7 +70,7 @@ public GenericInstanceMethodSignature? Signature public string FullName => MemberNameGenerator.GetMethodFullName(this); /// - public ModuleDefinition? Module => Method?.Module; + public ModuleDefinition? ContextModule => Method?.ContextModule; /// /// Gets the declaring type of the method. @@ -93,6 +93,13 @@ public IList CustomAttributes /// public MethodDefinition? Resolve() => Method?.Resolve(); + IMemberDefinition? IMemberDescriptor.Resolve() => Resolve(); + + /// + public MethodDefinition? Resolve(ModuleDefinition context) => Method?.Resolve(context); + + IMemberDefinition? IMemberDescriptor.Resolve(ModuleDefinition context) => Resolve(context); + /// public bool IsImportedInModule(ModuleDefinition module) { @@ -109,9 +116,6 @@ public bool IsImportedInModule(ModuleDefinition module) /// IImportable IImportable.ImportWith(ReferenceImporter importer) => ImportWith(importer); - - IMemberDefinition? IMemberDescriptor.Resolve() => Resolve(); - /// /// Obtains the instantiated method. /// diff --git a/src/AsmResolver.DotNet/ModuleDefinition.cs b/src/AsmResolver.DotNet/ModuleDefinition.cs index 055cf2b4d..663f25b10 100644 --- a/src/AsmResolver.DotNet/ModuleDefinition.cs +++ b/src/AsmResolver.DotNet/ModuleDefinition.cs @@ -425,7 +425,7 @@ public AssemblyDefinition? Assembly } /// - ModuleDefinition IModuleProvider.Module => this; + ModuleDefinition IModuleProvider.ContextModule => this; /// /// Gets or sets the name of the module. diff --git a/src/AsmResolver.DotNet/ModuleReference.cs b/src/AsmResolver.DotNet/ModuleReference.cs index f4666024c..82b403447 100644 --- a/src/AsmResolver.DotNet/ModuleReference.cs +++ b/src/AsmResolver.DotNet/ModuleReference.cs @@ -53,7 +53,7 @@ public Utf8String? Name string? INameProvider.Name => Name; /// - public ModuleDefinition? Module + public ModuleDefinition? ContextModule { get; private set; @@ -61,8 +61,8 @@ public ModuleDefinition? Module ModuleDefinition? IOwnedCollectionElement.Owner { - get => Module; - set => Module = value; + get => ContextModule; + set => ContextModule = value; } /// @@ -77,7 +77,7 @@ public IList CustomAttributes } /// - public bool IsImportedInModule(ModuleDefinition module) => Module == module; + public bool IsImportedInModule(ModuleDefinition module) => ContextModule == module; /// /// Imports the module reference using the provided reference importer object. @@ -98,7 +98,7 @@ public IList CustomAttributes /// protected virtual Utf8String? GetName() => null; - AssemblyDescriptor? IResolutionScope.GetAssembly() => Module?.Assembly; + AssemblyDescriptor? IResolutionScope.GetAssembly() => ContextModule?.Assembly; /// /// Obtains the list of custom attributes assigned to the member. diff --git a/src/AsmResolver.DotNet/ParameterDefinition.cs b/src/AsmResolver.DotNet/ParameterDefinition.cs index 6ab340b23..80acb2889 100644 --- a/src/AsmResolver.DotNet/ParameterDefinition.cs +++ b/src/AsmResolver.DotNet/ParameterDefinition.cs @@ -19,6 +19,7 @@ public class ParameterDefinition : IHasCustomAttribute, IHasConstant, IHasFieldMarshal, + IModuleProvider, IOwnedCollectionElement { private readonly LazyVariable _name; @@ -172,7 +173,9 @@ public MethodDefinition? Method } /// - public ModuleDefinition? Module => Method?.Module; + public ModuleDefinition? DeclaringModule => Method?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// public IList CustomAttributes diff --git a/src/AsmResolver.DotNet/PropertyDefinition.cs b/src/AsmResolver.DotNet/PropertyDefinition.cs index 22a589866..14c35cc13 100644 --- a/src/AsmResolver.DotNet/PropertyDefinition.cs +++ b/src/AsmResolver.DotNet/PropertyDefinition.cs @@ -121,7 +121,9 @@ public PropertySignature? Signature } /// - public ModuleDefinition? Module => DeclaringType?.Module; + public ModuleDefinition? DeclaringModule => DeclaringType?.DeclaringModule; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// /// Gets the type that defines the property. @@ -207,11 +209,12 @@ public bool IsAccessibleFromType(TypeDefinition type) => IMemberDefinition IMemberDescriptor.Resolve() => this; + IMemberDefinition IMemberDescriptor.Resolve(ModuleDefinition context) => this; + /// public bool IsImportedInModule(ModuleDefinition module) { - return Module == module - && (Signature?.IsImportedInModule(module) ?? false); + return DeclaringModule == module && (Signature?.IsImportedInModule(module) ?? false); } /// diff --git a/src/AsmResolver.DotNet/ReferenceImporter.cs b/src/AsmResolver.DotNet/ReferenceImporter.cs index f18a5cd57..f2f73f758 100644 --- a/src/AsmResolver.DotNet/ReferenceImporter.cs +++ b/src/AsmResolver.DotNet/ReferenceImporter.cs @@ -198,13 +198,21 @@ protected virtual ITypeDefOrRef ImportType(TypeReference type) if (type.IsImportedInModule(TargetModule)) return type; + // If the TypeRef's scope is null, the runtime assumes it is a type in the current assembly. + IResolutionScope? impliedScope; + if (type.Scope is not null) + impliedScope = ImportScope(type.Scope); + else if (type.ContextModule?.Assembly is { } assembly) + impliedScope = ImportAssembly(assembly); + else + impliedScope = null; + return new TypeReference( TargetModule, - type.Scope is not null - ? ImportScope(type.Scope) - : null, + impliedScope, type.Namespace, - type.Name); + type.Name + ); } /// diff --git a/src/AsmResolver.DotNet/ReflectionAssemblyDescriptor.cs b/src/AsmResolver.DotNet/ReflectionAssemblyDescriptor.cs index d41e16aca..be3d8a323 100644 --- a/src/AsmResolver.DotNet/ReflectionAssemblyDescriptor.cs +++ b/src/AsmResolver.DotNet/ReflectionAssemblyDescriptor.cs @@ -8,9 +8,8 @@ namespace AsmResolver.DotNet /// Provides a wrapper for that maps properties declared by onto an /// instance. This can be used for importing assemblies referenced by System.Reflection. /// - public class ReflectionAssemblyDescriptor : AssemblyDescriptor + public class ReflectionAssemblyDescriptor : AssemblyDescriptor, IModuleProvider { - private readonly ModuleDefinition? _parentModule; private readonly AssemblyName _assemblyName; /// @@ -20,7 +19,7 @@ public class ReflectionAssemblyDescriptor : AssemblyDescriptor public ReflectionAssemblyDescriptor(AssemblyName assemblyName) : base(new MetadataToken(TableIndex.AssemblyRef, 0)) { - _parentModule = null; + ContextModule = null; _assemblyName = assemblyName; Version = assemblyName.Version ?? new Version(); } @@ -33,7 +32,7 @@ public ReflectionAssemblyDescriptor(AssemblyName assemblyName) public ReflectionAssemblyDescriptor(ModuleDefinition parentModule, AssemblyName assemblyName) : base(new MetadataToken(TableIndex.AssemblyRef, 0)) { - _parentModule = parentModule; + ContextModule = parentModule; _assemblyName = assemblyName; Version = assemblyName.Version ?? new Version(); } @@ -54,10 +53,16 @@ public override AssemblyReference ImportWith(ReferenceImporter importer) => /// public override bool IsCorLib => Name is not null && KnownCorLibs.KnownCorLibNames.Contains(Name); + /// + public ModuleDefinition? ContextModule + { + get; + } + /// public override byte[]? GetPublicKeyToken() => _assemblyName.GetPublicKeyToken(); /// - public override AssemblyDefinition? Resolve() => _parentModule?.MetadataResolver.AssemblyResolver.Resolve(this); + public override AssemblyDefinition? Resolve() => ContextModule?.MetadataResolver.AssemblyResolver.Resolve(this); } } diff --git a/src/AsmResolver.DotNet/RuntimeContext.cs b/src/AsmResolver.DotNet/RuntimeContext.cs index 1d256f688..d84dc281b 100644 --- a/src/AsmResolver.DotNet/RuntimeContext.cs +++ b/src/AsmResolver.DotNet/RuntimeContext.cs @@ -75,7 +75,9 @@ public RuntimeContext(BundleManifest manifest, ModuleReaderParameters readerPara TargetRuntime = manifest.GetTargetRuntime(); DefaultReaderParameters = new ModuleReaderParameters(readerParameters) {RuntimeContext = this}; AssemblyResolver = new BundleAssemblyResolver(manifest, readerParameters); - RuntimeCorLib = AssemblyResolver.Resolve(TargetRuntime.GetDefaultCorLib())?.ManifestModule?.CorLibTypeFactory.Object.Resolve()?.Module?.Assembly; + RuntimeCorLib = AssemblyResolver.Resolve(TargetRuntime.GetDefaultCorLib())? + .ManifestModule?.CorLibTypeFactory.Object.Resolve()? + .DeclaringModule?.Assembly; } /// diff --git a/src/AsmResolver.DotNet/Serialized/SerializedTypeReference.cs b/src/AsmResolver.DotNet/Serialized/SerializedTypeReference.cs index e1988e607..ad9f20f43 100644 --- a/src/AsmResolver.DotNet/Serialized/SerializedTypeReference.cs +++ b/src/AsmResolver.DotNet/Serialized/SerializedTypeReference.cs @@ -25,7 +25,7 @@ public SerializedTypeReference(ModuleReaderContext context, MetadataToken token, _context = context ?? throw new ArgumentNullException(nameof(context)); _row = row; - Module = context.ParentModule; + ContextModule = context.ParentModule; } /// diff --git a/src/AsmResolver.DotNet/Signatures/ArrayTypeSignature.cs b/src/AsmResolver.DotNet/Signatures/ArrayTypeSignature.cs index 0b6e26c4e..6f2d966c0 100644 --- a/src/AsmResolver.DotNet/Signatures/ArrayTypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/ArrayTypeSignature.cs @@ -196,10 +196,9 @@ public bool Validate() } /// - public override TypeSignature? GetDirectBaseClass() => Module?.CorLibTypeFactory.CorLibScope + public override TypeSignature? GetDirectBaseClass() => ContextModule?.CorLibTypeFactory.CorLibScope .CreateTypeReference("System", "Array") - .ToTypeSignature(false) - .ImportWith(Module.DefaultImporter); + .ToTypeSignature(false); /// public override TResult AcceptVisitor(ITypeSignatureVisitor visitor) => diff --git a/src/AsmResolver.DotNet/Signatures/ByReferenceTypeSignature.cs b/src/AsmResolver.DotNet/Signatures/ByReferenceTypeSignature.cs index db5da0d4a..31b35ec1f 100644 --- a/src/AsmResolver.DotNet/Signatures/ByReferenceTypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/ByReferenceTypeSignature.cs @@ -29,10 +29,10 @@ public ByReferenceTypeSignature(TypeSignature baseType) /// public override TypeSignature GetVerificationType() { - if (Module is null) + if (ContextModule is null) throw new InvalidOperationException("Cannot determine verification type of a non-imported type."); - var factory = Module.CorLibTypeFactory; + var factory = ContextModule.CorLibTypeFactory; return BaseType.GetReducedType().ElementType switch { ElementType.I1 or ElementType.Boolean => factory.SByte.MakeByReferenceType(), diff --git a/src/AsmResolver.DotNet/Signatures/CorLibTypeSignature.cs b/src/AsmResolver.DotNet/Signatures/CorLibTypeSignature.cs index dd860cc46..de3b6d7fe 100644 --- a/src/AsmResolver.DotNet/Signatures/CorLibTypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/CorLibTypeSignature.cs @@ -20,9 +20,9 @@ internal CorLibTypeSignature(IResolutionScope corlibScope, ElementType elementTy { Type = module.TopLevelTypes.First(t => t.IsTypeOf("System", name)); } - else if (corlibScope.Module is not null) + else if (corlibScope.ContextModule is not null) { - Type = new TypeReference(corlibScope.Module, corlibScope, "System", name); + Type = new TypeReference(corlibScope.ContextModule, corlibScope, "System", name); } else { @@ -73,19 +73,13 @@ public override string? Name }; /// - public override TypeDefinition? Resolve() - { - return Type.Resolve(); - } + public override TypeDefinition? Resolve(ModuleDefinition context) => Type.Resolve(context); /// - public override bool IsImportedInModule(ModuleDefinition module) => Module == module; + public override bool IsImportedInModule(ModuleDefinition module) => ContextModule == module; /// - public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() - { - return Type; - } + public override ITypeDefOrRef GetUnderlyingTypeDefOrRef() => Type; /// public override ElementType ElementType @@ -105,7 +99,7 @@ public override IResolutionScope? Scope /// public override TypeSignature GetReducedType() { - var factory = Module!.CorLibTypeFactory; + var factory = ContextModule!.CorLibTypeFactory; return ElementType switch { ElementType.I1 or ElementType.U1 => factory.SByte, @@ -120,7 +114,7 @@ public override TypeSignature GetReducedType() /// public override TypeSignature GetVerificationType() { - var factory = Module!.CorLibTypeFactory; + var factory = ContextModule!.CorLibTypeFactory; return GetReducedType().ElementType switch { ElementType.I1 or ElementType.Boolean => factory.SByte, @@ -135,7 +129,7 @@ public override TypeSignature GetVerificationType() /// public override TypeSignature GetIntermediateType() { - var factory = Module!.CorLibTypeFactory; + var factory = ContextModule!.CorLibTypeFactory; var verificationType = GetVerificationType(); return verificationType.ElementType switch { diff --git a/src/AsmResolver.DotNet/Signatures/FunctionPointerTypeSignature.cs b/src/AsmResolver.DotNet/Signatures/FunctionPointerTypeSignature.cs index 6aaf6cdc2..0ac4364bc 100644 --- a/src/AsmResolver.DotNet/Signatures/FunctionPointerTypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/FunctionPointerTypeSignature.cs @@ -42,11 +42,11 @@ public MethodSignature Signature public override bool IsValueType => true; /// - public override TypeDefinition? Resolve() => GetUnderlyingTypeDefOrRef()?.Resolve(); + public override TypeDefinition? Resolve(ModuleDefinition context) => GetUnderlyingTypeDefOrRef()?.Resolve(context); /// public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() => - Signature.ReturnType.Module?.CorLibTypeFactory.IntPtr.Type; + Signature.ReturnType.ContextModule?.CorLibTypeFactory.IntPtr.Type; /// public override bool IsImportedInModule(ModuleDefinition module) => Signature.IsImportedInModule(module); diff --git a/src/AsmResolver.DotNet/Signatures/GenericInstanceTypeSignature.cs b/src/AsmResolver.DotNet/Signatures/GenericInstanceTypeSignature.cs index 0c3ef1a29..2e373f02c 100644 --- a/src/AsmResolver.DotNet/Signatures/GenericInstanceTypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/GenericInstanceTypeSignature.cs @@ -86,7 +86,7 @@ public ITypeDefOrRef GenericType public IList TypeArguments => _typeArguments; /// - public override string? Name + public override string Name { get { @@ -102,16 +102,16 @@ public override string? Name public override IResolutionScope? Scope => GenericType.Scope; /// - public override ModuleDefinition? Module => GenericType.Module; + public override ModuleDefinition? ContextModule => GenericType.ContextModule; /// public override bool IsValueType => _isValueType; /// - public override TypeDefinition? Resolve() => GenericType.Resolve(); + public override TypeDefinition? Resolve(ModuleDefinition context) => GenericType.Resolve(context); /// - public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() => GenericType; + public override ITypeDefOrRef GetUnderlyingTypeDefOrRef() => GenericType; /// public override bool IsImportedInModule(ModuleDefinition module) @@ -137,13 +137,13 @@ public override bool IsImportedInModule(ModuleDefinition module) // Interfaces have System.Object as direct base class. if (genericType.IsInterface) - return Module!.CorLibTypeFactory.Object; + return ContextModule!.CorLibTypeFactory.Object; if (genericType.BaseType is not { } baseType) return null; // If the base type is not generic, treat it as a normal TypeDefOrRef. - if (baseType is TypeDefinition or TypeReference) + if (baseType.MetadataToken.Table is TableIndex.TypeDef or TableIndex.TypeRef) return baseType.ToTypeSignature(IsValueType); // At this point we expect a type specification. Substitute any generic type arguments present in it. diff --git a/src/AsmResolver.DotNet/Signatures/GenericParameterSignature.cs b/src/AsmResolver.DotNet/Signatures/GenericParameterSignature.cs index 394be9e31..9e0fcae72 100644 --- a/src/AsmResolver.DotNet/Signatures/GenericParameterSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/GenericParameterSignature.cs @@ -1,5 +1,4 @@ using System; -using AsmResolver.IO; using AsmResolver.PE.DotNet.Metadata.Tables; namespace AsmResolver.DotNet.Signatures @@ -81,10 +80,10 @@ public override IResolutionScope? Scope public override bool IsValueType => false; /// - public override TypeDefinition? Resolve() => null; + public override TypeDefinition? Resolve(ModuleDefinition context) => null; /// - public override bool IsImportedInModule(ModuleDefinition module) => Module == module; + public override bool IsImportedInModule(ModuleDefinition module) => ContextModule == module; /// public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() => null; diff --git a/src/AsmResolver.DotNet/Signatures/Parsing/CustomAttributeArgumentWriter.cs b/src/AsmResolver.DotNet/Signatures/Parsing/CustomAttributeArgumentWriter.cs index 1270d9785..cb028de89 100644 --- a/src/AsmResolver.DotNet/Signatures/Parsing/CustomAttributeArgumentWriter.cs +++ b/src/AsmResolver.DotNet/Signatures/Parsing/CustomAttributeArgumentWriter.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using AsmResolver.IO; using AsmResolver.PE.DotNet.Metadata.Tables; using AsmResolver.Shims; @@ -66,7 +65,7 @@ private void WriteNullElement(TypeSignature argumentType) case ElementType.Object: // Most efficient way to store "null" is writing null as a string (two bytes). - TypeSignature.WriteFieldOrPropType(_context, argumentType.Module!.CorLibTypeFactory.String); + TypeSignature.WriteFieldOrPropType(_context, argumentType.ContextModule!.CorLibTypeFactory.String); break; case ElementType.SzArray: @@ -168,7 +167,7 @@ private void WriteNonNullElement(TypeSignature argumentType, object element) $"Object elements in a custom attribute signature should be either 'null' or an instance of {nameof(BoxedArgument)}."); // Write null as a recovery. - innerTypeSig = argumentType.Module!.CorLibTypeFactory.String; + innerTypeSig = argumentType.ContextModule!.CorLibTypeFactory.String; value = null; } @@ -216,7 +215,7 @@ private void WriteEnumValue(TypeSignature argumentType, object? element) } // Try inferring the enum type from the argument value. - var corLibTypeFactory = argumentType.Module!.CorLibTypeFactory; + var corLibTypeFactory = argumentType.ContextModule!.CorLibTypeFactory; var elementType = Type.GetTypeCode(element.GetType()) switch { TypeCode.Boolean => corLibTypeFactory.Boolean, diff --git a/src/AsmResolver.DotNet/Signatures/Parsing/TypeNameBuilder.cs b/src/AsmResolver.DotNet/Signatures/Parsing/TypeNameBuilder.cs index b425928f7..9843ce05b 100644 --- a/src/AsmResolver.DotNet/Signatures/Parsing/TypeNameBuilder.cs +++ b/src/AsmResolver.DotNet/Signatures/Parsing/TypeNameBuilder.cs @@ -44,7 +44,7 @@ private void WriteTypeAssemblyQualifiedName(TypeSignature type) type.AcceptVisitor(this); var assembly = type.Scope?.GetAssembly(); - if (assembly is not null && assembly != type.Module?.Assembly) + if (assembly is not null && assembly != type.ContextModule?.Assembly) { _writer.Write(", "); WriteAssemblySpec(assembly); diff --git a/src/AsmResolver.DotNet/Signatures/SentinelTypeSignature.cs b/src/AsmResolver.DotNet/Signatures/SentinelTypeSignature.cs index 4f2ca2f2d..97bac6b1d 100644 --- a/src/AsmResolver.DotNet/Signatures/SentinelTypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/SentinelTypeSignature.cs @@ -37,7 +37,7 @@ private SentinelTypeSignature() } /// - public override TypeDefinition? Resolve() => throw new InvalidOperationException(); + public override TypeDefinition? Resolve(ModuleDefinition context) => throw new InvalidOperationException(); /// public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() => null; diff --git a/src/AsmResolver.DotNet/Signatures/SignatureComparer.TypeDefOrRef.cs b/src/AsmResolver.DotNet/Signatures/SignatureComparer.TypeDefOrRef.cs index 6dab7378d..a9c0fd72e 100644 --- a/src/AsmResolver.DotNet/Signatures/SignatureComparer.TypeDefOrRef.cs +++ b/src/AsmResolver.DotNet/Signatures/SignatureComparer.TypeDefOrRef.cs @@ -45,7 +45,7 @@ public bool Equals(ITypeDescriptor? x, ITypeDescriptor? y) desc = ts.Signature; } - if ((desc?.Module ?? desc?.Scope?.Module)?.CorLibTypeFactory.FromType(desc!) is { } corLibType) + if ((desc?.ContextModule ?? desc?.Scope?.ContextModule)?.CorLibTypeFactory.FromType(desc!) is { } corLibType) desc = corLibType; return desc; @@ -85,7 +85,7 @@ private bool SimpleTypeEquals(ITypeDescriptor x, ITypeDescriptor y) // It can still be an exported type, we need to resolve the type then and check if the definitions match. return x.Resolve() is { } definition1 && y.Resolve() is { } definition2 - && Equals(definition1.Module!.Assembly, definition2.Module!.Assembly) + && Equals(definition1.DeclaringModule!.Assembly, definition2.DeclaringModule!.Assembly) && Equals(definition1.DeclaringType, definition2.DeclaringType); } diff --git a/src/AsmResolver.DotNet/Signatures/SzArrayTypeSignature.cs b/src/AsmResolver.DotNet/Signatures/SzArrayTypeSignature.cs index 7528a221e..585af3934 100644 --- a/src/AsmResolver.DotNet/Signatures/SzArrayTypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/SzArrayTypeSignature.cs @@ -32,10 +32,9 @@ public SzArrayTypeSignature(TypeSignature baseType) public override IEnumerable GetDimensions() => SzDimensions; /// - public override TypeSignature? GetDirectBaseClass() => Module?.CorLibTypeFactory.CorLibScope + public override TypeSignature? GetDirectBaseClass() => ContextModule?.CorLibTypeFactory.CorLibScope .CreateTypeReference("System", "Array") - .ToTypeSignature(false) - .ImportWith(Module.DefaultImporter); + .ToTypeSignature(false); /// diff --git a/src/AsmResolver.DotNet/Signatures/TypeDefOrRefSignature.cs b/src/AsmResolver.DotNet/Signatures/TypeDefOrRefSignature.cs index 1af240870..5fcd20329 100644 --- a/src/AsmResolver.DotNet/Signatures/TypeDefOrRefSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/TypeDefOrRefSignature.cs @@ -49,7 +49,7 @@ public ITypeDefOrRef Type public override ElementType ElementType => IsValueType ? ElementType.ValueType : ElementType.Class; /// - public override string Name => Type?.Name ?? NullTypeToString; + public override string Name => Type.Name ?? NullTypeToString; /// public override string? Namespace => Type.Namespace; @@ -58,13 +58,13 @@ public ITypeDefOrRef Type public override IResolutionScope? Scope => Type.Scope; /// - public override ModuleDefinition? Module => Type.Module; + public override ModuleDefinition? ContextModule => Type.ContextModule; /// public override bool IsValueType => _isValueType; /// - public override TypeDefinition? Resolve() => Type.Resolve(); + public override TypeDefinition? Resolve(ModuleDefinition context) => Type.Resolve(context); /// public override bool IsImportedInModule(ModuleDefinition module) => Type.IsImportedInModule(module); @@ -73,7 +73,7 @@ public ITypeDefOrRef Type public override ITypeDefOrRef ToTypeDefOrRef() => Type; /// - public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() => Type; + public override ITypeDefOrRef GetUnderlyingTypeDefOrRef() => Type; /// public override TypeSignature GetUnderlyingType() @@ -104,7 +104,7 @@ public override TypeSignature GetReducedType() // Interfaces have System.Object as direct base class. return type.IsInterface - ? Module!.CorLibTypeFactory.Object + ? ContextModule!.CorLibTypeFactory.Object : type.BaseType!.ToTypeSignature(false).StripModifiers(); } diff --git a/src/AsmResolver.DotNet/Signatures/TypeSignature.cs b/src/AsmResolver.DotNet/Signatures/TypeSignature.cs index 141d8a013..facff54b5 100644 --- a/src/AsmResolver.DotNet/Signatures/TypeSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/TypeSignature.cs @@ -50,7 +50,7 @@ public abstract ElementType ElementType } /// - public virtual ModuleDefinition? Module => Scope?.Module; + public virtual ModuleDefinition? ContextModule => Scope?.ContextModule; /// public ITypeDescriptor? DeclaringType => Scope as ITypeDescriptor; @@ -297,10 +297,17 @@ internal static void WriteFieldOrPropType(BlobSerializationContext context, Type } /// - public abstract TypeDefinition? Resolve(); + public TypeDefinition? Resolve() => ContextModule is not null + ? Resolve(ContextModule) + : null; + + /// + public abstract TypeDefinition? Resolve(ModuleDefinition context); IMemberDefinition? IMemberDescriptor.Resolve() => Resolve(); + IMemberDefinition? IMemberDescriptor.Resolve(ModuleDefinition context) => Resolve(context); + /// public virtual ITypeDefOrRef ToTypeDefOrRef() => new TypeSpecification(this); diff --git a/src/AsmResolver.DotNet/Signatures/TypeSpecificationSignature.cs b/src/AsmResolver.DotNet/Signatures/TypeSpecificationSignature.cs index 981a3e37a..57b775d0d 100644 --- a/src/AsmResolver.DotNet/Signatures/TypeSpecificationSignature.cs +++ b/src/AsmResolver.DotNet/Signatures/TypeSpecificationSignature.cs @@ -24,7 +24,7 @@ public TypeSignature BaseType } /// - public override ModuleDefinition? Module => BaseType.Module; + public override ModuleDefinition? ContextModule => BaseType.ContextModule; /// public override string? Namespace => BaseType.Namespace; @@ -33,12 +33,10 @@ public TypeSignature BaseType public override IResolutionScope? Scope => BaseType.Scope; /// - public override TypeDefinition? Resolve() => - BaseType.Resolve(); + public override TypeDefinition? Resolve(ModuleDefinition context) => BaseType.Resolve(context); /// - public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() => - BaseType.GetUnderlyingTypeDefOrRef(); + public override ITypeDefOrRef? GetUnderlyingTypeDefOrRef() => BaseType.GetUnderlyingTypeDefOrRef(); /// public override bool IsImportedInModule(ModuleDefinition module) => BaseType.IsImportedInModule(module); diff --git a/src/AsmResolver.DotNet/TypeDefinition.cs b/src/AsmResolver.DotNet/TypeDefinition.cs index e9a8cd3a8..61210ebb7 100644 --- a/src/AsmResolver.DotNet/TypeDefinition.cs +++ b/src/AsmResolver.DotNet/TypeDefinition.cs @@ -5,9 +5,7 @@ using System.Linq; using System.Threading; using AsmResolver.Collections; -using AsmResolver.DotNet.Code.Cil; using AsmResolver.DotNet.Signatures; -using AsmResolver.PE.DotNet.Cil; using AsmResolver.PE.DotNet.Metadata.Tables; using AsmResolver.Shims; @@ -19,7 +17,6 @@ namespace AsmResolver.DotNet public class TypeDefinition : MetadataMember, ITypeDefOrRef, - IMemberDefinition, IHasGenericParameters, IHasSecurityDeclaration, IOwnedCollectionElement, @@ -450,7 +447,9 @@ public ITypeDefOrRef? BaseType /// /// Gets the module that defines the type. /// - public ModuleDefinition? Module => DeclaringType is not null ? DeclaringType.Module : _module; + public ModuleDefinition? DeclaringModule => DeclaringType is not null ? DeclaringType.DeclaringModule : _module; + + ModuleDefinition? IModuleProvider.ContextModule => DeclaringModule; /// /// When this type is nested, gets the enclosing type. @@ -517,15 +516,15 @@ public bool IsDelegate /// true if this is the global (i.e., <Module>) type, otherwise false. /// /// - /// If the global (i.e., <Module>) type was not added or does not exist yet in the , + /// If the global (i.e., <Module>) type was not added or does not exist yet in the , /// this will return false. /// - [MemberNotNullWhen(true, nameof(Module))] + [MemberNotNullWhen(true, nameof(DeclaringModule))] public bool IsModuleType { get { - var module = Module?.GetModuleType(); + var module = DeclaringModule?.GetModuleType(); return module != null && module == this; } } @@ -767,12 +766,12 @@ private bool FindInTypeTree(Predicate condition) /// public TypeSignature ToTypeSignature(bool isValueType) { - return Module?.CorLibTypeFactory.FromType(this) as TypeSignature + return DeclaringModule?.CorLibTypeFactory.FromType(this) as TypeSignature ?? new TypeDefOrRefSignature(this, isValueType); } /// - public bool IsImportedInModule(ModuleDefinition module) => Module == module; + public bool IsImportedInModule(ModuleDefinition module) => DeclaringModule == module; /// /// Imports the type definition using the provided reference importer object. @@ -800,7 +799,7 @@ public bool IsAccessibleFromType(TypeDefinition type) if (SignatureComparer.Default.Equals(this, type)) return true; - bool isInSameAssembly = SignatureComparer.Default.Equals(Module, type.Module); + bool isInSameAssembly = SignatureComparer.Default.Equals(DeclaringModule, type.DeclaringModule); // Most common case: A top-level types is accessible by all other types in the same assembly, or types in // a different assembly if this top-level type is public. @@ -848,22 +847,23 @@ public bool IsAccessibleFromType(TypeDefinition type) /// The type reference. public TypeReference ToTypeReference() { - var scope = DeclaringType?.ToTypeReference() ?? Module as IResolutionScope; + var scope = DeclaringType?.ToTypeReference() ?? DeclaringModule as IResolutionScope; - return new TypeReference(Module, scope, Namespace, Name); + return new TypeReference(DeclaringModule, scope, Namespace, Name); } private IResolutionScope? GetDeclaringScope() { if (DeclaringType is null) - return Module; + return DeclaringModule; return DeclaringType.ToTypeReference(); } TypeDefinition ITypeDescriptor.Resolve() => this; - + TypeDefinition ITypeDescriptor.Resolve(ModuleDefinition context) => this; IMemberDefinition IMemberDescriptor.Resolve() => this; + IMemberDefinition? IMemberDescriptor.Resolve(ModuleDefinition context) => this; /// /// When this type is an enum, extracts the underlying enum type. @@ -880,7 +880,7 @@ public TypeReference ToTypeReference() foreach (var field in Fields) { - if (!field.IsLiteral && !field.IsStatic && field.Signature != null) + if (field is { IsLiteral: false, IsStatic: false, Signature: not null }) return field.Signature.FieldType; } @@ -910,7 +910,7 @@ public TypeReference ToTypeReference() /// If the static constructor was not present in the type, it will be inserted as the first method in the type. /// This method can only be used when the type has already been added to the metadata image. /// - public MethodDefinition GetOrCreateStaticConstructor() => GetOrCreateStaticConstructor(Module); + public MethodDefinition GetOrCreateStaticConstructor() => GetOrCreateStaticConstructor(DeclaringModule); /// /// Gets or creates the static constructor that is executed when the CLR loads this type. diff --git a/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs b/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs index 09b4d1bef..7b47ed4e4 100644 --- a/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs +++ b/src/AsmResolver.DotNet/TypeDescriptorExtensions.cs @@ -159,7 +159,7 @@ public static GenericInstanceTypeSignature MakeGenericInstanceType( /// The constructed reference. public static TypeReference CreateTypeReference(this IResolutionScope scope, string? ns, string name) { - return new TypeReference(scope, ns, name); + return new TypeReference(scope.ContextModule, scope, ns, name); } /// @@ -171,7 +171,7 @@ public static TypeReference CreateTypeReference(this IResolutionScope scope, str /// The constructed reference. public static TypeReference CreateTypeReference(this IResolutionScope scope, Utf8String? ns, Utf8String name) { - return new TypeReference(scope, ns, name); + return new TypeReference(scope.ContextModule, scope, ns, name); } /// @@ -192,7 +192,7 @@ public static TypeReference CreateTypeReference(this ITypeDefOrRef declaringType _ => throw new ArgumentOutOfRangeException() }; - return new TypeReference(parent, null, nestedTypeName); + return new TypeReference(declaringType.ContextModule, parent, null, nestedTypeName); } /// @@ -213,7 +213,7 @@ public static TypeReference CreateTypeReference(this ITypeDefOrRef declaringType _ => throw new ArgumentOutOfRangeException() }; - return new TypeReference(parent, null, nestedTypeName); + return new TypeReference(declaringType.ContextModule, parent, null, nestedTypeName); } /// diff --git a/src/AsmResolver.DotNet/TypeReference.cs b/src/AsmResolver.DotNet/TypeReference.cs index 37b19b40c..f032ca16b 100644 --- a/src/AsmResolver.DotNet/TypeReference.cs +++ b/src/AsmResolver.DotNet/TypeReference.cs @@ -37,10 +37,14 @@ protected TypeReference(MetadataToken token) /// The scope that defines the type. /// The namespace the type resides in. /// The name of the type. + /// + /// The resulting type will inherit the context module from . + /// public TypeReference(IResolutionScope? scope, Utf8String? ns, Utf8String? name) : this(new MetadataToken(TableIndex.TypeRef, 0)) { _scope.SetValue(scope); + ContextModule = scope?.ContextModule; // Assume the scope defines the module context. Namespace = ns; Name = name; } @@ -48,15 +52,15 @@ public TypeReference(IResolutionScope? scope, Utf8String? ns, Utf8String? name) /// /// Creates a new reference to a type. /// - /// The module that references the type. + /// The module that references the type. /// The scope that defines the type. /// The namespace the type resides in. /// The name of the type. - public TypeReference(ModuleDefinition? module, IResolutionScope? scope, Utf8String? ns, Utf8String? name) + public TypeReference(ModuleDefinition? contextModule, IResolutionScope? scope, Utf8String? ns, Utf8String? name) : this(new MetadataToken(TableIndex.TypeRef, 0)) { _scope.SetValue(scope); - Module = module; + ContextModule = contextModule; Namespace = ns; Name = name; } @@ -104,8 +108,11 @@ public IResolutionScope? Scope public bool IsValueType => Resolve()?.IsValueType ?? false; /// - public ModuleDefinition? Module + public ModuleDefinition? ContextModule { + // Note: We cannot make this a computed property that returns `Scope.ContextModule`, because a TypeRef's + // scope can be null and still be "valid" (albeit not according to spec). In such a case the runtime + // assumes it references a type in the current module. We therefore have to keep track of it separately. get; protected set; } @@ -136,13 +143,13 @@ public IList CustomAttributes /// public TypeSignature ToTypeSignature(bool isValueType) { - return Module?.CorLibTypeFactory.FromType(this) as TypeSignature + return ContextModule?.CorLibTypeFactory.FromType(this) as TypeSignature ?? new TypeDefOrRefSignature(this, isValueType); } /// public bool IsImportedInModule(ModuleDefinition module) => - Module == module && (Scope?.IsImportedInModule(module) ?? false); + ContextModule == module && (Scope?.IsImportedInModule(module) ?? false); /// /// Imports the type reference using the provided reference importer object. @@ -155,10 +162,15 @@ public bool IsImportedInModule(ModuleDefinition module) => IImportable IImportable.ImportWith(ReferenceImporter importer) => ImportWith(importer); /// - public TypeDefinition? Resolve() => Module?.MetadataResolver.ResolveType(this); + public TypeDefinition? Resolve() => ContextModule is { } context ? Resolve(context) : null; + + /// + public TypeDefinition? Resolve(ModuleDefinition context) => context.MetadataResolver.ResolveType(this); IMemberDefinition? IMemberDescriptor.Resolve() => Resolve(); + IMemberDefinition? IMemberDescriptor.Resolve(ModuleDefinition context) => Resolve(context); + /// /// Obtains the name of the type reference. /// diff --git a/src/AsmResolver.DotNet/TypeSpecification.cs b/src/AsmResolver.DotNet/TypeSpecification.cs index 66628dfb5..ce5fef315 100644 --- a/src/AsmResolver.DotNet/TypeSpecification.cs +++ b/src/AsmResolver.DotNet/TypeSpecification.cs @@ -64,7 +64,7 @@ public TypeSignature? Signature public string FullName => MemberNameGenerator.GetTypeFullName(this); /// - public ModuleDefinition? Module => Signature?.Module; + public ModuleDefinition? ContextModule => Signature?.ContextModule; /// public IResolutionScope? Scope => Signature?.Scope; @@ -112,10 +112,15 @@ public TypeSignature ToTypeSignature() => IImportable IImportable.ImportWith(ReferenceImporter importer) => ImportWith(importer); /// - public TypeDefinition? Resolve() => Module?.MetadataResolver.ResolveType(this); + public TypeDefinition? Resolve() => ContextModule is { } context ? Resolve(context) : null; + + /// + public TypeDefinition? Resolve(ModuleDefinition context) => ContextModule?.MetadataResolver.ResolveType(this); IMemberDefinition? IMemberDescriptor.Resolve() => Resolve(); + IMemberDefinition? IMemberDescriptor.Resolve(ModuleDefinition context) => Resolve(context); + /// /// Obtains the signature the type specification is referencing. /// diff --git a/test/AsmResolver.DotNet.Tests/AccessibilityTest.Fields.cs b/test/AsmResolver.DotNet.Tests/AccessibilityTest.Fields.cs index 219942bd5..cefc24539 100644 --- a/test/AsmResolver.DotNet.Tests/AccessibilityTest.Fields.cs +++ b/test/AsmResolver.DotNet.Tests/AccessibilityTest.Fields.cs @@ -7,7 +7,7 @@ public partial class AccessibilityTest { private static FieldDefinition AddField(TypeDefinition declaringType, string name, FieldAttributes attributes) { - var field = new FieldDefinition(name, attributes, declaringType.Module!.CorLibTypeFactory.Object); + var field = new FieldDefinition(name, attributes, declaringType.DeclaringModule!.CorLibTypeFactory.Object); declaringType.Fields.Add(field); return field; } diff --git a/test/AsmResolver.DotNet.Tests/AccessibilityTest.Methods.cs b/test/AsmResolver.DotNet.Tests/AccessibilityTest.Methods.cs index bddd97243..0bda0d4fd 100644 --- a/test/AsmResolver.DotNet.Tests/AccessibilityTest.Methods.cs +++ b/test/AsmResolver.DotNet.Tests/AccessibilityTest.Methods.cs @@ -8,7 +8,7 @@ public partial class AccessibilityTest { private static MethodDefinition AddMethod(TypeDefinition declaringType, string name, MethodAttributes attributes) { - var method = new MethodDefinition(name, attributes, MethodSignature.CreateInstance(declaringType.Module!.CorLibTypeFactory.Void)); + var method = new MethodDefinition(name, attributes, MethodSignature.CreateInstance(declaringType.DeclaringModule!.CorLibTypeFactory.Void)); declaringType.Methods.Add(method); return method; } diff --git a/test/AsmResolver.DotNet.Tests/AccessibilityTest.Types.cs b/test/AsmResolver.DotNet.Tests/AccessibilityTest.Types.cs index fc9d7e2a0..91bf8d53e 100644 --- a/test/AsmResolver.DotNet.Tests/AccessibilityTest.Types.cs +++ b/test/AsmResolver.DotNet.Tests/AccessibilityTest.Types.cs @@ -23,7 +23,7 @@ private static TypeDefinition AddTopLevelType(ModuleDefinition module, string na private static TypeDefinition AddNestedType(TypeDefinition declaringType, string name, TypeAttributes attributes, ITypeDefOrRef baseType = null) { - var type = new TypeDefinition(null, name, attributes, baseType ?? declaringType.Module!.CorLibTypeFactory.Object.Type); + var type = new TypeDefinition(null, name, attributes, baseType ?? declaringType.DeclaringModule!.CorLibTypeFactory.Object.Type); declaringType.NestedTypes.Add(type); return type; } diff --git a/test/AsmResolver.DotNet.Tests/AssemblyReferenceTest.cs b/test/AsmResolver.DotNet.Tests/AssemblyReferenceTest.cs index 984df2161..70e76b085 100644 --- a/test/AsmResolver.DotNet.Tests/AssemblyReferenceTest.cs +++ b/test/AsmResolver.DotNet.Tests/AssemblyReferenceTest.cs @@ -67,5 +67,49 @@ public void CorLibResolution() Assert.Equal(assemblyDef.Name, assemblyDef.Name); Assert.Equal(assemblyDef.Version, assemblyDef.Version); } + + [Fact] + public void CreateTypeReferenceFromImportedAssemblyShouldBeImported() + { + var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld, TestReaderParameters); + var systemConsole = new AssemblyReference("System.Console", new Version(8, 0, 0, 0)); + module.DefaultImporter.ImportScope(systemConsole); + + var someAssembly = new AssemblyReference("SomeAssembly", new Version(1, 2, 3, 4)); + module.AssemblyReferences.Add(someAssembly); + + var reference = someAssembly.CreateTypeReference("Namespace", "Type"); + Assert.True(reference.IsImportedInModule(module)); + } + + [Fact] + public void CreateTypeReferenceFromNonImportedAssemblyShouldNotBeImported() + { + var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld, TestReaderParameters); + var someAssembly = new AssemblyReference("SomeAssembly", new Version(1, 2, 3, 4)); + + var reference = someAssembly.CreateTypeReference("Namespace", "Type"); + Assert.False(reference.IsImportedInModule(module)); + } + + [Fact] + public void CreateClassGenericType() + { + var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld, TestReaderParameters); + var genericType = module.CorLibTypeFactory.CorLibScope + .CreateTypeReference("System.Collections.Generic", "List`1") + .MakeGenericInstanceType(module.CorLibTypeFactory.Int32); + Assert.False(genericType.IsValueType); + } + + [Fact] + public void CreateValueTypeGenericType() + { + var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld, TestReaderParameters); + var genericType = module.CorLibTypeFactory.CorLibScope + .CreateTypeReference("System", "Nullable`1") + .MakeGenericInstanceType(module.CorLibTypeFactory.Int32); + Assert.True(genericType.IsValueType); + } } } diff --git a/test/AsmResolver.DotNet.Tests/Builder/ManagedPEImageBuilderTest.cs b/test/AsmResolver.DotNet.Tests/Builder/ManagedPEImageBuilderTest.cs index ae19f741b..c134113ea 100644 --- a/test/AsmResolver.DotNet.Tests/Builder/ManagedPEImageBuilderTest.cs +++ b/test/AsmResolver.DotNet.Tests/Builder/ManagedPEImageBuilderTest.cs @@ -182,29 +182,6 @@ public void PreserveUnknownStreamsAndStreamOrder() Assert.Equal(data, Assert.IsAssignableFrom(newStream.Contents).ToArray()); } - [Fact] - public void BuildInvalidImageShouldRegisterDiagnostics() - { - // Prepare temp assembly. - var assembly = new AssemblyDefinition("Assembly", new Version(1, 0, 0, 0)); - var module = new ModuleDefinition("Module"); - assembly.Modules.Add(module); - - // Add some field with an non-imported field type. - module.GetOrCreateModuleType().Fields.Add(new FieldDefinition( - "Field", - FieldAttributes.Static, - new TypeReference(null, "NonImportedNamespace", "NonImportedType").ToTypeSignature())); - - // Build. - var bag = new DiagnosticBag(); - var image = module.ToPEImage(new ManagedPEImageBuilder(bag), false); - - // Verify diagnostics. - Assert.NotNull(image); - Assert.Contains(bag.Exceptions, x => x is MemberNotImportedException); - } - [Fact] public void BuildingImageShouldConsiderJTDStreamAndUseLargeColumns() { diff --git a/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/EventTokenPreservationTest.cs b/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/EventTokenPreservationTest.cs index 4115046c6..0a663c7ca 100644 --- a/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/EventTokenPreservationTest.cs +++ b/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/EventTokenPreservationTest.cs @@ -45,8 +45,8 @@ private static EventDefinition CreateDummyEventToType(TypeDefinition dummyType, // Create signature for add/remove methods. var signature = MethodSignature.CreateStatic( - eventHandlerTypeRef.Module!.CorLibTypeFactory.Void, - eventHandlerTypeRef.Module.CorLibTypeFactory.Object, + eventHandlerTypeRef.ContextModule!.CorLibTypeFactory.Void, + eventHandlerTypeRef.ContextModule.CorLibTypeFactory.Object, eventHandlerTypeSig); var methodAttributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName diff --git a/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/PropertyTokenPreservationTest.cs b/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/PropertyTokenPreservationTest.cs index 785e414fb..23c7fc198 100644 --- a/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/PropertyTokenPreservationTest.cs +++ b/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/PropertyTokenPreservationTest.cs @@ -31,13 +31,13 @@ private static PropertyDefinition CreateDummyProperty(TypeDefinition dummyType, var property = new PropertyDefinition( name, PropertyAttributes.None, - PropertySignature.CreateStatic(dummyType.Module!.CorLibTypeFactory.Object) + PropertySignature.CreateStatic(dummyType.DeclaringModule!.CorLibTypeFactory.Object) ); var getMethod = new MethodDefinition( $"get_{property.Name}", MethodAttributes.Public | MethodAttributes.Static, - MethodSignature.CreateStatic(dummyType.Module.CorLibTypeFactory.Object) + MethodSignature.CreateStatic(dummyType.DeclaringModule.CorLibTypeFactory.Object) ); getMethod.CilMethodBody = new CilMethodBody diff --git a/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/TypeRefTokenPreservationTest.cs b/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/TypeRefTokenPreservationTest.cs index ecc503c9f..33af0dc53 100644 --- a/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/TypeRefTokenPreservationTest.cs +++ b/test/AsmResolver.DotNet.Tests/Builder/TokenPreservation/TypeRefTokenPreservationTest.cs @@ -106,12 +106,8 @@ public void PreserveDuplicatedTypeRefsInBaseType() var assembly = new AssemblyDefinition("Test", new Version(1, 0, 0, 0)); assembly.Modules.Add(module); - var ref1 = (TypeReference) module.CorLibTypeFactory.CorLibScope - .CreateTypeReference("System", "Object") - .ImportWith(module.DefaultImporter); - var ref2 = (TypeReference) module.CorLibTypeFactory.CorLibScope - .CreateTypeReference("System", "Object") - .ImportWith(module.DefaultImporter); + var ref1 = module.CorLibTypeFactory.CorLibScope.CreateTypeReference("System", "Object"); + var ref2 = module.CorLibTypeFactory.CorLibScope.CreateTypeReference("System", "Object"); // Force assign new tokens to instruct builder that both type references need to be added. module.TokenAllocator.AssignNextAvailableToken(ref1); diff --git a/test/AsmResolver.DotNet.Tests/Cloning/MetadataClonerTest.cs b/test/AsmResolver.DotNet.Tests/Cloning/MetadataClonerTest.cs index 024f063ad..28e3dbe14 100644 --- a/test/AsmResolver.DotNet.Tests/Cloning/MetadataClonerTest.cs +++ b/test/AsmResolver.DotNet.Tests/Cloning/MetadataClonerTest.cs @@ -271,7 +271,7 @@ public void ReferencesToMethodSpecs() .Operand; Assert.Equal(originalSpec, newSpec, _signatureComparer); - Assert.NotSame(originalSpec.Module, newSpec.Module); + Assert.NotSame(originalSpec.ContextModule, newSpec.ContextModule); } [Fact] diff --git a/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs b/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs index 353c1892e..5dae7920d 100644 --- a/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs +++ b/test/AsmResolver.DotNet.Tests/Code/Cil/CilMethodBodyTest.cs @@ -29,7 +29,7 @@ private static CilMethodBody GetMethodBodyInModule(ModuleDefinition module, stri private CilMethodBody RebuildAndLookup(CilMethodBody methodBody) { - var module = methodBody.Owner.Module!; + var module = methodBody.Owner!.DeclaringModule!; var stream = new MemoryStream(); module.Write(stream); @@ -236,7 +236,7 @@ public void ExceptionHandlerExpectsOneValueOnStack() body.ExceptionHandlers.Add(new CilExceptionHandler { HandlerType = CilExceptionHandlerType.Exception, - ExceptionType = body.Owner.Module.CorLibTypeFactory.Object.ToTypeDefOrRef(), + ExceptionType = body.Owner.DeclaringModule.CorLibTypeFactory.Object.ToTypeDefOrRef(), TryStart = tryStart, TryEnd = tryEnd, HandlerStart = handlerStart, @@ -267,7 +267,7 @@ public void FinallyHandlerExpectsNoValueOnStack() body.ExceptionHandlers.Add(new CilExceptionHandler { HandlerType = CilExceptionHandlerType.Finally, - ExceptionType = body.Owner.Module.CorLibTypeFactory.Object.ToTypeDefOrRef(), + ExceptionType = body.Owner.DeclaringModule.CorLibTypeFactory.Object.ToTypeDefOrRef(), TryStart = tryStart, TryEnd = tryEnd, HandlerStart = handlerStart, @@ -298,7 +298,7 @@ public void LeaveInstructionShouldClearStackAndNotFail() body.ExceptionHandlers.Add(new CilExceptionHandler { HandlerType = CilExceptionHandlerType.Exception, - ExceptionType = body.Owner.Module.CorLibTypeFactory.Object.ToTypeDefOrRef(), + ExceptionType = body.Owner.DeclaringModule.CorLibTypeFactory.Object.ToTypeDefOrRef(), TryStart = tryStart, TryEnd = tryEnd, HandlerStart = handlerStart, @@ -360,7 +360,7 @@ public void UnreachableExceptionHandlerShouldNotBeScheduled() body.ExceptionHandlers.Add(new CilExceptionHandler { HandlerType = CilExceptionHandlerType.Exception, - ExceptionType = body.Owner!.Module!.CorLibTypeFactory.Object.ToTypeDefOrRef(), + ExceptionType = body.Owner!.DeclaringModule!.CorLibTypeFactory.Object.ToTypeDefOrRef(), TryStart = start, TryEnd = handler, HandlerStart = handler, @@ -395,7 +395,7 @@ public void EnterTryBlockWithNonEmptyStackShouldThrow() body.ExceptionHandlers.Add(new CilExceptionHandler { HandlerType = CilExceptionHandlerType.Exception, - ExceptionType = body.Owner!.Module!.CorLibTypeFactory.Object.ToTypeDefOrRef(), + ExceptionType = body.Owner!.DeclaringModule!.CorLibTypeFactory.Object.ToTypeDefOrRef(), TryStart = start, TryEnd = handler, HandlerStart = handler, diff --git a/test/AsmResolver.DotNet.Tests/Code/Native/NativeMethodBodyTest.cs b/test/AsmResolver.DotNet.Tests/Code/Native/NativeMethodBodyTest.cs index ec0fe87d5..6a851e511 100644 --- a/test/AsmResolver.DotNet.Tests/Code/Native/NativeMethodBodyTest.cs +++ b/test/AsmResolver.DotNet.Tests/Code/Native/NativeMethodBodyTest.cs @@ -82,8 +82,7 @@ public void NativeMethodBodyShouldResultInRawCodeSegment() }; // Serialize module to PE image. - var module = body.Owner.Module!; - var image = module.ToPEImage(); + var image = body.Owner!.DeclaringModule!.ToPEImage(); // Lookup method row. var segment = GetNewCodeSegment(image); @@ -124,8 +123,7 @@ public void NativeMethodBodyImportedSymbolShouldEndUpInImportsDirectory() )); // Serialize module to PE image. - var module = body.Owner.Module!; - var image = module.ToPEImage(); + var image = body.Owner!.DeclaringModule!.ToPEImage(); // Verify import is added to PE image. Assert.Contains(image.Imports, m => @@ -161,8 +159,7 @@ public void Native32BitMethodShouldResultInBaseRelocation() )); // Serialize module to PE image. - var module = body.Owner.Module!; - var image = module.ToPEImage(); + var image = body.Owner!.DeclaringModule!.ToPEImage(); // Verify import is added to PE image. Assert.Contains(image.Imports, m => @@ -215,8 +212,7 @@ public void DuplicateImportedSymbolsShouldResultInSameImportInImage() )); // Serialize module to PE image. - var module = body.Owner.Module!; - var image = module.ToPEImage(); + var image = body.Owner!.DeclaringModule!.ToPEImage(); // Verify import is added to PE image. var importedModule = Assert.Single(image.Imports); @@ -239,9 +235,8 @@ public void ReadNativeMethodShouldResultInReferenceWithRightContents() }; // Serialize module. - var module = body.Owner.Module!; using var stream = new MemoryStream(); - module.Write(stream); + body.Owner!.DeclaringModule!.Write(stream); // Reload and look up native method. var newModule = ModuleDefinition.FromBytes(stream.ToArray(), TestReaderParameters); @@ -294,7 +289,7 @@ public void NativeBodyWithLocalSymbols(bool is32Bit, byte[] movInstruction, uint // Verify. _fixture .GetRunner() - .RebuildAndRun(body.Owner.Module!, "StringPointer.exe", "Hello, world!\n"); + .RebuildAndRun(body.Owner!.DeclaringModule!, "StringPointer.exe", "Hello, world!\n"); } [SkippableTheory] @@ -326,7 +321,7 @@ public void NativeBodyWithGlobalSymbol(bool is32Bit, byte[] movInstruction, uint InjectCallToNativeBody(body, messageSymbol, fixupOffset, fixupType); // Add symbol to new section. - var image = body.Owner.Module!.ToPEImage(); + var image = body.Owner!.DeclaringModule!.ToPEImage(); var file = new ManagedPEFileBuilder().CreateFile(image); file.Sections.Add(new PESection( ".asmres", @@ -345,23 +340,21 @@ private static void InjectCallToNativeBody(NativeMethodBody body, ISymbol messag body.AddressFixups.Add(new AddressFixup(fixupOffset, fixupType, messageSymbol)); // Update main to call native method, convert the returned pointer to a String, and write to stdout. - var module = body.Owner.Module!; + var module = body.Owner!.DeclaringModule!; body.Owner.Signature!.ReturnType = module.CorLibTypeFactory.IntPtr; var stringConstructor = module.CorLibTypeFactory.String.Type .CreateMemberReference(".ctor", MethodSignature.CreateInstance( - module.CorLibTypeFactory.Void, - module.CorLibTypeFactory.Char.MakePointerType() - )) - .ImportWith(module.DefaultImporter); + module.CorLibTypeFactory.Void, + module.CorLibTypeFactory.Char.MakePointerType() + )); var writeLine = module.CorLibTypeFactory.CorLibScope .CreateTypeReference("System", "Console") .CreateMemberReference("WriteLine", MethodSignature.CreateStatic( - module.CorLibTypeFactory.Void, - module.CorLibTypeFactory.String - )) - .ImportWith(module.DefaultImporter); + module.CorLibTypeFactory.Void, + module.CorLibTypeFactory.String + )); var instructions = module.ManagedEntryPointMethod!.CilMethodBody!.Instructions; instructions.Clear(); diff --git a/test/AsmResolver.DotNet.Tests/Collections/ParameterCollectionTest.cs b/test/AsmResolver.DotNet.Tests/Collections/ParameterCollectionTest.cs index 39506a6c7..2ff43f8b4 100644 --- a/test/AsmResolver.DotNet.Tests/Collections/ParameterCollectionTest.cs +++ b/test/AsmResolver.DotNet.Tests/Collections/ParameterCollectionTest.cs @@ -146,21 +146,25 @@ public void ReadReturnTypeFromStaticParameterlessMethod() public void UpdateReturnTypeFromStaticParameterlessMethodShouldThrow() { var method = ObtainStaticTestMethod(nameof(MultipleMethods.VoidParameterlessMethod)); - Assert.Throws(() => method.Parameters.ReturnParameter.ParameterType = method.Module.CorLibTypeFactory.Int32); + Assert.Throws( + () => method.Parameters.ReturnParameter.ParameterType = method.DeclaringModule!.CorLibTypeFactory.Int32 + ); } [Fact] public void UpdateThisParameterParameterTypeShouldThrow() { var method = ObtainInstanceTestMethod(nameof(InstanceMethods.InstanceParameterlessMethod)); - Assert.Throws(() => method.Parameters.ThisParameter.ParameterType = method.Module.CorLibTypeFactory.Int32); + Assert.Throws( + () => method.Parameters.ThisParameter!.ParameterType = method.DeclaringModule!.CorLibTypeFactory.Int32 + ); } [Fact] public void MoveMethodToOtherTypeShouldUpdateThisParameter() { var method = ObtainInstanceTestMethod(nameof(InstanceMethods.InstanceParameterlessMethod)); - var newType = method.Module.TopLevelTypes.First(t => t.Name == nameof(MultipleMethods)); + var newType = method.DeclaringModule!.TopLevelTypes.First(t => t.Name == nameof(MultipleMethods)); method.DeclaringType.Methods.Remove(method); newType.Methods.Add(method); diff --git a/test/AsmResolver.DotNet.Tests/ConstantTest.cs b/test/AsmResolver.DotNet.Tests/ConstantTest.cs index 31c64e533..579ba3613 100644 --- a/test/AsmResolver.DotNet.Tests/ConstantTest.cs +++ b/test/AsmResolver.DotNet.Tests/ConstantTest.cs @@ -69,7 +69,7 @@ public void ReadAndInterpretData(string name, object expected) public void PersistentConstants(string name) { var constant = GetFieldConstant(name); - var newConstant = RebuildAndLookup(constant.Parent.Module, name); + var newConstant = RebuildAndLookup(constant.Parent!.DeclaringModule, name); Assert.NotNull(newConstant); Assert.Equal(constant.Value.Data, newConstant.Value.Data); } diff --git a/test/AsmResolver.DotNet.Tests/CustomAttributeTest.cs b/test/AsmResolver.DotNet.Tests/CustomAttributeTest.cs index 0a99bdc7b..079169f8a 100644 --- a/test/AsmResolver.DotNet.Tests/CustomAttributeTest.cs +++ b/test/AsmResolver.DotNet.Tests/CustomAttributeTest.cs @@ -4,7 +4,6 @@ using AsmResolver.DotNet.Signatures; using AsmResolver.DotNet.TestCases.CustomAttributes; using AsmResolver.DotNet.TestCases.Properties; -using AsmResolver.IO; using AsmResolver.PE; using AsmResolver.PE.DotNet.Metadata; using AsmResolver.PE.DotNet.Metadata.Tables; @@ -101,7 +100,7 @@ private static CustomAttribute RebuildAndLookup(CustomAttribute attribute) { var stream = new MemoryStream(); var method = (MethodDefinition) attribute.Parent!; - method.Module!.Write(stream); + method.DeclaringModule!.Write(stream); var newModule = ModuleDefinition.FromBytes(stream.ToArray(), TestReaderParameters); return newModule @@ -226,7 +225,7 @@ public void FixedTypeArgument(bool rebuild, bool access) var argument = attribute.Signature.FixedArguments[0]; Assert.Equal( - attribute.Constructor!.Module!.CorLibTypeFactory.String, + attribute.Constructor!.ContextModule!.CorLibTypeFactory.String, argument.Element as TypeSignature, _comparer); } @@ -241,7 +240,7 @@ public void FixedComplexTypeArgument(bool rebuild, bool access) Assert.Empty(attribute.Signature.NamedArguments); var argument = attribute.Signature.FixedArguments[0]; - var factory = attribute.Constructor!.Module!.CorLibTypeFactory; + var factory = attribute.Constructor!.ContextModule!.CorLibTypeFactory; var instance = factory.CorLibScope .CreateTypeReference("System.Collections.Generic", "KeyValuePair`2") @@ -264,7 +263,7 @@ public void FixedGenericNestedTypeArgument(bool rebuild, bool access) Assert.Empty(attribute.Signature!.NamedArguments); var argument = Assert.Single(attribute.Signature.FixedArguments); - var factory = attribute.Constructor!.Module!.CorLibTypeFactory; + var factory = attribute.Constructor!.ContextModule!.CorLibTypeFactory; var expected = factory.CorLibScope .CreateTypeReference("System.Collections.Generic", "List`1") .CreateTypeReference("Enumerator") @@ -345,7 +344,7 @@ public void NamedTypeArgument(bool rebuild, bool access) Assert.Single(attribute.Signature.NamedArguments); var expected = new TypeReference( - attribute.Constructor!.Module!.CorLibTypeFactory.CorLibScope, + attribute.Constructor!.ContextModule!.CorLibTypeFactory.CorLibScope, "System", "Int32"); var argument = attribute.Signature.NamedArguments[0]; @@ -390,7 +389,7 @@ public void GenericTypeArgument(bool rebuild, bool access) var attribute = GetCustomAttributeTestCase(nameof(CustomAttributesTestClass.GenericType),rebuild, access); var argument = attribute.Signature!.FixedArguments[0]; - var module = attribute.Constructor!.Module!; + var module = attribute.Constructor!.ContextModule!; var nestedClass = (TypeDefinition) module.LookupMember(typeof(TestGenericType<>).MetadataToken); var expected = nestedClass.MakeGenericInstanceType(false, module.CorLibTypeFactory.Object); @@ -409,7 +408,7 @@ public void ArrayGenericTypeArgument(bool rebuild, bool access) var attribute = GetCustomAttributeTestCase(nameof(CustomAttributesTestClass.GenericTypeArray),rebuild, access); var argument = attribute.Signature!.FixedArguments[0]; - var module = attribute.Constructor!.Module!; + var module = attribute.Constructor!.ContextModule!; var nestedClass = (TypeDefinition) module.LookupMember(typeof(TestGenericType<>).MetadataToken); var expected = nestedClass .MakeGenericInstanceType(false, module.CorLibTypeFactory.Object) @@ -445,7 +444,7 @@ public void TypePassedOnAsObject(bool rebuild, bool access) var attribute = GetCustomAttributeTestCase(nameof(CustomAttributesTestClass.TypePassedAsObject),rebuild, access); var argument = attribute.Signature!.FixedArguments[0]; - var module = attribute.Constructor!.Module!; + var module = attribute.Constructor!.ContextModule!; var element = Assert.IsAssignableFrom(argument.Element); Assert.Equal(module.CorLibTypeFactory.Int32, (ITypeDescriptor) element.Value, _comparer); } @@ -638,7 +637,7 @@ public void FixedGenericTypeArgument(bool rebuild, bool access) rebuild, access, true); var argument = attribute.Signature!.FixedArguments[0]; - var expected = attribute.Constructor!.Module!.CorLibTypeFactory.Int32; + var expected = attribute.Constructor!.ContextModule!.CorLibTypeFactory.Int32; var element = Assert.IsAssignableFrom(argument.Element); Assert.Equal(expected, element, _comparer); } @@ -728,7 +727,7 @@ public void NamedGenericTypeArgument(bool rebuild, bool access) rebuild, access, true); var argument = attribute.Signature!.NamedArguments[0]; - var expected = attribute.Constructor!.Module!.CorLibTypeFactory.Int32; + var expected = attribute.Constructor!.ContextModule!.CorLibTypeFactory.Int32; var element = Assert.IsAssignableFrom(argument.Argument.Element); Assert.Equal(expected, element, _comparer); } @@ -753,8 +752,7 @@ public void TestSignatureCompatibility() var factory = module.CorLibTypeFactory; var ctor = factory.CorLibScope .CreateTypeReference("System", "CLSCompliantAttribute") - .CreateMemberReference(".ctor", MethodSignature.CreateInstance(factory.Void, factory.Boolean)) - .ImportWith(module.DefaultImporter); + .CreateMemberReference(".ctor", MethodSignature.CreateInstance(factory.Void, factory.Boolean)); var attribute = new CustomAttribute(ctor); diff --git a/test/AsmResolver.DotNet.Tests/DotNetRuntimeInfoTest.cs b/test/AsmResolver.DotNet.Tests/DotNetRuntimeInfoTest.cs index 45ad11b3c..ec161aa90 100644 --- a/test/AsmResolver.DotNet.Tests/DotNetRuntimeInfoTest.cs +++ b/test/AsmResolver.DotNet.Tests/DotNetRuntimeInfoTest.cs @@ -35,9 +35,9 @@ public void Parse(string name, string expectedFramework, int major, int minor) [InlineData(".NETCoreApp,Version=v10.0", "System.Runtime, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public void DefaultCorLib(string name, string expectedCorLib) { - Assert.Equal( + Assert.Equal( new ReflectionAssemblyDescriptor(new AssemblyName(expectedCorLib)), - (AssemblyDescriptor) DotNetRuntimeInfo.Parse(name).GetDefaultCorLib(), + DotNetRuntimeInfo.Parse(name).GetDefaultCorLib(), SignatureComparer.Default ); } diff --git a/test/AsmResolver.DotNet.Tests/FieldDefinitionTest.cs b/test/AsmResolver.DotNet.Tests/FieldDefinitionTest.cs index f2c27a926..750828e82 100644 --- a/test/AsmResolver.DotNet.Tests/FieldDefinitionTest.cs +++ b/test/AsmResolver.DotNet.Tests/FieldDefinitionTest.cs @@ -16,7 +16,7 @@ public class FieldDefinitionTest private FieldDefinition RebuildAndLookup(FieldDefinition field) { var stream = new MemoryStream(); - field.Module.Write(stream); + field.DeclaringModule.Write(stream); var newModule = ModuleDefinition.FromBytes(stream.ToArray(), TestReaderParameters); return newModule diff --git a/test/AsmResolver.DotNet.Tests/ImplementationMapTest.cs b/test/AsmResolver.DotNet.Tests/ImplementationMapTest.cs index 7ef08c8ec..9d7c16bfc 100644 --- a/test/AsmResolver.DotNet.Tests/ImplementationMapTest.cs +++ b/test/AsmResolver.DotNet.Tests/ImplementationMapTest.cs @@ -27,7 +27,7 @@ private static MethodDefinition LookupMethod(string methodName) private ImplementationMap RebuildAndLookup(ImplementationMap implementationMap) { using var stream = new MemoryStream(); - implementationMap.MemberForwarded.Module.Write(stream); + implementationMap.MemberForwarded!.DeclaringModule!.Write(stream); var newModule = ModuleDefinition.FromBytes(stream.ToArray(), TestReaderParameters); var t = newModule.TopLevelTypes.First(t => t.Name == nameof(PlatformInvoke)); @@ -63,7 +63,7 @@ public void PersistentScope() var map = Lookup(nameof(PlatformInvoke.ExternalMethod)); var newModule = new ModuleReference("SomeOtherDll.dll"); - map.MemberForwarded.Module.ModuleReferences.Add(newModule); + map.MemberForwarded!.DeclaringModule!.ModuleReferences.Add(newModule); map.Scope = newModule; var newMap = RebuildAndLookup(map); @@ -89,7 +89,7 @@ public void RemoveMapShouldUnsetMemberForwarded() public void AddingAlreadyAddedMapToAnotherMemberShouldThrow() { var map = Lookup(nameof(PlatformInvoke.ExternalMethod)); - var declaringType = (TypeDefinition) map.MemberForwarded.DeclaringType; + var declaringType = map.MemberForwarded.DeclaringType; var otherMethod = declaringType.Methods.First(m => m.Name == nameof(PlatformInvoke.NonImplementationMapMethod)); diff --git a/test/AsmResolver.DotNet.Tests/MetadataResolverTest.cs b/test/AsmResolver.DotNet.Tests/MetadataResolverTest.cs index 36e6db78e..db112d481 100644 --- a/test/AsmResolver.DotNet.Tests/MetadataResolverTest.cs +++ b/test/AsmResolver.DotNet.Tests/MetadataResolverTest.cs @@ -150,7 +150,7 @@ public void ResolveTypeWithModuleScope() var definition = reference.Resolve(); Assert.NotNull(definition); - Assert.Same(module, definition.Module); + Assert.Same(module, definition.DeclaringModule); } [Fact] @@ -162,7 +162,7 @@ public void ResolveTypeWithNullScopeCurrentModule() var definition = reference.Resolve(); Assert.NotNull(definition); - Assert.Same(module, definition.Module); + Assert.Same(module, definition.DeclaringModule); } [Fact] @@ -174,7 +174,7 @@ public void ResolveTypeWithNullScopeExportedType() var definition = reference.Resolve(); Assert.NotNull(definition); - Assert.Equal("mscorlib", definition.Module!.Assembly!.Name); + Assert.Equal("mscorlib", definition.DeclaringModule!.Assembly!.Name); } [Fact] diff --git a/test/AsmResolver.DotNet.Tests/ModuleDefinitionTest.cs b/test/AsmResolver.DotNet.Tests/ModuleDefinitionTest.cs index d2ae9a479..683a997e7 100644 --- a/test/AsmResolver.DotNet.Tests/ModuleDefinitionTest.cs +++ b/test/AsmResolver.DotNet.Tests/ModuleDefinitionTest.cs @@ -500,8 +500,8 @@ public void NewModuleShouldContainSingleReferenceToCorLib() public void RewriteSystemPrivateCoreLib() { string runtimePath = DotNetCorePathProvider.Default - .GetRuntimePathCandidates("Microsoft.NETCore.App", new Version(3, 1, 0)) - .FirstOrDefault() ?? throw new InvalidOperationException(".NET Core 3.1 is not installed."); + .GetRuntimePathCandidates("Microsoft.NETCore.App", new Version(8, 0, 0)) + .FirstOrDefault() ?? throw new InvalidOperationException(".NET Core 8.0 is not installed."); var module = ModuleDefinition.FromFile(Path.Combine(runtimePath, "System.Private.CoreLib.dll"), TestReaderParameters); using var stream = new MemoryStream(); @@ -512,8 +512,8 @@ public void RewriteSystemPrivateCoreLib() public void RewriteSystemRuntime() { string runtimePath = DotNetCorePathProvider.Default - .GetRuntimePathCandidates("Microsoft.NETCore.App", new Version(3, 1, 0)) - .FirstOrDefault() ?? throw new InvalidOperationException(".NET Core 3.1 is not installed."); + .GetRuntimePathCandidates("Microsoft.NETCore.App", new Version(8, 0, 0)) + .FirstOrDefault() ?? throw new InvalidOperationException(".NET Core 8.0 is not installed."); var module = ModuleDefinition.FromFile(Path.Combine(runtimePath, "System.Runtime.dll"), TestReaderParameters); using var stream = new MemoryStream(); @@ -524,8 +524,8 @@ public void RewriteSystemRuntime() public void RewriteSystemPrivateXml() { string runtimePath = DotNetCorePathProvider.Default - .GetRuntimePathCandidates("Microsoft.NETCore.App", new Version(3, 1, 0)) - .FirstOrDefault() ?? throw new InvalidOperationException(".NET Core 3.1 is not installed."); + .GetRuntimePathCandidates("Microsoft.NETCore.App", new Version(8, 0, 0)) + .FirstOrDefault() ?? throw new InvalidOperationException(".NET Core 8.0 is not installed."); var module = ModuleDefinition.FromFile(Path.Combine(runtimePath, "System.Private.Xml.dll"), TestReaderParameters); using var stream = new MemoryStream(); diff --git a/test/AsmResolver.DotNet.Tests/ReferenceImporterTest.cs b/test/AsmResolver.DotNet.Tests/ReferenceImporterTest.cs index 88f08f048..7a8b0d4dd 100644 --- a/test/AsmResolver.DotNet.Tests/ReferenceImporterTest.cs +++ b/test/AsmResolver.DotNet.Tests/ReferenceImporterTest.cs @@ -55,7 +55,7 @@ public void ImportNewTypeShouldCreateNewReference() var result = _importer.ImportType(type); Assert.Equal(type, result, Comparer); - Assert.Equal(_module, result.Module); + Assert.Equal(_module, result.ContextModule); } [Fact] @@ -94,6 +94,20 @@ public void ImportTypeDefInSameModuleShouldReturnSameInstance() Assert.Same(definition, importedType); } + [Fact] + public void ImportTypeRefWithNullScopeShouldReturnTypeRefToContextAssembly() + { + var assembly = new AssemblyDefinition("OtherModule", new Version(1, 0, 0, 0)); + var module = new ModuleDefinition("OtherModule.dll"); + assembly.Modules.Add(module); + + var reference = new TypeReference(module, null, "SomeNamespace", "SomeName"); + + Assert.Null(reference.Scope); + var importedType = _importer.ImportType(reference); + Assert.Equal(assembly, importedType.Scope?.GetAssembly(), SignatureComparer.Default); + } + [Fact] public void ImportNestedTypeShouldImportParentType() { @@ -103,8 +117,8 @@ public void ImportNestedTypeShouldImportParentType() var result = _importer.ImportType(nested); Assert.Equal(nested, result, Comparer); - Assert.Equal(_module, result.Module); - Assert.Equal(_module, result.DeclaringType?.Module); + Assert.Equal(_module, result.ContextModule); + Assert.Equal(_module, result.DeclaringType?.ContextModule); } [Fact] @@ -134,8 +148,8 @@ public void ImportNestedTypeDefinitionShouldImportParentType() Assert.NotNull(reference.DeclaringType); Assert.Equal(declaringType, reference.DeclaringType, Comparer); - Assert.Equal(_module, reference.Module); - Assert.Equal(_module, reference.DeclaringType.Module); + Assert.Equal(_module, reference.ContextModule); + Assert.Equal(_module, reference.DeclaringType.ContextModule); } [Fact] @@ -148,8 +162,8 @@ public void ImportNestedTypeViaReflectionShouldImportParentType() var result = _importer.ImportType(typeof(TopLevelClass1.Nested1)); Assert.Equal(nested, result, Comparer); - Assert.Equal(_module, result.Module); - Assert.Equal(_module, result.DeclaringType?.Module); + Assert.Equal(_module, result.ContextModule); + Assert.Equal(_module, result.DeclaringType?.ContextModule); } [Fact] @@ -218,7 +232,7 @@ public void ImportMethodFromExternalModuleShouldResultInMemberRef() var result = _importer.ImportMethod(method); Assert.Equal(method, result, Comparer); - Assert.Same(_module, result.Module); + Assert.Same(_module, result.ContextModule); } [Fact] @@ -279,7 +293,7 @@ public void ImportFieldFromExternalModuleShouldResultInMemberRef() var result = _importer.ImportField(field); Assert.Equal(field, result, Comparer); - Assert.Same(_module, result.Module); + Assert.Same(_module, result.ContextModule); } [Fact] @@ -315,20 +329,20 @@ public void ImportFieldFromReflectionShouldResultInMemberRef() [Fact] public void ImportNonImportedTypeDefOrRefShouldResultInNewInstance() { - var signature = new TypeReference(_module.CorLibTypeFactory.CorLibScope, "System.IO", "Stream") + var signature = new TypeReference(null, _module.CorLibTypeFactory.CorLibScope, "System.IO", "Stream") .ToTypeSignature(); var imported = _importer.ImportTypeSignature(signature); Assert.NotSame(signature, imported); Assert.Equal(signature, imported, Comparer); - Assert.Equal(_module, imported.Module); + Assert.Equal(_module, imported.ContextModule); } [Fact] public void ImportTypeSpecWithNonImportedBaseTypeShouldResultInNewInstance() { - var signature = new TypeReference(_module.CorLibTypeFactory.CorLibScope, "System.IO", "Stream") + var signature = new TypeReference(null, _module.CorLibTypeFactory.CorLibScope, "System.IO", "Stream") .ToTypeSignature() .MakeSzArrayType(); @@ -336,7 +350,7 @@ public void ImportTypeSpecWithNonImportedBaseTypeShouldResultInNewInstance() var newInstance = Assert.IsAssignableFrom(imported); Assert.NotSame(signature, newInstance); Assert.Equal(signature, newInstance, Comparer); - Assert.Equal(_module, newInstance.BaseType.Module); + Assert.Equal(_module, newInstance.BaseType.ContextModule); } [Fact] @@ -371,15 +385,15 @@ public void ImportGenericTypeSigWithNonImportedTypeArgumentShouldResultInNewInst var instance = genericType.MakeGenericInstanceType( new TypeDefOrRefSignature( - new TypeReference(_module.CorLibTypeFactory.CorLibScope, "System.IO", "Stream"), false) + new TypeReference(null, _module.CorLibTypeFactory.CorLibScope, "System.IO", "Stream"), false) ); var imported = _importer.ImportTypeSignature(instance); var newInstance = Assert.IsAssignableFrom(imported); Assert.NotSame(instance, newInstance); - Assert.Equal(_module, newInstance.Module); - Assert.Equal(_module, newInstance.TypeArguments[0].Module); + Assert.Equal(_module, newInstance.ContextModule); + Assert.Equal(_module, newInstance.TypeArguments[0].ContextModule); } [Fact] @@ -413,8 +427,8 @@ public void ImportCustomModifierTypeWithNonImportedModifierTypeShouldResultInNew var newInstance = Assert.IsAssignableFrom(imported); Assert.NotSame(signature, newInstance); - Assert.Equal(_module, newInstance.Module); - Assert.Equal(_module, newInstance.ModifierType.Module); + Assert.Equal(_module, newInstance.ContextModule); + Assert.Equal(_module, newInstance.ModifierType.ContextModule); } [Fact] @@ -445,8 +459,8 @@ public void ImportFunctionPointerTypeWithNonImportedParameterShouldResultInNewIn var newInstance = Assert.IsAssignableFrom(imported); Assert.NotSame(signature, newInstance); Assert.Equal(signature, newInstance, Comparer); - Assert.Equal(_module, newInstance.Module); - Assert.Equal(_module, newInstance.Signature.ParameterTypes[0].Module); + Assert.Equal(_module, newInstance.ContextModule); + Assert.Equal(_module, newInstance.Signature.ParameterTypes[0].ContextModule); } [Fact] @@ -463,8 +477,8 @@ public void ImportFunctionPointerTypeWithNonImportedReturnTypeShouldResultInNewI var newInstance = Assert.IsAssignableFrom(imported); Assert.NotSame(signature, newInstance); Assert.Equal(signature, newInstance, Comparer); - Assert.Equal(_module, newInstance.Module); - Assert.Equal(_module, newInstance.Signature.ReturnType.Module); + Assert.Equal(_module, newInstance.ContextModule); + Assert.Equal(_module, newInstance.Signature.ReturnType.ContextModule); } [Fact] diff --git a/test/AsmResolver.DotNet.Tests/RuntimeContextTest.cs b/test/AsmResolver.DotNet.Tests/RuntimeContextTest.cs index e4f0bcf29..babb38e77 100644 --- a/test/AsmResolver.DotNet.Tests/RuntimeContextTest.cs +++ b/test/AsmResolver.DotNet.Tests/RuntimeContextTest.cs @@ -68,17 +68,17 @@ public void ForceNetStandardLoadAsNetFx() var module = ModuleDefinition.FromFile(typeof(Class).Assembly.Location, new ModuleReaderParameters(context)); Assert.Equal(context.TargetRuntime, module.RuntimeContext.TargetRuntime); - Assert.Equal("mscorlib", module.CorLibTypeFactory.Object.Resolve()?.Module?.Assembly?.Name); + Assert.Equal("mscorlib", module.CorLibTypeFactory.Object.Resolve()?.DeclaringModule?.Assembly?.Name); } [Fact] public void ForceNetStandardLoadAsNetCore() { - var context = new RuntimeContext(new DotNetRuntimeInfo(DotNetRuntimeInfo.NetCoreApp, new Version(3, 1))); + var context = new RuntimeContext(new DotNetRuntimeInfo(DotNetRuntimeInfo.NetCoreApp, new Version(8, 0))); var module = ModuleDefinition.FromFile(typeof(Class).Assembly.Location, new ModuleReaderParameters(context)); Assert.Equal(context.TargetRuntime, module.RuntimeContext.TargetRuntime); - Assert.Equal("System.Private.CoreLib", module.CorLibTypeFactory.Object.Resolve()?.Module?.Assembly?.Name); + Assert.Equal("System.Private.CoreLib", module.CorLibTypeFactory.Object.Resolve()?.DeclaringModule?.Assembly?.Name); } [Fact] diff --git a/test/AsmResolver.DotNet.Tests/Signatures/MarshalDescriptorTest.cs b/test/AsmResolver.DotNet.Tests/Signatures/MarshalDescriptorTest.cs index ea0ed588a..4f0af16fd 100644 --- a/test/AsmResolver.DotNet.Tests/Signatures/MarshalDescriptorTest.cs +++ b/test/AsmResolver.DotNet.Tests/Signatures/MarshalDescriptorTest.cs @@ -38,7 +38,7 @@ private static FieldDefinition LookupFieldInModule(ModuleDefinition module, stri private static MethodDefinition RebuildAndLookup(MethodDefinition method) { var builder = new ManagedPEImageBuilder(); - var newImage = builder.CreateImage(method.Module).ConstructedImage; + var newImage = builder.CreateImage(method.DeclaringModule!).ConstructedImage; var newModule = ModuleDefinition.FromImage(newImage, TestReaderParameters); return LookupMethodInModule(newModule, method.Name); } @@ -46,7 +46,7 @@ private static MethodDefinition RebuildAndLookup(MethodDefinition method) private static FieldDefinition RebuildAndLookup(FieldDefinition field) { var builder = new ManagedPEImageBuilder(); - var newImage = builder.CreateImage(field.Module).ConstructedImage; + var newImage = builder.CreateImage(field.DeclaringModule!).ConstructedImage; var newModule = ModuleDefinition.FromImage(newImage, TestReaderParameters); return LookupFieldInModule(newModule, field.Name); } diff --git a/test/AsmResolver.DotNet.Tests/Signatures/TypeSignatureTest.cs b/test/AsmResolver.DotNet.Tests/Signatures/TypeSignatureTest.cs index b8d30ad08..3b091baf1 100644 --- a/test/AsmResolver.DotNet.Tests/Signatures/TypeSignatureTest.cs +++ b/test/AsmResolver.DotNet.Tests/Signatures/TypeSignatureTest.cs @@ -624,7 +624,7 @@ public void GetModuleOfTypeDefOrRef() { var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld, TestReaderParameters); var signature = module.GetOrCreateModuleType().ToTypeSignature(); - Assert.Same(module, signature.Module); + Assert.Same(module, signature.ContextModule); } [Fact] @@ -636,7 +636,7 @@ public void GetModuleOfTypeDefOrRefWithNullScope() .ToTypeSignature(); Assert.Null(signature.Scope); - Assert.Same(module, signature.Module); + Assert.Same(module, signature.ContextModule); } [Fact] @@ -649,7 +649,7 @@ public void GetModuleOfSpecificationTypeWithNullScope() .MakeSzArrayType(); Assert.Null(signature.Scope); - Assert.Same(module, signature.Module); + Assert.Same(module, signature.ContextModule); } } } diff --git a/test/AsmResolver.DotNet.Tests/TypeDefinitionTest.cs b/test/AsmResolver.DotNet.Tests/TypeDefinitionTest.cs index 0edb09567..144260a9b 100644 --- a/test/AsmResolver.DotNet.Tests/TypeDefinitionTest.cs +++ b/test/AsmResolver.DotNet.Tests/TypeDefinitionTest.cs @@ -24,7 +24,7 @@ public class TypeDefinitionTest private TypeDefinition RebuildAndLookup(TypeDefinition type) { var stream = new MemoryStream(); - type.Module!.Write(stream); + type.DeclaringModule!.Write(stream); var newModule = ModuleDefinition.FromBytes(stream.ToArray(), TestReaderParameters); return newModule.TopLevelTypes.FirstOrDefault(t => t.FullName == type.FullName); @@ -40,7 +40,7 @@ public void LinkedToModule() { var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld, TestReaderParameters); foreach (var type in module.TopLevelTypes) - Assert.Same(module, type.Module); + Assert.Same(module, type.DeclaringModule); } [Fact] @@ -178,10 +178,10 @@ public void ReadNestedTypes() Assert.Same(class1, nested2.DeclaringType); Assert.Same(class2, nested3.DeclaringType); Assert.Same(class2, nested4.DeclaringType); - Assert.Same(module, nested1.Module); - Assert.Same(module, nested2.Module); - Assert.Same(module, nested3.Module); - Assert.Same(module, nested4.Module); + Assert.Same(module, nested1.DeclaringModule); + Assert.Same(module, nested2.DeclaringModule); + Assert.Same(module, nested3.DeclaringModule); + Assert.Same(module, nested4.DeclaringModule); } [Fact] @@ -629,14 +629,14 @@ public void AddTypeWithCorLibBaseTypeToAssemblyWithCorLibTypeReferenceInAttribut Assert.Same(scope, corlib.Object.Scope); var reference = Assert.IsAssignableFrom(corlib.Object.Scope!.GetAssembly()); - Assert.Same(module, reference.Module); + Assert.Same(module, reference.ContextModule); } [Fact] public void ReadIsByRefLike() { - var resolver = new DotNetCoreAssemblyResolver(new Version(5, 0)); - var corLib = resolver.Resolve(KnownCorLibs.SystemPrivateCoreLib_v5_0_0_0)!; + var resolver = new DotNetCoreAssemblyResolver(new Version(8, 0)); + var corLib = resolver.Resolve(KnownCorLibs.SystemPrivateCoreLib_v8_0_0_0)!; var intType = corLib.ManifestModule!.TopLevelTypes.First(t => t.Name == "Int32"); var spanType = corLib.ManifestModule.TopLevelTypes.First(t => t.Name == "Span`1"); @@ -739,7 +739,7 @@ public void AddTypeToModuleShouldSetOwner() var module = new ModuleDefinition("Dummy"); var type = new TypeDefinition("SomeNamespace", "SomeType", TypeAttributes.Public); module.TopLevelTypes.Add(type); - Assert.Same(module, type.Module); + Assert.Same(module, type.DeclaringModule); } [Fact] @@ -751,7 +751,7 @@ public void AddNestedTypeToModuleShouldSetOwner() module.TopLevelTypes.Add(type1); type1.NestedTypes.Add(type2); Assert.Same(type1, type2.DeclaringType); - Assert.Same(module, type2.Module); + Assert.Same(module, type2.DeclaringModule); } [Fact] @@ -805,7 +805,7 @@ public void NestedTypeRemovedFromOwnerShouldHaveNoModule() nestedType.DeclaringType!.NestedTypes.Remove(nestedType); - Assert.Null(nestedType.Module); + Assert.Null(nestedType.DeclaringModule); } } } diff --git a/test/AsmResolver.DotNet.Tests/TypeReferenceTest.cs b/test/AsmResolver.DotNet.Tests/TypeReferenceTest.cs index d2211247c..894c05324 100644 --- a/test/AsmResolver.DotNet.Tests/TypeReferenceTest.cs +++ b/test/AsmResolver.DotNet.Tests/TypeReferenceTest.cs @@ -25,14 +25,13 @@ public void WriteAssemblyRefScope() { var module = new ModuleDefinition("SomeModule"); module.GetOrCreateModuleType().Fields.Add(new FieldDefinition( - "SomeField", - FieldAttributes.Static, - new TypeDefOrRefSignature(new TypeReference( - new AssemblyReference("SomeAssembly", new Version(1, 0, 0, 0)), - "SomeNamespace", - "SomeName") - ).ImportWith(module.DefaultImporter) - )); + "SomeField", + FieldAttributes.Static, + new AssemblyReference("SomeAssembly", new Version(1, 0, 0, 0)) + .CreateTypeReference("SomeNamespace", "SomeName") + .ToTypeSignature(false) + ) + ); var image = module.ToPEImage(); @@ -60,14 +59,10 @@ public void WriteTypeRefScope() module.GetOrCreateModuleType().Fields.Add(new FieldDefinition( "SomeField", FieldAttributes.Static, - new TypeDefOrRefSignature(new TypeReference( - new TypeReference( - new AssemblyReference("SomeAssembly", new Version(1, 0, 0, 0)), - "SomeNamespace", - "SomeName"), - null, - "SomeNestedType" - )).ImportWith(module.DefaultImporter) + new AssemblyReference("SomeAssembly", new Version(1, 0, 0, 0)) + .CreateTypeReference("SomeNamespace", "SomeName") + .CreateTypeReference("SomeNestedType") + .ToTypeSignature(false) )); var image = module.ToPEImage(); @@ -96,11 +91,7 @@ public void WriteModuleScope() module.GetOrCreateModuleType().Fields.Add(new FieldDefinition( "SomeField", FieldAttributes.Static, - new TypeDefOrRefSignature(new TypeReference( - module, - "SomeNamepace", - "SomeName") - ).ImportWith(module.DefaultImporter) + module.CreateTypeReference("SomeNamepace", "SomeName").ToTypeSignature(false) )); var image = module.ToPEImage(); @@ -119,11 +110,7 @@ public void WriteNullScope() module.GetOrCreateModuleType().Fields.Add(new FieldDefinition( "SomeField", FieldAttributes.Static, - new TypeDefOrRefSignature(new TypeReference( - null, - "SomeNamespace", - "SomeName") - ).ImportWith(module.DefaultImporter) + new TypeReference(null, "SomeNamespace", "SomeName").ToTypeSignature(false) )); var image = module.ToPEImage();