Browse Source

Use MetadataFile instead of PEFile in TypeSystem.

pull/3184/head
Siegfried Pammer 2 years ago
parent
commit
ca78d4a14d
  1. 2
      ICSharpCode.BamlDecompiler/Baml/KnownThings.cs
  2. 12
      ICSharpCode.BamlDecompiler/BamlDecompilerTypeSystem.cs
  3. 6
      ICSharpCode.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs
  4. 3
      ICSharpCode.Decompiler.PowerShell/GetDecompiledProjectCmdlet.cs
  5. 28
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  6. 8
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs
  7. 34
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
  8. 2
      ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs
  9. 7
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs
  10. 2
      ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs
  11. 7
      ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs
  12. 4
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  13. 6
      ICSharpCode.Decompiler/DecompilerException.cs
  14. 8
      ICSharpCode.Decompiler/Disassembler/ILStructure.cs
  15. 19
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  16. 96
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  17. 2
      ICSharpCode.Decompiler/Documentation/GetPotentiallyNestedClassTypeReference.cs
  18. 4
      ICSharpCode.Decompiler/Documentation/XmlDocLoader.cs
  19. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  20. 6
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  21. 4
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs
  22. 2
      ICSharpCode.Decompiler/IL/ILReader.cs
  23. 2
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  24. 2
      ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs
  25. 12
      ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
  26. 2
      ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs
  27. 8
      ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs
  28. 8
      ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs
  29. 10
      ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs
  30. 4
      ICSharpCode.Decompiler/Metadata/CodeMappingInfo.cs
  31. 16
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs
  32. 10
      ICSharpCode.Decompiler/Metadata/EnumUnderlyingTypeResolveException.cs
  33. 8
      ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs
  34. 331
      ICSharpCode.Decompiler/Metadata/MetadataFile.cs
  35. 2
      ICSharpCode.Decompiler/Metadata/MetadataGenericContext.cs
  36. 260
      ICSharpCode.Decompiler/Metadata/PEFile.cs
  37. 19
      ICSharpCode.Decompiler/Metadata/Resource.cs
  38. 10
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  39. 2
      ICSharpCode.Decompiler/NRExtensions.cs
  40. 9
      ICSharpCode.Decompiler/SRMExtensions.cs
  41. 20
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  42. 2
      ICSharpCode.Decompiler/TypeSystem/IAssembly.cs
  43. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs
  44. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs
  45. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  46. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs
  47. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs
  48. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs
  49. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs
  50. 12
      ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs
  51. 4
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  52. 2
      ICSharpCode.ILSpyX/Abstractions/ILanguage.cs
  53. 2
      ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs
  54. 28
      ICSharpCode.ILSpyX/AssemblyListSnapshot.cs
  55. 64
      ICSharpCode.ILSpyX/LoadedAssembly.cs
  56. 10
      ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs
  57. 20
      ICSharpCode.ILSpyX/LoadedPackage.cs
  58. 5
      ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs
  59. 4
      ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs
  60. 2
      ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs
  61. 7
      ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs
  62. 8
      ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs
  63. 3
      ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs
  64. 3
      ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs
  65. 6
      ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs
  66. 7
      ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs
  67. 8
      ICSharpCode.ILSpyX/Search/SearchResult.cs
  68. 2
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  69. 2
      ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
  70. 43
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  71. 9
      ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
  72. 8
      ILSpy/Analyzers/AnalyzerContext.cs
  73. 4
      ILSpy/Analyzers/AnalyzerEntityTreeNode.cs
  74. 6
      ILSpy/Analyzers/AnalyzerHelpers.cs
  75. 28
      ILSpy/Analyzers/AnalyzerScope.cs
  76. 6
      ILSpy/Analyzers/Builtin/EventImplementedByAnalyzer.cs
  77. 6
      ILSpy/Analyzers/Builtin/EventOverriddenByAnalyzer.cs
  78. 13
      ILSpy/Analyzers/Builtin/FieldAccessAnalyzer.cs
  79. 6
      ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs
  80. 6
      ILSpy/Analyzers/Builtin/MethodImplementedByAnalyzer.cs
  81. 6
      ILSpy/Analyzers/Builtin/MethodOverriddenByAnalyzer.cs
  82. 10
      ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs
  83. 10
      ILSpy/Analyzers/Builtin/MethodUsesAnalyzer.cs
  84. 6
      ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs
  85. 6
      ILSpy/Analyzers/Builtin/PropertyImplementedByAnalyzer.cs
  86. 6
      ILSpy/Analyzers/Builtin/PropertyOverriddenByAnalyzer.cs
  87. 2
      ILSpy/Analyzers/Builtin/TypeExposedByAnalyzer.cs
  88. 2
      ILSpy/Analyzers/Builtin/TypeExtensionMethodsAnalyzer.cs
  89. 4
      ILSpy/Analyzers/Builtin/TypeInstantiatedByAnalyzer.cs
  90. 10
      ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs
  91. 4
      ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs
  92. 3
      ILSpy/Commands/GeneratePdbContextMenuEntry.cs
  93. 2
      ILSpy/EntityReference.cs
  94. 8
      ILSpy/Languages/CSharpILMixedLanguage.cs
  95. 30
      ILSpy/Languages/CSharpLanguage.cs
  96. 14
      ILSpy/Languages/ILAstLanguage.cs
  97. 26
      ILSpy/Languages/ILLanguage.cs
  98. 8
      ILSpy/Languages/Language.cs
  99. 16
      ILSpy/MainWindow.xaml.cs
  100. 2
      ILSpy/Metadata/DebugDirectoryTreeNode.cs
  101. Some files were not shown because too many files have changed in this diff Show More

2
ICSharpCode.BamlDecompiler/Baml/KnownThings.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.BamlDecompiler.Baml
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new ICSharpCode.Decompiler.DecompilerException(typeSystem.MainModule.PEFile, ex.Message, ex); throw new ICSharpCode.Decompiler.DecompilerException(typeSystem.MainModule.MetadataFile, ex.Message, ex);
} }
} }

12
ICSharpCode.BamlDecompiler/BamlDecompilerTypeSystem.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.BamlDecompiler
"System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" "System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
}; };
public BamlDecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver) public BamlDecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver)
{ {
if (mainModule == null) if (mainModule == null)
throw new ArgumentNullException(nameof(mainModule)); throw new ArgumentNullException(nameof(mainModule));
@ -48,8 +48,8 @@ namespace ICSharpCode.BamlDecompiler
throw new ArgumentNullException(nameof(assemblyResolver)); throw new ArgumentNullException(nameof(assemblyResolver));
// Load referenced assemblies and type-forwarder references. // Load referenced assemblies and type-forwarder references.
// This is necessary to make .NET Core/PCL binaries work better. // This is necessary to make .NET Core/PCL binaries work better.
var referencedAssemblies = new List<PEFile>(); var referencedAssemblies = new List<MetadataFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference)>(); var assemblyReferenceQueue = new Queue<(bool IsAssembly, MetadataFile MainModule, object Reference)>();
var mainMetadata = mainModule.Metadata; var mainMetadata = mainModule.Metadata;
foreach (var h in mainMetadata.GetModuleReferences()) foreach (var h in mainMetadata.GetModuleReferences())
{ {
@ -73,16 +73,16 @@ namespace ICSharpCode.BamlDecompiler
{ {
assemblyReferenceQueue.Enqueue((true, mainModule, AssemblyNameReference.Parse(bamlReference))); assemblyReferenceQueue.Enqueue((true, mainModule, AssemblyNameReference.Parse(bamlReference)));
} }
var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) => var comparer = KeyComparer.Create(((bool IsAssembly, MetadataFile MainModule, object Reference) reference) =>
reference.IsAssembly ? "A:" + ((IAssemblyReference)reference.Reference).FullName : reference.IsAssembly ? "A:" + ((IAssemblyReference)reference.Reference).FullName :
"M:" + reference.Reference); "M:" + reference.Reference);
var processedAssemblyReferences = new HashSet<(bool IsAssembly, PEFile Parent, object Reference)>(comparer); var processedAssemblyReferences = new HashSet<(bool IsAssembly, MetadataFile Parent, object Reference)>(comparer);
while (assemblyReferenceQueue.Count > 0) while (assemblyReferenceQueue.Count > 0)
{ {
var asmRef = assemblyReferenceQueue.Dequeue(); var asmRef = assemblyReferenceQueue.Dequeue();
if (!processedAssemblyReferences.Add(asmRef)) if (!processedAssemblyReferences.Add(asmRef))
continue; continue;
PEFile asm; MetadataFile asm;
if (asmRef.IsAssembly) if (asmRef.IsAssembly)
{ {
asm = assemblyResolver.Resolve((IAssemblyReference)asmRef.Reference); asm = assemblyResolver.Resolve((IAssemblyReference)asmRef.Reference);

6
ICSharpCode.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs

@ -128,7 +128,7 @@ namespace ICSharpCode.BamlDecompiler.Rewrite
IMethod connectMethod = null; IMethod connectMethod = null;
MethodDefinition connectMetadataEntry = default; MethodDefinition connectMetadataEntry = default;
var module = ctx.TypeSystem.MainModule.PEFile; var module = ctx.TypeSystem.MainModule.MetadataFile;
foreach (IMethod m in type.Methods) foreach (IMethod m in type.Methods)
{ {
@ -171,9 +171,7 @@ namespace ICSharpCode.BamlDecompiler.Rewrite
ctx.GeneratedMembers.Add(connectMethod.MetadataToken); ctx.GeneratedMembers.Add(connectMethod.MetadataToken);
var body = module.GetMethodBody(connectMetadataEntry.RelativeVirtualAddress);
var body = module.Reader.GetMethodBody(connectMetadataEntry.RelativeVirtualAddress);
var genericContext = new GenericContext( var genericContext = new GenericContext(
classTypeParameters: connectMethod.DeclaringType?.TypeParameters, classTypeParameters: connectMethod.DeclaringType?.TypeParameters,
methodTypeParameters: connectMethod.TypeParameters); methodTypeParameters: connectMethod.TypeParameters);

3
ICSharpCode.Decompiler.PowerShell/GetDecompiledProjectCmdlet.cs

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Concurrent;
using System.IO; using System.IO;
using System.Management.Automation; using System.Management.Automation;
using System.Threading; using System.Threading;
@ -89,7 +88,7 @@ namespace ICSharpCode.Decompiler.PowerShell
private void DoDecompile(string path) private void DoDecompile(string path)
{ {
PEFile module = Decompiler.TypeSystem.MainModule.PEFile; MetadataFile module = Decompiler.TypeSystem.MainModule.MetadataFile;
var assemblyResolver = new UniversalAssemblyResolver(module.FileName, false, module.Metadata.DetectTargetFrameworkId()); var assemblyResolver = new UniversalAssemblyResolver(module.FileName, false, module.Metadata.DetectTargetFrameworkId());
WholeProjectDecompiler decompiler = new WholeProjectDecompiler(assemblyResolver); WholeProjectDecompiler decompiler = new WholeProjectDecompiler(assemblyResolver);
decompiler.ProgressIndicator = this; decompiler.ProgressIndicator = this;

28
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -251,7 +251,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// <summary> /// <summary>
/// Creates a new <see cref="CSharpDecompiler"/> instance from the given <paramref name="module"/> using the given <paramref name="assemblyResolver"/> and <paramref name="settings"/>. /// Creates a new <see cref="CSharpDecompiler"/> instance from the given <paramref name="module"/> using the given <paramref name="assemblyResolver"/> and <paramref name="settings"/>.
/// </summary> /// </summary>
public CSharpDecompiler(PEFile module, IAssemblyResolver assemblyResolver, DecompilerSettings settings) public CSharpDecompiler(MetadataFile module, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
: this(new DecompilerTypeSystem(module, assemblyResolver, settings), settings) : this(new DecompilerTypeSystem(module, assemblyResolver, settings), settings)
{ {
} }
@ -264,7 +264,7 @@ namespace ICSharpCode.Decompiler.CSharp
this.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem)); this.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));
this.settings = settings; this.settings = settings;
this.module = typeSystem.MainModule; this.module = typeSystem.MainModule;
this.metadata = module.PEFile.Metadata; this.metadata = module.MetadataFile.Metadata;
if (module.TypeSystemOptions.HasFlag(TypeSystemOptions.Uncached)) if (module.TypeSystemOptions.HasFlag(TypeSystemOptions.Uncached))
throw new ArgumentException("Cannot use an uncached type system in the decompiler."); throw new ArgumentException("Cannot use an uncached type system in the decompiler.");
} }
@ -276,7 +276,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// <param name="module">The module containing the member.</param> /// <param name="module">The module containing the member.</param>
/// <param name="member">The metadata token/handle of the member. Can be a TypeDef, MethodDef or FieldDef.</param> /// <param name="member">The metadata token/handle of the member. Can be a TypeDef, MethodDef or FieldDef.</param>
/// <param name="settings">THe settings used to determine whether code should be hidden. E.g. if async methods are not transformed, async state machines are included in the decompiled code.</param> /// <param name="settings">THe settings used to determine whether code should be hidden. E.g. if async methods are not transformed, async state machines are included in the decompiled code.</param>
public static bool MemberIsHidden(Metadata.PEFile module, EntityHandle member, DecompilerSettings settings) public static bool MemberIsHidden(MetadataFile module, EntityHandle member, DecompilerSettings settings)
{ {
if (module == null || member.IsNil) if (module == null || member.IsNil)
return false; return false;
@ -539,7 +539,7 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
try try
{ {
return XmlDocLoader.LoadDocumentation(module.PEFile); return XmlDocLoader.LoadDocumentation(module.MetadataFile);
} }
catch (System.Xml.XmlException) catch (System.Xml.XmlException)
{ {
@ -633,7 +633,7 @@ namespace ICSharpCode.Decompiler.CSharp
var typeDef = module.GetDefinition(typeDefHandle); var typeDef = module.GetDefinition(typeDefHandle);
if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0) if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0)
continue; continue;
if (MemberIsHidden(module.PEFile, typeDefHandle, settings)) if (MemberIsHidden(module.MetadataFile, typeDefHandle, settings))
continue; continue;
if (string.IsNullOrEmpty(typeDef.Namespace)) if (string.IsNullOrEmpty(typeDef.Namespace))
{ {
@ -702,7 +702,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// <summary> /// <summary>
/// Determines the "code-mappings" for a given TypeDef or MethodDef. See <see cref="CodeMappingInfo"/> for more information. /// Determines the "code-mappings" for a given TypeDef or MethodDef. See <see cref="CodeMappingInfo"/> for more information.
/// </summary> /// </summary>
public static CodeMappingInfo GetCodeMappingInfo(PEFile module, EntityHandle member) public static CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)
{ {
var declaringType = (TypeDefinitionHandle)member.GetDeclaringType(module.Metadata); var declaringType = (TypeDefinitionHandle)member.GetDeclaringType(module.Metadata);
@ -744,7 +744,7 @@ namespace ICSharpCode.Decompiler.CSharp
return info; return info;
} }
private static void ReadCodeMappingInfo(PEFile module, CodeMappingInfo info, MethodDefinitionHandle parent, MethodDefinitionHandle part, Queue<MethodDefinitionHandle> connectedMethods, HashSet<TypeDefinitionHandle> processedNestedTypes) private static void ReadCodeMappingInfo(MetadataFile module, CodeMappingInfo info, MethodDefinitionHandle parent, MethodDefinitionHandle part, Queue<MethodDefinitionHandle> connectedMethods, HashSet<TypeDefinitionHandle> processedNestedTypes)
{ {
var md = module.Metadata.GetMethodDefinition(part); var md = module.Metadata.GetMethodDefinition(part);
@ -756,7 +756,7 @@ namespace ICSharpCode.Decompiler.CSharp
var declaringType = md.GetDeclaringType(); var declaringType = md.GetDeclaringType();
var blob = module.Reader.GetMethodBody(md.RelativeVirtualAddress).GetILReader(); var blob = module.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
while (blob.RemainingBytes > 0) while (blob.RemainingBytes > 0)
{ {
var code = blob.DecodeOpCode(); var code = blob.DecodeOpCode();
@ -1357,7 +1357,7 @@ namespace ICSharpCode.Decompiler.CSharp
// Decompile members that are not compiler-generated. // Decompile members that are not compiler-generated.
foreach (var entity in allOrderedEntities) foreach (var entity in allOrderedEntities)
{ {
if (entity.MetadataToken.IsNil || MemberIsHidden(module.PEFile, entity.MetadataToken, settings)) if (entity.MetadataToken.IsNil || MemberIsHidden(module.MetadataFile, entity.MetadataToken, settings))
{ {
continue; continue;
} }
@ -1403,7 +1403,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (typeDecl.ClassType == ClassType.Enum) if (typeDecl.ClassType == ClassType.Enum)
{ {
Debug.Assert(typeDef.Kind == TypeKind.Enum); Debug.Assert(typeDef.Kind == TypeKind.Enum);
EnumValueDisplayMode displayMode = DetectBestEnumValueDisplayMode(typeDef, module.PEFile); EnumValueDisplayMode displayMode = DetectBestEnumValueDisplayMode(typeDef, module.MetadataFile);
switch (displayMode) switch (displayMode)
{ {
case EnumValueDisplayMode.FirstOnly: case EnumValueDisplayMode.FirstOnly:
@ -1532,7 +1532,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} }
EnumValueDisplayMode DetectBestEnumValueDisplayMode(ITypeDefinition typeDef, PEFile module) EnumValueDisplayMode DetectBestEnumValueDisplayMode(ITypeDefinition typeDef, MetadataFile module)
{ {
if (typeDef.HasAttribute(KnownAttribute.Flags)) if (typeDef.HasAttribute(KnownAttribute.Flags))
return EnumValueDisplayMode.AllHex; return EnumValueDisplayMode.AllHex;
@ -1608,7 +1608,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
FixParameterNames(methodDecl); FixParameterNames(methodDecl);
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken); var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
if (!settings.LocalFunctions && LocalFunctionDecompiler.LocalFunctionNeedsAccessibilityChange(method.ParentModule.PEFile, (MethodDefinitionHandle)method.MetadataToken)) if (!settings.LocalFunctions && LocalFunctionDecompiler.LocalFunctionNeedsAccessibilityChange(method.ParentModule.MetadataFile, (MethodDefinitionHandle)method.MetadataToken))
{ {
// if local functions are not active and we're dealing with a local function, // if local functions are not active and we're dealing with a local function,
// reduce the visibility of the method to private, // reduce the visibility of the method to private,
@ -1701,7 +1701,7 @@ namespace ICSharpCode.Decompiler.CSharp
MethodBodyBlock methodBody; MethodBodyBlock methodBody;
try try
{ {
methodBody = module.PEFile.Reader.GetMethodBody(methodDef.RelativeVirtualAddress); methodBody = module.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
} }
catch (BadImageFormatException ex) catch (BadImageFormatException ex)
{ {
@ -1980,7 +1980,7 @@ namespace ICSharpCode.Decompiler.CSharp
string message; string message;
try try
{ {
var initVal = fieldDefinition.GetInitialValue(module.PEFile.Reader, TypeSystem); var initVal = fieldDefinition.GetInitialValue(module.MetadataFile, TypeSystem);
message = string.Format(" Not supported: data({0}) ", BitConverter.ToString(initVal.ReadBytes(initVal.RemainingBytes)).Replace('-', ' ')); message = string.Format(" Not supported: data({0}) ", BitConverter.ToString(initVal.ReadBytes(initVal.RemainingBytes)).Replace('-', ' '));
} }
catch (BadImageFormatException ex) catch (BadImageFormatException ex)

8
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs

@ -216,9 +216,9 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}; };
/// <summary> /// <summary>
/// Gets exact <see cref="TargetFramework"/> if <see cref="PEFile.GetRuntime"/> is <see cref="TargetRuntime.Net_2_0"/> /// Gets exact <see cref="TargetFramework"/> if <see cref="MetadataFile.GetRuntime"/> is <see cref="TargetRuntime.Net_2_0"/>
/// </summary> /// </summary>
public static TargetFramework DetectTargetFrameworkNET20(PEFile module, IAssemblyResolver assemblyResolver, TargetFramework targetFramework) public static TargetFramework DetectTargetFrameworkNET20(MetadataFile module, IAssemblyResolver assemblyResolver, TargetFramework targetFramework)
{ {
var resolvedAssemblies = new HashSet<string>(); var resolvedAssemblies = new HashSet<string>();
int version = 200; int version = 200;
@ -226,7 +226,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
return new TargetFramework(targetFramework.Identifier, version, targetFramework.Profile); return new TargetFramework(targetFramework.Identifier, version, targetFramework.Profile);
} }
static void GetFrameworkVersionNET20(PEFile module, IAssemblyResolver assemblyResolver, HashSet<string> resolvedAssemblies, ref int version) static void GetFrameworkVersionNET20(MetadataFile module, IAssemblyResolver assemblyResolver, HashSet<string> resolvedAssemblies, ref int version)
{ {
foreach (var r in module.Metadata.AssemblyReferences) foreach (var r in module.Metadata.AssemblyReferences)
{ {
@ -245,7 +245,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
break; break;
} }
PEFile resolvedReference; MetadataFile resolvedReference;
try try
{ {
resolvedReference = assemblyResolver.Resolve(reference); resolvedReference = assemblyResolver.Resolve(reference);

34
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs

@ -37,8 +37,6 @@ using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using Microsoft.Win32;
using static ICSharpCode.Decompiler.Metadata.MetadataExtensions; using static ICSharpCode.Decompiler.Metadata.MetadataExtensions;
namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
@ -133,40 +131,48 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
HashSet<string> directories = new HashSet<string>(Platform.FileNameComparer); HashSet<string> directories = new HashSet<string>(Platform.FileNameComparer);
readonly IProjectFileWriter projectWriter; readonly IProjectFileWriter projectWriter;
public void DecompileProject(PEFile moduleDefinition, string targetDirectory, CancellationToken cancellationToken = default(CancellationToken)) public void DecompileProject(MetadataFile file, string targetDirectory, CancellationToken cancellationToken = default(CancellationToken))
{ {
string projectFileName = Path.Combine(targetDirectory, CleanUpFileName(moduleDefinition.Name) + ".csproj"); if (file is not PEFile)
{
throw new NotSupportedException("Module is not a valid PE file!");
}
string projectFileName = Path.Combine(targetDirectory, CleanUpFileName(file.Name) + ".csproj");
using (var writer = new StreamWriter(projectFileName)) using (var writer = new StreamWriter(projectFileName))
{ {
DecompileProject(moduleDefinition, targetDirectory, writer, cancellationToken); DecompileProject(file, targetDirectory, writer, cancellationToken);
} }
} }
public ProjectId DecompileProject(PEFile moduleDefinition, string targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken = default(CancellationToken)) public ProjectId DecompileProject(MetadataFile file, string targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (file is not PEFile module)
{
throw new NotSupportedException("Module is not a valid PE file!");
}
if (string.IsNullOrEmpty(targetDirectory)) if (string.IsNullOrEmpty(targetDirectory))
{ {
throw new InvalidOperationException("Must set TargetDirectory"); throw new InvalidOperationException("Must set TargetDirectory");
} }
TargetDirectory = targetDirectory; TargetDirectory = targetDirectory;
directories.Clear(); directories.Clear();
var resources = WriteResourceFilesInProject(moduleDefinition).ToList(); var resources = WriteResourceFilesInProject(file).ToList();
var files = WriteCodeFilesInProject(moduleDefinition, resources.SelectMany(r => r.PartialTypes ?? Enumerable.Empty<PartialTypeInfo>()).ToList(), cancellationToken).ToList(); var files = WriteCodeFilesInProject(file, resources.SelectMany(r => r.PartialTypes ?? Enumerable.Empty<PartialTypeInfo>()).ToList(), cancellationToken).ToList();
files.AddRange(resources); files.AddRange(resources);
files.AddRange(WriteMiscellaneousFilesInProject(moduleDefinition)); files.AddRange(WriteMiscellaneousFilesInProject(module));
if (StrongNameKeyFile != null) if (StrongNameKeyFile != null)
{ {
File.Copy(StrongNameKeyFile, Path.Combine(targetDirectory, Path.GetFileName(StrongNameKeyFile)), overwrite: true); File.Copy(StrongNameKeyFile, Path.Combine(targetDirectory, Path.GetFileName(StrongNameKeyFile)), overwrite: true);
} }
projectWriter.Write(projectFileWriter, this, files, moduleDefinition); projectWriter.Write(projectFileWriter, this, files, module);
string platformName = TargetServices.GetPlatformName(moduleDefinition); string platformName = TargetServices.GetPlatformName(module);
return new ProjectId(platformName, ProjectGuid, ProjectTypeGuids.CSharpWindows); return new ProjectId(platformName, ProjectGuid, ProjectTypeGuids.CSharpWindows);
} }
#region WriteCodeFilesInProject #region WriteCodeFilesInProject
protected virtual bool IncludeTypeWhenDecompilingProject(PEFile module, TypeDefinitionHandle type) protected virtual bool IncludeTypeWhenDecompilingProject(MetadataFile module, TypeDefinitionHandle type)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var typeDef = metadata.GetTypeDefinition(type); var typeDef = metadata.GetTypeDefinition(type);
@ -208,7 +214,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
return new[] { new ProjectItemInfo("Compile", assemblyInfo) }; return new[] { new ProjectItemInfo("Compile", assemblyInfo) };
} }
IEnumerable<ProjectItemInfo> WriteCodeFilesInProject(Metadata.PEFile module, IList<PartialTypeInfo> partialTypes, CancellationToken cancellationToken) IEnumerable<ProjectItemInfo> WriteCodeFilesInProject(MetadataFile module, IList<PartialTypeInfo> partialTypes, CancellationToken cancellationToken)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var files = module.Metadata.GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td)) var files = module.Metadata.GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td))
@ -306,7 +312,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
#endregion #endregion
#region WriteResourceFilesInProject #region WriteResourceFilesInProject
protected virtual IEnumerable<ProjectItemInfo> WriteResourceFilesInProject(Metadata.PEFile module) protected virtual IEnumerable<ProjectItemInfo> WriteResourceFilesInProject(MetadataFile module)
{ {
foreach (var r in module.Resources.Where(r => r.ResourceType == ResourceType.Embedded)) foreach (var r in module.Resources.Where(r => r.ResourceType == ResourceType.Embedded))
{ {

2
ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

@ -1100,7 +1100,7 @@ namespace ICSharpCode.Decompiler.CSharp
var genericContext = new GenericContext( var genericContext = new GenericContext(
classTypeParameters: recordTypeDef.TypeParameters, classTypeParameters: recordTypeDef.TypeParameters,
methodTypeParameters: null); methodTypeParameters: null);
var body = typeSystem.MainModule.PEFile.Reader.GetMethodBody(methodDef.RelativeVirtualAddress); var body = typeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
var ilReader = new ILReader(typeSystem.MainModule); var ilReader = new ILReader(typeSystem.MainModule);
var il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken); var il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken);
var settings = new DecompilerSettings(LanguageVersion.CSharp1); var settings = new DecompilerSettings(LanguageVersion.CSharp1);

7
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

@ -58,10 +58,10 @@ namespace ICSharpCode.Decompiler.CSharp
void CollectNamespaces(IEntity entity, MetadataModule module, CodeMappingInfo mappingInfo = null) void CollectNamespaces(IEntity entity, MetadataModule module, CodeMappingInfo mappingInfo = null)
{ {
if (entity == null || entity.MetadataToken.IsNil) if (entity == null || entity.MetadataToken.IsNil || module.MetadataFile is not MetadataFile corFile)
return; return;
if (mappingInfo == null) if (mappingInfo == null)
mappingInfo = CSharpDecompiler.GetCodeMappingInfo(entity.ParentModule.PEFile, entity.MetadataToken); mappingInfo = CSharpDecompiler.GetCodeMappingInfo(corFile, entity.MetadataToken);
switch (entity) switch (entity)
{ {
case ITypeDefinition td: case ITypeDefinition td:
@ -104,7 +104,6 @@ namespace ICSharpCode.Decompiler.CSharp
CollectNamespacesForTypeReference(field.ReturnType); CollectNamespacesForTypeReference(field.ReturnType);
break; break;
case IMethod method: case IMethod method:
var reader = module.PEFile.Reader;
var parts = mappingInfo.GetMethodParts((MethodDefinitionHandle)method.MetadataToken).ToList(); var parts = mappingInfo.GetMethodParts((MethodDefinitionHandle)method.MetadataToken).ToList();
foreach (var part in parts) foreach (var part in parts)
{ {
@ -125,7 +124,7 @@ namespace ICSharpCode.Decompiler.CSharp
MethodBodyBlock body; MethodBodyBlock body;
try try
{ {
body = reader.GetMethodBody(methodDef.RelativeVirtualAddress); body = module.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
} }
catch (BadImageFormatException) catch (BadImageFormatException)
{ {

2
ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs

@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
IMethod ctorMethod = staticCtor.GetSymbol() as IMethod; IMethod ctorMethod = staticCtor.GetSymbol() as IMethod;
if (!ctorMethod.MetadataToken.IsNil) if (!ctorMethod.MetadataToken.IsNil)
{ {
var metadata = context.TypeSystem.MainModule.PEFile.Metadata; var metadata = context.TypeSystem.MainModule.MetadataFile.Metadata;
SRM.MethodDefinition ctorMethodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)ctorMethod.MetadataToken); SRM.MethodDefinition ctorMethodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)ctorMethod.MetadataToken);
SRM.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType()); SRM.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType());
bool declaringTypeIsBeforeFieldInit = declaringType.HasFlag(TypeAttributes.BeforeFieldInit); bool declaringTypeIsBeforeFieldInit = declaringType.HasFlag(TypeAttributes.BeforeFieldInit);

7
ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs

@ -19,15 +19,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using ICSharpCode.Decompiler.CSharp; using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
@ -231,11 +228,11 @@ namespace ICSharpCode.Decompiler.DebugInfo
this.functions.Add(function); this.functions.Add(function);
var method = function.MoveNextMethod ?? function.Method; var method = function.MoveNextMethod ?? function.Method;
MethodDefinitionHandle handle = (MethodDefinitionHandle)method.MetadataToken; MethodDefinitionHandle handle = (MethodDefinitionHandle)method.MetadataToken;
var file = typeSystem.MainModule.PEFile; var file = typeSystem.MainModule.MetadataFile;
MethodDefinition md = file.Metadata.GetMethodDefinition(handle); MethodDefinition md = file.Metadata.GetMethodDefinition(handle);
if (md.HasBody()) if (md.HasBody())
{ {
HandleMethodBody(function, file.Reader.GetMethodBody(md.RelativeVirtualAddress)); HandleMethodBody(function, file.GetMethodBody(md.RelativeVirtualAddress));
} }
} }

4
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -26,10 +26,8 @@ using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using System.Runtime;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading;
using ICSharpCode.Decompiler.CSharp; using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor; using ICSharpCode.Decompiler.CSharp.OutputVisitor;
@ -49,7 +47,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
public static bool HasCodeViewDebugDirectoryEntry(PEFile file) public static bool HasCodeViewDebugDirectoryEntry(PEFile file)
{ {
return file.Reader.ReadDebugDirectory().Any(entry => entry.Type == DebugDirectoryEntryType.CodeView); return file != null && file.Reader.ReadDebugDirectory().Any(entry => entry.Type == DebugDirectoryEntryType.CodeView);
} }
private static bool IncludeTypeWhenGeneratingPdb(PEFile module, TypeDefinitionHandle type, DecompilerSettings settings) private static bool IncludeTypeWhenGeneratingPdb(PEFile module, TypeDefinitionHandle type, DecompilerSettings settings)

6
ICSharpCode.Decompiler/DecompilerException.cs

@ -42,18 +42,18 @@ namespace ICSharpCode.Decompiler
public IEntity DecompiledEntity { get; } public IEntity DecompiledEntity { get; }
public IModule Module { get; } public IModule Module { get; }
public PEFile File { get; } public MetadataFile File { get; }
public DecompilerException(MetadataModule module, IEntity decompiledEntity, public DecompilerException(MetadataModule module, IEntity decompiledEntity,
Exception innerException, string message = null) Exception innerException, string message = null)
: base(message ?? GetDefaultMessage(decompiledEntity), innerException) : base(message ?? GetDefaultMessage(decompiledEntity), innerException)
{ {
this.File = module.PEFile; this.File = module.MetadataFile;
this.Module = module; this.Module = module;
this.DecompiledEntity = decompiledEntity; this.DecompiledEntity = decompiledEntity;
} }
public DecompilerException(PEFile file, string message, Exception innerException) public DecompilerException(MetadataFile file, string message, Exception innerException)
: base(message, innerException) : base(message, innerException)
{ {
this.File = file; this.File = file;

8
ICSharpCode.Decompiler/Disassembler/ILStructure.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary> /// </summary>
public class ILStructure public class ILStructure
{ {
public readonly PEFile Module; public readonly MetadataFile Module;
public readonly MethodDefinitionHandle MethodHandle; public readonly MethodDefinitionHandle MethodHandle;
public readonly MetadataGenericContext GenericContext; public readonly MetadataGenericContext GenericContext;
public readonly ILStructureType Type; public readonly ILStructureType Type;
@ -88,7 +88,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary> /// </summary>
public readonly List<ILStructure> Children = new List<ILStructure>(); public readonly List<ILStructure> Children = new List<ILStructure>();
public ILStructure(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, MethodBodyBlock body) public ILStructure(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, MethodBodyBlock body)
: this(module, handle, genericContext, ILStructureType.Root, 0, body.GetILReader().Length) : this(module, handle, genericContext, ILStructureType.Root, 0, body.GetILReader().Length)
{ {
// Build the tree of exception structures: // Build the tree of exception structures:
@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Disassembler
SortChildren(); SortChildren();
} }
public ILStructure(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default) public ILStructure(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default)
{ {
Debug.Assert(startOffset < endOffset); Debug.Assert(startOffset < endOffset);
this.Module = module; this.Module = module;
@ -154,7 +154,7 @@ namespace ICSharpCode.Decompiler.Disassembler
this.ExceptionHandler = handler; this.ExceptionHandler = handler;
} }
public ILStructure(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint) public ILStructure(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)
{ {
Debug.Assert(startOffset < endOffset); Debug.Assert(startOffset < endOffset);
this.Module = module; this.Module = module;

19
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.Decompiler.Disassembler
int nextSequencePointIndex; int nextSequencePointIndex;
// cache info // cache info
PEFile module; MetadataFile module;
MetadataReader metadata; MetadataReader metadata;
MetadataGenericContext genericContext; MetadataGenericContext genericContext;
DisassemblerSignatureTypeProvider signatureDecoder; DisassemblerSignatureTypeProvider signatureDecoder;
@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.Disassembler
this.cancellationToken = cancellationToken; this.cancellationToken = cancellationToken;
} }
public virtual void Disassemble(PEFile module, MethodDefinitionHandle handle) public virtual void Disassemble(MetadataFile module, MethodDefinitionHandle handle)
{ {
this.module = module ?? throw new ArgumentNullException(nameof(module)); this.module = module ?? throw new ArgumentNullException(nameof(module));
metadata = module.Metadata; metadata = module.Metadata;
@ -105,8 +105,8 @@ namespace ICSharpCode.Decompiler.Disassembler
BlobReader bodyBlockReader; BlobReader bodyBlockReader;
try try
{ {
body = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); body = module.GetMethodBody(methodDefinition.RelativeVirtualAddress);
bodyBlockReader = module.Reader.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader(); bodyBlockReader = module.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader();
} }
catch (BadImageFormatException ex) catch (BadImageFormatException ex)
{ {
@ -119,7 +119,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine("// Code size: {0} (0x{0:x})", blob.Length); output.WriteLine("// Code size: {0} (0x{0:x})", blob.Length);
output.WriteLine(".maxstack {0}", body.MaxStack); output.WriteLine(".maxstack {0}", body.MaxStack);
var entrypointHandle = MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress); var entrypointHandle = MetadataTokens.MethodDefinitionHandle(module.CorHeader?.EntryPointTokenOrRelativeVirtualAddress ?? 0);
if (handle == entrypointHandle) if (handle == entrypointHandle)
output.WriteLine(".entrypoint"); output.WriteLine(".entrypoint");
@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.Disassembler
while (blob.RemainingBytes > 0) while (blob.RemainingBytes > 0)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
WriteInstruction(output, metadata, handle, ref blob, methodDefinition.RelativeVirtualAddress); WriteInstruction(output, module, handle, ref blob, methodDefinition.RelativeVirtualAddress);
} }
WriteExceptionHandlers(module, handle, body); WriteExceptionHandlers(module, handle, body);
} }
@ -195,7 +195,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine(")"); output.WriteLine(")");
} }
internal void WriteExceptionHandlers(PEFile module, MethodDefinitionHandle handle, MethodBodyBlock body) internal void WriteExceptionHandlers(MetadataFile module, MethodDefinitionHandle handle, MethodBodyBlock body)
{ {
this.module = module; this.module = module;
metadata = module.Metadata; metadata = module.Metadata;
@ -291,7 +291,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
var currentOpCode = ILParser.DecodeOpCode(ref body); var currentOpCode = ILParser.DecodeOpCode(ref body);
body.Offset = offset; // reset IL stream body.Offset = offset; // reset IL stream
WriteInstruction(output, metadata, s.MethodHandle, ref body, methodRva); WriteInstruction(output, module, s.MethodHandle, ref body, methodRva);
prevInstructionWasBranch = currentOpCode.IsBranch() prevInstructionWasBranch = currentOpCode.IsBranch()
|| currentOpCode.IsReturn() || currentOpCode.IsReturn()
|| currentOpCode == ILOpCode.Throw || currentOpCode == ILOpCode.Throw
@ -324,8 +324,9 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
protected virtual void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva) protected virtual void WriteInstruction(ITextOutput output, MetadataFile metadataFile, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva)
{ {
var metadata = metadataFile.Metadata;
int offset = blob.Offset; int offset = blob.Offset;
if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count) if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count)
{ {

96
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -143,7 +143,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ MethodImplAttributes.AggressiveInlining, "aggressiveinlining" }, { MethodImplAttributes.AggressiveInlining, "aggressiveinlining" },
}; };
public void DisassembleMethod(PEFile module, MethodDefinitionHandle handle) public void DisassembleMethod(MetadataFile module, MethodDefinitionHandle handle)
{ {
var genericContext = new MetadataGenericContext(handle, module); var genericContext = new MetadataGenericContext(handle, module);
// write method header // write method header
@ -153,7 +153,7 @@ namespace ICSharpCode.Decompiler.Disassembler
DisassembleMethodBlock(module, handle, genericContext); DisassembleMethodBlock(module, handle, genericContext);
} }
public void DisassembleMethodHeader(PEFile module, MethodDefinitionHandle handle) public void DisassembleMethodHeader(MetadataFile module, MethodDefinitionHandle handle)
{ {
var genericContext = new MetadataGenericContext(handle, module); var genericContext = new MetadataGenericContext(handle, module);
// write method header // write method header
@ -162,7 +162,7 @@ namespace ICSharpCode.Decompiler.Disassembler
DisassembleMethodHeaderInternal(module, handle, genericContext); DisassembleMethodHeaderInternal(module, handle, genericContext);
} }
void DisassembleMethodHeaderInternal(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext) void DisassembleMethodHeaderInternal(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
@ -310,7 +310,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Unindent(); output.Unindent();
} }
internal static void WriteMetadataToken(ITextOutput output, PEFile module, Handle? handle, internal static void WriteMetadataToken(ITextOutput output, MetadataFile module, Handle? handle,
int metadataToken, bool spaceAfter, bool spaceBefore, bool showMetadataTokens, bool base10) int metadataToken, bool spaceAfter, bool spaceBefore, bool showMetadataTokens, bool base10)
{ {
// handle can be null in case of errors, if that's the case, we always want to print a comment, // handle can be null in case of errors, if that's the case, we always want to print a comment,
@ -344,7 +344,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
void DisassembleMethodBlock(PEFile module, MethodDefinitionHandle handle, void DisassembleMethodBlock(MetadataFile module, MethodDefinitionHandle handle,
MetadataGenericContext genericContext) MetadataGenericContext genericContext)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
@ -380,7 +380,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
#region Write Security Declarations #region Write Security Declarations
void WriteSecurityDeclarations(PEFile module, DeclarativeSecurityAttributeHandleCollection secDeclProvider) void WriteSecurityDeclarations(MetadataFile module, DeclarativeSecurityAttributeHandleCollection secDeclProvider)
{ {
if (secDeclProvider.Count == 0) if (secDeclProvider.Count == 0)
return; return;
@ -479,9 +479,9 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
readonly ITextOutput output; readonly ITextOutput output;
readonly IAssemblyResolver resolver; readonly IAssemblyResolver resolver;
readonly PEFile module; readonly MetadataFile module;
public SecurityDeclarationDecoder(ITextOutput output, IAssemblyResolver resolver, PEFile module) public SecurityDeclarationDecoder(ITextOutput output, IAssemblyResolver resolver, MetadataFile module)
{ {
this.output = output; this.output = output;
this.resolver = resolver; this.resolver = resolver;
@ -535,11 +535,11 @@ namespace ICSharpCode.Decompiler.Disassembler
return "type" == type.Item2; return "type" == type.Item2;
} }
(PEFile, TypeDefinitionHandle) ResolveType(string typeName, PEFile module) (MetadataFile, TypeDefinitionHandle) ResolveType(string typeName, MetadataFile module)
{ {
string[] nameParts = typeName.Split(new[] { ", " }, 2, StringSplitOptions.None); string[] nameParts = typeName.Split(new[] { ", " }, 2, StringSplitOptions.None);
string[] typeNameParts = nameParts[0].Split('.'); string[] typeNameParts = nameParts[0].Split('.');
PEFile containingModule = null; MetadataFile containingModule = null;
TypeDefinitionHandle typeDefHandle = default; TypeDefinitionHandle typeDefHandle = default;
// if we deal with an assembly-qualified name, resolve the assembly // if we deal with an assembly-qualified name, resolve the assembly
if (nameParts.Length == 2) if (nameParts.Length == 2)
@ -564,7 +564,7 @@ namespace ICSharpCode.Decompiler.Disassembler
return (containingModule, typeDefHandle); return (containingModule, typeDefHandle);
TypeDefinitionHandle FindType(PEFile currentModule, string[] name) TypeDefinitionHandle FindType(MetadataFile currentModule, string[] name)
{ {
var metadata = currentModule.Metadata; var metadata = currentModule.Metadata;
var currentNamespace = metadata.GetNamespaceDefinitionRoot(); var currentNamespace = metadata.GetNamespaceDefinitionRoot();
@ -618,9 +618,9 @@ namespace ICSharpCode.Decompiler.Disassembler
return typeCode; return typeCode;
} }
PEFile mscorlib; MetadataFile mscorlib;
bool TryResolveMscorlib(out PEFile mscorlib) bool TryResolveMscorlib(out MetadataFile mscorlib)
{ {
mscorlib = null; mscorlib = null;
if (this.mscorlib != null) if (this.mscorlib != null)
@ -637,7 +637,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
void TryDecodeSecurityDeclaration(TextOutputWithRollback output, BlobReader blob, PEFile module) void TryDecodeSecurityDeclaration(TextOutputWithRollback output, BlobReader blob, MetadataFile module)
{ {
output.WriteLine(" = {"); output.WriteLine(" = {");
output.Indent(); output.Indent();
@ -1134,7 +1134,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine(); output.WriteLine();
} }
void WriteGenericParametersAndAttributes(PEFile module, MetadataGenericContext context, GenericParameterHandle handle) void WriteGenericParametersAndAttributes(MetadataFile module, MetadataGenericContext context, GenericParameterHandle handle)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var p = metadata.GetGenericParameter(handle); var p = metadata.GetGenericParameter(handle);
@ -1161,7 +1161,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
void WriteParameterAttributes(PEFile module, ParameterHandle handle) void WriteParameterAttributes(MetadataFile module, ParameterHandle handle)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var p = metadata.GetParameter(handle); var p = metadata.GetParameter(handle);
@ -1247,7 +1247,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ FieldAttributes.NotSerialized, "notserialized" }, { FieldAttributes.NotSerialized, "notserialized" },
}; };
public void DisassembleField(PEFile module, FieldDefinitionHandle handle) public void DisassembleField(MetadataFile module, FieldDefinitionHandle handle)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(handle); var fieldDefinition = metadata.GetFieldDefinition(handle);
@ -1264,7 +1264,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
// Field data as specified in II.16.3.1 of ECMA-335 6th edition // Field data as specified in II.16.3.1 of ECMA-335 6th edition
int rva = fieldDefinition.GetRelativeVirtualAddress(); int rva = fieldDefinition.GetRelativeVirtualAddress();
int sectionIndex = module.Reader.PEHeaders.GetContainingSectionIndex(rva); int sectionIndex = module.GetContainingSectionIndex(rva);
if (sectionIndex < 0) if (sectionIndex < 0)
{ {
output.WriteLine($"// RVA {rva:X8} invalid (not in any section)"); output.WriteLine($"// RVA {rva:X8} invalid (not in any section)");
@ -1274,7 +1274,7 @@ namespace ICSharpCode.Decompiler.Disassembler
BlobReader initVal; BlobReader initVal;
try try
{ {
initVal = fieldDefinition.GetInitialValue(module.Reader, null); initVal = fieldDefinition.GetInitialValue(module, null);
} }
catch (BadImageFormatException ex) catch (BadImageFormatException ex)
{ {
@ -1283,7 +1283,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
if (initVal.Length > 0) if (initVal.Length > 0)
{ {
var sectionHeader = module.Reader.PEHeaders.SectionHeaders[sectionIndex]; var sectionHeader = module.SectionHeaders[sectionIndex];
output.Write(".data "); output.Write(".data ");
if (sectionHeader.Name == ".text") if (sectionHeader.Name == ".text")
{ {
@ -1293,7 +1293,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
output.Write("tls "); output.Write("tls ");
} }
else if (sectionHeader.Name != ".data") else if (sectionHeader.Name is not (null or ".data"))
{ {
output.Write($"/* {sectionHeader.Name} */ "); output.Write($"/* {sectionHeader.Name} */ ");
} }
@ -1305,14 +1305,14 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
public void DisassembleFieldHeader(PEFile module, FieldDefinitionHandle handle) public void DisassembleFieldHeader(MetadataFile module, FieldDefinitionHandle handle)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(handle); var fieldDefinition = metadata.GetFieldDefinition(handle);
DisassembleFieldHeaderInternal(module, handle, metadata, fieldDefinition); DisassembleFieldHeaderInternal(module, handle, metadata, fieldDefinition);
} }
private char DisassembleFieldHeaderInternal(PEFile module, FieldDefinitionHandle handle, MetadataReader metadata, FieldDefinition fieldDefinition) private char DisassembleFieldHeaderInternal(MetadataFile module, FieldDefinitionHandle handle, MetadataReader metadata, FieldDefinition fieldDefinition)
{ {
output.WriteReference(module, handle, ".field", isDefinition: true); output.WriteReference(module, handle, ".field", isDefinition: true);
WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle), WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),
@ -1342,7 +1342,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (fieldDefinition.HasFlag(FieldAttributes.HasFieldRVA)) if (fieldDefinition.HasFlag(FieldAttributes.HasFieldRVA))
{ {
int rva = fieldDefinition.GetRelativeVirtualAddress(); int rva = fieldDefinition.GetRelativeVirtualAddress();
sectionPrefix = GetRVASectionPrefix(module.Reader.PEHeaders, rva); sectionPrefix = GetRVASectionPrefix(module, rva);
output.Write(" at {1}_{0:X8}", rva, sectionPrefix); output.Write(" at {1}_{0:X8}", rva, sectionPrefix);
} }
@ -1356,12 +1356,14 @@ namespace ICSharpCode.Decompiler.Disassembler
return sectionPrefix; return sectionPrefix;
} }
char GetRVASectionPrefix(System.Reflection.PortableExecutable.PEHeaders headers, int rva) char GetRVASectionPrefix(MetadataFile module, int rva)
{ {
int sectionIndex = headers.GetContainingSectionIndex(rva); if (module is not PEFile peFile)
throw new NotSupportedException("Cannot get RVA section prefix from module");
int sectionIndex = peFile.Reader.PEHeaders.GetContainingSectionIndex(rva);
if (sectionIndex < 0) if (sectionIndex < 0)
return 'D'; return 'D';
var sectionHeader = headers.SectionHeaders[sectionIndex]; var sectionHeader = peFile.Reader.PEHeaders.SectionHeaders[sectionIndex];
switch (sectionHeader.Name) switch (sectionHeader.Name)
{ {
case ".tls": case ".tls":
@ -1381,7 +1383,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ PropertyAttributes.HasDefault, "hasdefault" }, { PropertyAttributes.HasDefault, "hasdefault" },
}; };
public void DisassembleProperty(PEFile module, PropertyDefinitionHandle property) public void DisassembleProperty(MetadataFile module, PropertyDefinitionHandle property)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property); var propertyDefinition = metadata.GetPropertyDefinition(property);
@ -1398,14 +1400,14 @@ namespace ICSharpCode.Decompiler.Disassembler
CloseBlock(); CloseBlock();
} }
public void DisassemblePropertyHeader(PEFile module, PropertyDefinitionHandle property) public void DisassemblePropertyHeader(MetadataFile module, PropertyDefinitionHandle property)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property); var propertyDefinition = metadata.GetPropertyDefinition(property);
DisassemblePropertyHeaderInternal(module, property, metadata, propertyDefinition); DisassemblePropertyHeaderInternal(module, property, metadata, propertyDefinition);
} }
private PropertyAccessors DisassemblePropertyHeaderInternal(PEFile module, PropertyDefinitionHandle handle, MetadataReader metadata, PropertyDefinition propertyDefinition) private PropertyAccessors DisassemblePropertyHeaderInternal(MetadataFile module, PropertyDefinitionHandle handle, MetadataReader metadata, PropertyDefinition propertyDefinition)
{ {
output.WriteReference(module, handle, ".property", isDefinition: true); output.WriteReference(module, handle, ".property", isDefinition: true);
WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle), WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),
@ -1436,7 +1438,7 @@ namespace ICSharpCode.Decompiler.Disassembler
return accessors; return accessors;
} }
void WriteNestedMethod(string keyword, PEFile module, MethodDefinitionHandle method) void WriteNestedMethod(string keyword, MetadataFile module, MethodDefinitionHandle method)
{ {
if (method.IsNil) if (method.IsNil)
return; return;
@ -1454,7 +1456,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ EventAttributes.RTSpecialName, "rtspecialname" }, { EventAttributes.RTSpecialName, "rtspecialname" },
}; };
public void DisassembleEvent(PEFile module, EventDefinitionHandle handle) public void DisassembleEvent(MetadataFile module, EventDefinitionHandle handle)
{ {
var eventDefinition = module.Metadata.GetEventDefinition(handle); var eventDefinition = module.Metadata.GetEventDefinition(handle);
var accessors = eventDefinition.GetAccessors(); var accessors = eventDefinition.GetAccessors();
@ -1471,14 +1473,14 @@ namespace ICSharpCode.Decompiler.Disassembler
CloseBlock(); CloseBlock();
} }
public void DisassembleEventHeader(PEFile module, EventDefinitionHandle handle) public void DisassembleEventHeader(MetadataFile module, EventDefinitionHandle handle)
{ {
var eventDefinition = module.Metadata.GetEventDefinition(handle); var eventDefinition = module.Metadata.GetEventDefinition(handle);
var accessors = eventDefinition.GetAccessors(); var accessors = eventDefinition.GetAccessors();
DisassembleEventHeaderInternal(module, handle, eventDefinition, accessors); DisassembleEventHeaderInternal(module, handle, eventDefinition, accessors);
} }
private void DisassembleEventHeaderInternal(PEFile module, EventDefinitionHandle handle, EventDefinition eventDefinition, EventAccessors accessors) private void DisassembleEventHeaderInternal(MetadataFile module, EventDefinitionHandle handle, EventDefinition eventDefinition, EventAccessors accessors)
{ {
TypeDefinitionHandle declaringType; TypeDefinitionHandle declaringType;
if (!accessors.Adder.IsNil) if (!accessors.Adder.IsNil)
@ -1555,7 +1557,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ TypeAttributes.HasSecurity, null }, { TypeAttributes.HasSecurity, null },
}; };
public void DisassembleType(PEFile module, TypeDefinitionHandle type) public void DisassembleType(MetadataFile module, TypeDefinitionHandle type)
{ {
var typeDefinition = module.Metadata.GetTypeDefinition(type); var typeDefinition = module.Metadata.GetTypeDefinition(type);
MetadataGenericContext genericContext = new MetadataGenericContext(type, module); MetadataGenericContext genericContext = new MetadataGenericContext(type, module);
@ -1676,14 +1678,14 @@ namespace ICSharpCode.Decompiler.Disassembler
isInType = oldIsInType; isInType = oldIsInType;
} }
public void DisassembleTypeHeader(PEFile module, TypeDefinitionHandle type) public void DisassembleTypeHeader(MetadataFile module, TypeDefinitionHandle type)
{ {
var typeDefinition = module.Metadata.GetTypeDefinition(type); var typeDefinition = module.Metadata.GetTypeDefinition(type);
MetadataGenericContext genericContext = new MetadataGenericContext(type, module); MetadataGenericContext genericContext = new MetadataGenericContext(type, module);
DisassembleTypeHeaderInternal(module, type, typeDefinition, genericContext); DisassembleTypeHeaderInternal(module, type, typeDefinition, genericContext);
} }
private void DisassembleTypeHeaderInternal(PEFile module, TypeDefinitionHandle handle, TypeDefinition typeDefinition, MetadataGenericContext genericContext) private void DisassembleTypeHeaderInternal(MetadataFile module, TypeDefinitionHandle handle, TypeDefinition typeDefinition, MetadataGenericContext genericContext)
{ {
output.WriteReference(module, handle, ".class", isDefinition: true); output.WriteReference(module, handle, ".class", isDefinition: true);
WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle), WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),
@ -1712,7 +1714,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
void WriteTypeParameters(ITextOutput output, PEFile module, MetadataGenericContext context, GenericParameterHandleCollection p) void WriteTypeParameters(ITextOutput output, MetadataFile module, MetadataGenericContext context, GenericParameterHandleCollection p)
{ {
if (p.Count > 0) if (p.Count > 0)
{ {
@ -1765,37 +1767,37 @@ namespace ICSharpCode.Decompiler.Disassembler
#region Processing #region Processing
private IReadOnlyCollection<InterfaceImplementationHandle> Process(PEFile module, IReadOnlyCollection<InterfaceImplementationHandle> items) private IReadOnlyCollection<InterfaceImplementationHandle> Process(MetadataFile module, IReadOnlyCollection<InterfaceImplementationHandle> items)
{ {
return EntityProcessor?.Process(module, items) ?? items; return EntityProcessor?.Process(module, items) ?? items;
} }
private IReadOnlyCollection<TypeDefinitionHandle> Process(PEFile module, IReadOnlyCollection<TypeDefinitionHandle> items) private IReadOnlyCollection<TypeDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<TypeDefinitionHandle> items)
{ {
return EntityProcessor?.Process(module, items) ?? items; return EntityProcessor?.Process(module, items) ?? items;
} }
private IReadOnlyCollection<MethodDefinitionHandle> Process(PEFile module, IReadOnlyCollection<MethodDefinitionHandle> items) private IReadOnlyCollection<MethodDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<MethodDefinitionHandle> items)
{ {
return EntityProcessor?.Process(module, items) ?? items; return EntityProcessor?.Process(module, items) ?? items;
} }
private IReadOnlyCollection<PropertyDefinitionHandle> Process(PEFile module, IReadOnlyCollection<PropertyDefinitionHandle> items) private IReadOnlyCollection<PropertyDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<PropertyDefinitionHandle> items)
{ {
return EntityProcessor?.Process(module, items) ?? items; return EntityProcessor?.Process(module, items) ?? items;
} }
private IReadOnlyCollection<EventDefinitionHandle> Process(PEFile module, IReadOnlyCollection<EventDefinitionHandle> items) private IReadOnlyCollection<EventDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<EventDefinitionHandle> items)
{ {
return EntityProcessor?.Process(module, items) ?? items; return EntityProcessor?.Process(module, items) ?? items;
} }
private IReadOnlyCollection<FieldDefinitionHandle> Process(PEFile module, IReadOnlyCollection<FieldDefinitionHandle> items) private IReadOnlyCollection<FieldDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<FieldDefinitionHandle> items)
{ {
return EntityProcessor?.Process(module, items) ?? items; return EntityProcessor?.Process(module, items) ?? items;
} }
private IReadOnlyCollection<CustomAttributeHandle> Process(PEFile module, IReadOnlyCollection<CustomAttributeHandle> items) private IReadOnlyCollection<CustomAttributeHandle> Process(MetadataFile module, IReadOnlyCollection<CustomAttributeHandle> items)
{ {
return EntityProcessor?.Process(module, items) ?? items; return EntityProcessor?.Process(module, items) ?? items;
} }
@ -1804,7 +1806,7 @@ namespace ICSharpCode.Decompiler.Disassembler
#region Helper methods #region Helper methods
void WriteAttributes(PEFile module, CustomAttributeHandleCollection attributes) void WriteAttributes(MetadataFile module, CustomAttributeHandleCollection attributes)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
foreach (CustomAttributeHandle a in Process(module, attributes)) foreach (CustomAttributeHandle a in Process(module, attributes))
@ -1931,7 +1933,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
#endregion #endregion
public void DisassembleNamespace(string nameSpace, PEFile module, IEnumerable<TypeDefinitionHandle> types) public void DisassembleNamespace(string nameSpace, MetadataFile module, IEnumerable<TypeDefinitionHandle> types)
{ {
if (!string.IsNullOrEmpty(nameSpace)) if (!string.IsNullOrEmpty(nameSpace))
{ {

2
ICSharpCode.Decompiler/Documentation/GetPotentiallyNestedClassTypeReference.cs

@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.Documentation
/// </summary> /// </summary>
/// <returns>Either TypeDefinitionHandle, if the type is defined in the module or ExportedTypeHandle, /// <returns>Either TypeDefinitionHandle, if the type is defined in the module or ExportedTypeHandle,
/// if the module contains a type forwarder. Returns a nil handle, if the type was not found.</returns> /// if the module contains a type forwarder. Returns a nil handle, if the type was not found.</returns>
public EntityHandle ResolveInPEFile(PEFile module) public EntityHandle ResolveInPEFile(MetadataFile module)
{ {
string[] parts = typeName.Split('.'); string[] parts = typeName.Split('.');
for (int i = parts.Length - 1; i >= 0; i--) for (int i = parts.Length - 1; i >= 0; i--)

4
ICSharpCode.Decompiler/Documentation/XmlDocLoader.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.Documentation
public static class XmlDocLoader public static class XmlDocLoader
{ {
static readonly Lazy<XmlDocumentationProvider> mscorlibDocumentation = new Lazy<XmlDocumentationProvider>(LoadMscorlibDocumentation); static readonly Lazy<XmlDocumentationProvider> mscorlibDocumentation = new Lazy<XmlDocumentationProvider>(LoadMscorlibDocumentation);
static readonly ConditionalWeakTable<PEFile, XmlDocumentationProvider> cache = new ConditionalWeakTable<PEFile, XmlDocumentationProvider>(); static readonly ConditionalWeakTable<MetadataFile, XmlDocumentationProvider> cache = new();
static XmlDocumentationProvider LoadMscorlibDocumentation() static XmlDocumentationProvider LoadMscorlibDocumentation()
{ {
@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.Documentation
get { return mscorlibDocumentation.Value; } get { return mscorlibDocumentation.Value; }
} }
public static XmlDocumentationProvider LoadDocumentation(PEFile module) public static XmlDocumentationProvider LoadDocumentation(MetadataFile module)
{ {
if (module == null) if (module == null)
throw new ArgumentNullException(nameof(module)); throw new ArgumentNullException(nameof(module));

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -98,6 +98,7 @@
<Compile Include="Disassembler\IEntityProcessor.cs" /> <Compile Include="Disassembler\IEntityProcessor.cs" />
<Compile Include="Disassembler\SortByNameProcessor.cs" /> <Compile Include="Disassembler\SortByNameProcessor.cs" />
<Compile Include="IL\ApplyPdbLocalTypeInfoTypeVisitor.cs" /> <Compile Include="IL\ApplyPdbLocalTypeInfoTypeVisitor.cs" />
<Compile Include="Metadata\MetadataFile.cs" />
<Compile Include="Metadata\ModuleReferenceMetadata.cs" /> <Compile Include="Metadata\ModuleReferenceMetadata.cs" />
<Compile Include="NRTAttributes.cs" /> <Compile Include="NRTAttributes.cs" />
<Compile Include="PartialTypeInfo.cs" /> <Compile Include="PartialTypeInfo.cs" />

6
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -26,8 +26,8 @@ using System.Reflection.Metadata;
using ICSharpCode.Decompiler.CSharp; using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.DebugInfo; using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL.ControlFlow namespace ICSharpCode.Decompiler.IL.ControlFlow
@ -53,11 +53,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return false; return false;
} }
internal static bool IsCompilerGeneratedMainMethod(Metadata.PEFile module, MethodDefinitionHandle method) internal static bool IsCompilerGeneratedMainMethod(MetadataFile module, MethodDefinitionHandle method)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var definition = metadata.GetMethodDefinition(method); var definition = metadata.GetMethodDefinition(method);
var entrypoint = System.Reflection.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress); var entrypoint = System.Reflection.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(module.CorHeader?.EntryPointTokenOrRelativeVirtualAddress ?? 0);
return method == entrypoint && metadata.GetString(definition.Name).Equals("<Main>", StringComparison.Ordinal); return method == entrypoint && metadata.GetString(definition.Name).Equals("<Main>", StringComparison.Ordinal);
} }

4
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -496,7 +496,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
classTypeParameters: (genericContext.ClassTypeParameters ?? EmptyList<ITypeParameter>.Instance) classTypeParameters: (genericContext.ClassTypeParameters ?? EmptyList<ITypeParameter>.Instance)
.Concat(genericContext.MethodTypeParameters ?? EmptyList<ITypeParameter>.Instance).ToArray(), .Concat(genericContext.MethodTypeParameters ?? EmptyList<ITypeParameter>.Instance).ToArray(),
methodTypeParameters: null); methodTypeParameters: null);
var body = context.TypeSystem.MainModule.PEFile.Reader.GetMethodBody(methodDef.RelativeVirtualAddress); var body = context.TypeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
var il = context.CreateILReader() var il = context.CreateILReader()
.ReadIL(method, body, genericContext, ILFunctionKind.TopLevelFunction, context.CancellationToken); .ReadIL(method, body, genericContext, ILFunctionKind.TopLevelFunction, context.CancellationToken);
il.RunTransforms(CSharpDecompiler.EarlyILTransforms(true), il.RunTransforms(CSharpDecompiler.EarlyILTransforms(true),
@ -1438,7 +1438,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
ITypeDefinition declaringTypeDefinition = call.Method.DeclaringTypeDefinition; ITypeDefinition declaringTypeDefinition = call.Method.DeclaringTypeDefinition;
if (declaringTypeDefinition.MetadataToken != this.enumeratorType) if (declaringTypeDefinition.MetadataToken != this.enumeratorType)
return false; return false;
if (declaringTypeDefinition.ParentModule.PEFile.Metadata != metadata) if (declaringTypeDefinition.ParentModule.MetadataFile.Metadata != metadata)
return false; return false;
finallyMethod = call.Method; finallyMethod = call.Method;
return !call.Method.MetadataToken.IsNil; return !call.Method.MetadataToken.IsNil;

2
ICSharpCode.Decompiler/IL/ILReader.cs

@ -690,7 +690,7 @@ namespace ICSharpCode.Decompiler.IL
output.WriteLine(); output.WriteLine();
} }
new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false } new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false }
.WriteExceptionHandlers(module.PEFile, method, body); .WriteExceptionHandlers(module.MetadataFile, method, body);
} }
/// <summary> /// <summary>

2
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -189,7 +189,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (genericContext == null) if (genericContext == null)
return null; return null;
var ilReader = context.CreateILReader(); var ilReader = context.CreateILReader();
var body = context.PEFile.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); var body = context.PEFile.GetMethodBody(methodDefinition.RelativeVirtualAddress);
var function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, genericContext.Value, ILFunctionKind.Delegate, context.CancellationToken); var function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, genericContext.Value, ILFunctionKind.Delegate, context.CancellationToken);
function.DelegateType = delegateType; function.DelegateType = delegateType;
// Embed the lambda into the parent function's ILAst, so that "Show steps" can show // Embed the lambda into the parent function's ILAst, so that "Show steps" can show

2
ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public DecompilerSettings Settings { get; } public DecompilerSettings Settings { get; }
public CancellationToken CancellationToken { get; set; } public CancellationToken CancellationToken { get; set; }
public Stepper Stepper { get; set; } public Stepper Stepper { get; set; }
public Metadata.PEFile PEFile => TypeSystem.MainModule.PEFile; public Metadata.MetadataFile PEFile => TypeSystem.MainModule.MetadataFile;
internal DecompileRun? DecompileRun { get; set; } internal DecompileRun? DecompileRun { get; set; }
internal ResolvedUsingScope? UsingScope => DecompileRun?.UsingScope.Resolve(TypeSystem); internal ResolvedUsingScope? UsingScope => DecompileRun?.UsingScope.Resolve(TypeSystem);

12
ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs

@ -80,7 +80,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// Disable the transform if we are decompiling a display-class or local function method: // Disable the transform if we are decompiling a display-class or local function method:
// This happens if a local function or display class is selected in the ILSpy tree view. // This happens if a local function or display class is selected in the ILSpy tree view.
if (IsLocalFunctionMethod(function.Method, context) || IsLocalFunctionDisplayClass( if (IsLocalFunctionMethod(function.Method, context) || IsLocalFunctionDisplayClass(
function.Method.ParentModule.PEFile, function.Method.ParentModule.MetadataFile,
(TypeDefinitionHandle)function.Method.DeclaringTypeDefinition.MetadataToken, (TypeDefinitionHandle)function.Method.DeclaringTypeDefinition.MetadataToken,
context) context)
) )
@ -462,7 +462,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
else else
{ {
var ilReader = context.CreateILReader(); var ilReader = context.CreateILReader();
var body = context.PEFile.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); var body = context.PEFile.GetMethodBody(methodDefinition.RelativeVirtualAddress);
function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body,
genericContext.GetValueOrDefault(), ILFunctionKind.LocalFunction, genericContext.GetValueOrDefault(), ILFunctionKind.LocalFunction,
@ -755,10 +755,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (method.MetadataToken.IsNil) if (method.MetadataToken.IsNil)
return false; return false;
return IsLocalFunctionMethod(method.ParentModule.PEFile, (MethodDefinitionHandle)method.MetadataToken, context); return IsLocalFunctionMethod(method.ParentModule.MetadataFile, (MethodDefinitionHandle)method.MetadataToken, context);
} }
public static bool IsLocalFunctionMethod(PEFile module, MethodDefinitionHandle methodHandle, ILTransformContext context = null) public static bool IsLocalFunctionMethod(MetadataFile module, MethodDefinitionHandle methodHandle, ILTransformContext context = null)
{ {
if (context != null && context.PEFile != module) if (context != null && context.PEFile != module)
return false; return false;
@ -776,7 +776,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true; return true;
} }
public static bool LocalFunctionNeedsAccessibilityChange(PEFile module, MethodDefinitionHandle methodHandle) public static bool LocalFunctionNeedsAccessibilityChange(MetadataFile module, MethodDefinitionHandle methodHandle)
{ {
if (!IsLocalFunctionMethod(module, methodHandle)) if (!IsLocalFunctionMethod(module, methodHandle))
return false; return false;
@ -797,7 +797,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
} }
public static bool IsLocalFunctionDisplayClass(PEFile module, TypeDefinitionHandle typeHandle, ILTransformContext context = null) public static bool IsLocalFunctionDisplayClass(MetadataFile module, TypeDefinitionHandle typeHandle, ILTransformContext context = null)
{ {
if (context != null && context.PEFile != module) if (context != null && context.PEFile != module)
return false; return false;

2
ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var genericContext = new GenericContext(inst.Method); var genericContext = new GenericContext(inst.Method);
// partially copied from CSharpDecompiler // partially copied from CSharpDecompiler
var ilReader = context.CreateILReader(); var ilReader = context.CreateILReader();
var body = context.PEFile.Reader.GetMethodBody(methodDef.RelativeVirtualAddress); var body = context.PEFile.GetMethodBody(methodDef.RelativeVirtualAddress);
var proxyFunction = ilReader.ReadIL(handle, body, genericContext, ILFunctionKind.TopLevelFunction, context.CancellationToken); var proxyFunction = ilReader.ReadIL(handle, body, genericContext, ILFunctionKind.TopLevelFunction, context.CancellationToken);
var transformContext = new ILTransformContext(context, proxyFunction); var transformContext = new ILTransformContext(context, proxyFunction);
proxyFunction.RunTransforms(CSharp.CSharpDecompiler.EarlyILTransforms(), transformContext); proxyFunction.RunTransforms(CSharp.CSharpDecompiler.EarlyILTransforms(), transformContext);

8
ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs

@ -124,7 +124,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA)) if (field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))
{ {
var valuesList = new List<ILInstruction>(); var valuesList = new List<ILInstruction>();
var initialValue = field.GetInitialValue(context.PEFile.Reader, context.TypeSystem); var initialValue = field.GetInitialValue(context.PEFile, context.TypeSystem);
if (context.Settings.Utf8StringLiterals && if (context.Settings.Utf8StringLiterals &&
elementType.IsKnownType(KnownTypeCode.Byte) && elementType.IsKnownType(KnownTypeCode.Byte) &&
DecodeUTF8String(initialValue, size, out string text)) DecodeUTF8String(initialValue, size, out string text))
@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
return false; return false;
} }
blob = fd.GetInitialValue(context.PEFile.Reader, context.TypeSystem); blob = fd.GetInitialValue(context.PEFile, context.TypeSystem);
return true; return true;
} }
@ -720,7 +720,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA)) if (field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))
{ {
var valuesList = new List<ILInstruction>(); var valuesList = new List<ILInstruction>();
var initialValue = field.GetInitialValue(context.PEFile.Reader, context.TypeSystem); var initialValue = field.GetInitialValue(context.PEFile, context.TypeSystem);
if (DecodeArrayInitializer(arrayType, initialValue, arrayLength, valuesList)) if (DecodeArrayInitializer(arrayType, initialValue, arrayLength, valuesList))
{ {
values = valuesList.ToArray(); values = valuesList.ToArray();
@ -753,7 +753,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA)) if (!field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))
return false; return false;
var valuesList = new List<ILInstruction>(); var valuesList = new List<ILInstruction>();
var initialValue = field.GetInitialValue(context.PEFile.Reader, context.TypeSystem); var initialValue = field.GetInitialValue(context.PEFile, context.TypeSystem);
if (!DecodeArrayInitializer(elementType, initialValue, arrayLength, valuesList)) if (!DecodeArrayInitializer(elementType, initialValue, arrayLength, valuesList))
return false; return false;
context.Step("InlineRuntimeHelpersInitializeArray: single-dim", inst); context.Step("InlineRuntimeHelpersInitializeArray: single-dim", inst);

8
ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

@ -413,11 +413,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (definition == null) if (definition == null)
return false; return false;
if (definition.ParentModule.PEFile != context.PEFile) if (definition.ParentModule.MetadataFile != context.PEFile)
return false; return false;
// We do not want to accidentially transform state-machines and thus destroy them. // We do not want to accidentially transform state-machines and thus destroy them.
var token = (TypeDefinitionHandle)definition.MetadataToken; var token = (TypeDefinitionHandle)definition.MetadataToken;
var metadata = definition.ParentModule.PEFile.Metadata; var metadata = definition.ParentModule.MetadataFile.Metadata;
if (YieldReturnDecompiler.IsCompilerGeneratorEnumerator(token, metadata)) if (YieldReturnDecompiler.IsCompilerGeneratorEnumerator(token, metadata))
return false; return false;
if (AsyncAwaitDecompiler.IsCompilerGeneratedStateMachine(token, metadata)) if (AsyncAwaitDecompiler.IsCompilerGeneratedStateMachine(token, metadata))
@ -440,13 +440,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
var handle = (MethodDefinitionHandle)method.MetadataToken; var handle = (MethodDefinitionHandle)method.MetadataToken;
var module = (MetadataModule)method.ParentModule; var module = (MetadataModule)method.ParentModule;
var file = module.PEFile; var file = module.MetadataFile;
if (handle.IsNil || file != context.PEFile) if (handle.IsNil || file != context.PEFile)
return false; return false;
var def = file.Metadata.GetMethodDefinition(handle); var def = file.Metadata.GetMethodDefinition(handle);
if (def.RelativeVirtualAddress == 0) if (def.RelativeVirtualAddress == 0)
return false; return false;
var body = file.Reader.GetMethodBody(def.RelativeVirtualAddress); var body = file.GetMethodBody(def.RelativeVirtualAddress);
// some compilers produce ctors with unused local variables // some compilers produce ctors with unused local variables
// see https://github.com/icsharpcode/ILSpy/issues/2174 // see https://github.com/icsharpcode/ILSpy/issues/2174
//if (!body.LocalSignature.IsNil) //if (!body.LocalSignature.IsNil)

10
ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs

@ -61,10 +61,10 @@ namespace ICSharpCode.Decompiler.Metadata
public interface IAssemblyResolver public interface IAssemblyResolver
{ {
#if !VSADDIN #if !VSADDIN
PEFile? Resolve(IAssemblyReference reference); MetadataFile? Resolve(IAssemblyReference reference);
PEFile? ResolveModule(PEFile mainModule, string moduleName); MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName);
Task<PEFile?> ResolveAsync(IAssemblyReference reference); Task<MetadataFile?> ResolveAsync(IAssemblyReference reference);
Task<PEFile?> ResolveModuleAsync(PEFile mainModule, string moduleName); Task<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName);
#endif #endif
} }
@ -323,7 +323,7 @@ namespace ICSharpCode.Decompiler.Metadata
entry = metadata.GetAssemblyReference(handle); entry = metadata.GetAssemblyReference(handle);
} }
public AssemblyReference(PEFile module, AssemblyReferenceHandle handle) public AssemblyReference(MetadataFile module, AssemblyReferenceHandle handle)
{ {
if (module == null) if (module == null)
throw new ArgumentNullException(nameof(module)); throw new ArgumentNullException(nameof(module));

4
ICSharpCode.Decompiler/Metadata/CodeMappingInfo.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.Metadata
/// <summary> /// <summary>
/// The module containing the code. /// The module containing the code.
/// </summary> /// </summary>
public PEFile Module { get; } public MetadataFile Module { get; }
/// <summary> /// <summary>
/// The (parent) TypeDef containing the code. /// The (parent) TypeDef containing the code.
@ -45,7 +45,7 @@ namespace ICSharpCode.Decompiler.Metadata
/// <summary> /// <summary>
/// Creates a <see cref="CodeMappingInfo"/> instance using the given <paramref name="module"/> and <paramref name="type"/>. /// Creates a <see cref="CodeMappingInfo"/> instance using the given <paramref name="module"/> and <paramref name="type"/>.
/// </summary> /// </summary>
public CodeMappingInfo(PEFile module, TypeDefinitionHandle type) public CodeMappingInfo(MetadataFile module, TypeDefinitionHandle type)
{ {
this.Module = module; this.Module = module;
this.TypeDefinition = type; this.TypeDefinition = type;

16
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

@ -18,7 +18,6 @@
using System; using System;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -40,7 +39,7 @@ namespace ICSharpCode.Decompiler.Metadata
@"|(NuGetFallbackFolder[/\\](?<type>[^/\\]+)\\(?<version>[^/\\]+)([/\\].*)?[/\\]ref[/\\])" + @"|(NuGetFallbackFolder[/\\](?<type>[^/\\]+)\\(?<version>[^/\\]+)([/\\].*)?[/\\]ref[/\\])" +
@"|(packs[/\\](?<type>[^/\\]+)\\(?<version>[^/\\]+)\\ref([/\\].*)?[/\\])"; @"|(packs[/\\](?<type>[^/\\]+)\\(?<version>[^/\\]+)\\ref([/\\].*)?[/\\])";
public static string DetectTargetFrameworkId(this PEFile assembly) public static string DetectTargetFrameworkId(this MetadataFile assembly)
{ {
return DetectTargetFrameworkId(assembly.Metadata, assembly.FileName); return DetectTargetFrameworkId(assembly.Metadata, assembly.FileName);
} }
@ -178,17 +177,16 @@ namespace ICSharpCode.Decompiler.Metadata
return string.Empty; return string.Empty;
} }
public static bool IsReferenceAssembly(this PEFile assembly) public static bool IsReferenceAssembly(this MetadataFile assembly)
{ {
return IsReferenceAssembly(assembly.Reader, assembly.FileName); return IsReferenceAssembly(assembly.Metadata, assembly.FileName);
} }
public static bool IsReferenceAssembly(this PEReader assembly, string assemblyPath) public static bool IsReferenceAssembly(this MetadataReader metadata, string assemblyPath)
{ {
if (assembly == null) if (metadata == null)
throw new ArgumentNullException(nameof(assembly)); throw new ArgumentNullException(nameof(metadata));
var metadata = assembly.GetMetadataReader();
if (metadata.GetCustomAttributes(Handle.AssemblyDefinition).HasKnownAttribute(metadata, KnownAttribute.ReferenceAssembly)) if (metadata.GetCustomAttributes(Handle.AssemblyDefinition).HasKnownAttribute(metadata, KnownAttribute.ReferenceAssembly))
return true; return true;
@ -197,7 +195,7 @@ namespace ICSharpCode.Decompiler.Metadata
return refPathMatch.Success; return refPathMatch.Success;
} }
public static string DetectRuntimePack(this PEFile assembly) public static string DetectRuntimePack(this MetadataFile assembly)
{ {
if (assembly is null) if (assembly is null)
{ {

10
ICSharpCode.Decompiler/Metadata/EnumUnderlyingTypeResolveException.cs

@ -35,12 +35,12 @@ namespace ICSharpCode.Decompiler.Metadata
} }
[Serializable] [Serializable]
public class PEFileNotSupportedException : Exception public class MetadataFileNotSupportedException : Exception
{ {
public PEFileNotSupportedException() { } public MetadataFileNotSupportedException() { }
public PEFileNotSupportedException(string message) : base(message) { } public MetadataFileNotSupportedException(string message) : base(message) { }
public PEFileNotSupportedException(string message, Exception inner) : base(message, inner) { } public MetadataFileNotSupportedException(string message, Exception inner) : base(message, inner) { }
protected PEFileNotSupportedException( protected MetadataFileNotSupportedException(
SerializationInfo info, SerializationInfo info,
StreamingContext context) : base(info, context) { } StreamingContext context) : base(info, context) { }
} }

8
ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.Metadata
{ {
public class FindTypeDecoder : ISignatureTypeProvider<bool, Unit> public class FindTypeDecoder : ISignatureTypeProvider<bool, Unit>
{ {
readonly PEFile declaringModule; readonly MetadataFile declaringModule;
readonly MetadataModule? currentModule; readonly MetadataModule? currentModule;
readonly TypeDefinitionHandle handle; readonly TypeDefinitionHandle handle;
readonly string? typeName; readonly string? typeName;
@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.Metadata
/// Constructs a FindTypeDecoder that finds uses of a specific type-definition handle. /// Constructs a FindTypeDecoder that finds uses of a specific type-definition handle.
/// This assumes that the module we are search in is the same as the module containing the type-definiton. /// This assumes that the module we are search in is the same as the module containing the type-definiton.
/// </summary> /// </summary>
internal FindTypeDecoder(TypeDefinitionHandle handle, PEFile declaringModule) internal FindTypeDecoder(TypeDefinitionHandle handle, MetadataFile declaringModule)
{ {
this.handle = handle; this.handle = handle;
this.declaringModule = declaringModule; this.declaringModule = declaringModule;
@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.Metadata
public FindTypeDecoder(MetadataModule currentModule, ITypeDefinition type) public FindTypeDecoder(MetadataModule currentModule, ITypeDefinition type)
{ {
this.currentModule = currentModule; this.currentModule = currentModule;
this.declaringModule = type.ParentModule?.PEFile ?? throw new InvalidOperationException("Cannot use MetadataModule without PEFile as context."); this.declaringModule = type.ParentModule?.MetadataFile ?? throw new InvalidOperationException("Cannot use MetadataModule without PEFile as context.");
this.handle = (TypeDefinitionHandle)type.MetadataToken; this.handle = (TypeDefinitionHandle)type.MetadataToken;
this.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode(); this.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode();
this.typeName = type.MetadataName; this.typeName = type.MetadataName;
@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.Metadata
if (td == null) if (td == null)
return false; return false;
return td.MetadataToken == this.handle && td.ParentModule?.PEFile == declaringModule; return td.MetadataToken == this.handle && td.ParentModule?.MetadataFile == declaringModule;
} }
public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind) public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)

331
ICSharpCode.Decompiler/Metadata/MetadataFile.cs

@ -0,0 +1,331 @@
// Copyright (c) 2024 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Metadata
{
/// <summary>
/// MetadataFile is the main class the decompiler uses to represent a metadata assembly/module.
/// Every file on disk can be loaded into a standalone MetadataFile instance.
///
/// A MetadataFile can be combined with its referenced assemblies/modules to form a type system,
/// in that case the <see cref="MetadataModule"/> class is used instead.
/// </summary>
/// <remarks>
/// In addition to wrapping a <c>System.Reflection.Metadata.MetadataReader</c>, this class
/// contains a few decompiler-specific caches to allow efficiently constructing a type
/// system from multiple MetadataFiles. This allows the caches to be shared across multiple
/// decompiled type systems.
/// </remarks>
[DebuggerDisplay("{Kind}: {FileName}")]
public class MetadataFile
{
public enum MetadataFileKind
{
PortableExecutable,
ProgramDebugDatabase,
Metadata
}
public string FileName { get; }
public MetadataFileKind Kind { get; }
public MetadataReader Metadata { get; }
public virtual int MetadataOffset { get; }
public virtual bool IsEmbedded { get; }
public bool IsAssembly => Metadata.IsAssembly;
string? name;
public string Name {
get {
var value = LazyInit.VolatileRead(ref name);
if (value == null)
{
var metadata = Metadata;
value = metadata.IsAssembly
? metadata.GetString(metadata.GetAssemblyDefinition().Name)
: metadata.GetString(metadata.GetModuleDefinition().Name);
value = LazyInit.GetOrSet(ref name, value);
}
return value;
}
}
string? fullName;
public string FullName {
get {
var value = LazyInit.VolatileRead(ref fullName);
if (value == null)
{
var metadata = Metadata;
value = metadata.IsAssembly ? metadata.GetFullAssemblyName() : Name;
value = LazyInit.GetOrSet(ref fullName, value);
}
return value;
}
}
public TargetRuntime GetRuntime()
{
string version = Metadata.MetadataVersion;
if (version == null || version.Length <= 1)
return TargetRuntime.Unknown;
switch (version[1])
{
case '1':
if (version.Length <= 3)
return TargetRuntime.Unknown;
if (version[3] == 1)
return TargetRuntime.Net_1_0;
else
return TargetRuntime.Net_1_1;
case '2':
return TargetRuntime.Net_2_0;
case '4':
return TargetRuntime.Net_4_0;
default:
return TargetRuntime.Unknown;
}
}
ImmutableArray<AssemblyReference> assemblyReferences;
public ImmutableArray<AssemblyReference> AssemblyReferences {
get {
var value = assemblyReferences;
if (value.IsDefault)
{
value = Metadata.AssemblyReferences.Select(r => new AssemblyReference(this.Metadata, r)).ToImmutableArray();
assemblyReferences = value;
}
return value;
}
}
ImmutableArray<ModuleReferenceMetadata> moduleReferences;
public ImmutableArray<ModuleReferenceMetadata> ModuleReferences {
get {
var value = moduleReferences;
if (value.IsDefault)
{
value = Metadata.GetModuleReferences()
.Select(m => new ModuleReferenceMetadata(this.Metadata, m))
.ToImmutableArray();
moduleReferences = value;
}
return value;
}
}
public ImmutableArray<Resource> Resources => GetResources().ToImmutableArray();
IEnumerable<Resource> GetResources()
{
var metadata = Metadata;
foreach (var h in metadata.ManifestResources)
{
yield return new MetadataResource(this, h);
}
}
Dictionary<TopLevelTypeName, TypeDefinitionHandle>? typeLookup;
/// <summary>
/// Finds the top-level-type with the specified name.
/// </summary>
public TypeDefinitionHandle GetTypeDefinition(TopLevelTypeName typeName)
{
var lookup = LazyInit.VolatileRead(ref typeLookup);
if (lookup == null)
{
lookup = new Dictionary<TopLevelTypeName, TypeDefinitionHandle>();
foreach (var handle in Metadata.TypeDefinitions)
{
var td = Metadata.GetTypeDefinition(handle);
if (!td.GetDeclaringType().IsNil)
{
continue; // nested type
}
var nsHandle = td.Namespace;
string ns = nsHandle.IsNil ? string.Empty : Metadata.GetString(nsHandle);
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(Metadata.GetString(td.Name), out int typeParameterCount);
lookup[new TopLevelTypeName(ns, name, typeParameterCount)] = handle;
}
lookup = LazyInit.GetOrSet(ref typeLookup, lookup);
}
if (lookup.TryGetValue(typeName, out var resultHandle))
return resultHandle;
else
return default;
}
Dictionary<FullTypeName, ExportedTypeHandle>? typeForwarderLookup;
/// <summary>
/// Finds the type forwarder with the specified name.
/// </summary>
public ExportedTypeHandle GetTypeForwarder(FullTypeName typeName)
{
var lookup = LazyInit.VolatileRead(ref typeForwarderLookup);
if (lookup == null)
{
lookup = new Dictionary<FullTypeName, ExportedTypeHandle>();
foreach (var handle in Metadata.ExportedTypes)
{
var td = Metadata.GetExportedType(handle);
lookup[td.GetFullTypeName(Metadata)] = handle;
}
lookup = LazyInit.GetOrSet(ref typeForwarderLookup, lookup);
}
if (lookup.TryGetValue(typeName, out var resultHandle))
return resultHandle;
else
return default;
}
MethodSemanticsLookup? methodSemanticsLookup;
internal MethodSemanticsLookup MethodSemanticsLookup {
get {
var r = LazyInit.VolatileRead(ref methodSemanticsLookup);
if (r != null)
return r;
else
return LazyInit.GetOrSet(ref methodSemanticsLookup, new MethodSemanticsLookup(Metadata));
}
}
public MetadataFile(MetadataFileKind kind, string fileName, MetadataReaderProvider metadata, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, int metadataOffset = 0, bool isEmbedded = false)
{
this.Kind = kind;
this.FileName = fileName;
this.Metadata = metadata.GetMetadataReader(metadataOptions);
this.MetadataOffset = metadataOffset;
this.IsEmbedded = isEmbedded;
}
private protected MetadataFile(MetadataFileKind kind, string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
{
this.Kind = kind;
this.FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
_ = reader ?? throw new ArgumentNullException(nameof(reader));
if (!reader.HasMetadata)
throw new MetadataFileNotSupportedException("PE file does not contain any managed metadata.");
this.Metadata = reader.GetMetadataReader(metadataOptions);
}
public virtual MethodBodyBlock GetMethodBody(int rva)
{
throw new BadImageFormatException("This metadata file does not contain method bodies.");
}
public virtual SectionData GetSectionData(int rva)
{
throw new BadImageFormatException("This metadata file does not support sections.");
}
public virtual int GetContainingSectionIndex(int rva)
{
throw new BadImageFormatException("This metadata file does not support sections.");
}
public virtual ImmutableArray<SectionHeader> SectionHeaders => throw new BadImageFormatException("This metadata file does not support sections.");
/// <summary>
/// Gets the CLI header or null if the image does not have one.
/// </summary>
public virtual CorHeader? CorHeader => null;
public IModuleReference WithOptions(TypeSystemOptions options)
{
return new MetadataFileWithOptions(this, options);
}
private class MetadataFileWithOptions : IModuleReference
{
readonly MetadataFile peFile;
readonly TypeSystemOptions options;
public MetadataFileWithOptions(MetadataFile peFile, TypeSystemOptions options)
{
this.peFile = peFile;
this.options = options;
}
IModule IModuleReference.Resolve(ITypeResolveContext context)
{
return new MetadataModule(context.Compilation, peFile, options);
}
}
}
/// <summary>
/// Abstraction over PEMemoryBlock
/// </summary>
public readonly unsafe struct SectionData
{
public byte* Pointer { get; }
public int Length { get; }
public SectionData(PEMemoryBlock block)
{
Pointer = block.Pointer;
Length = block.Length;
}
public SectionData(byte* startPointer, int length)
{
Pointer = startPointer;
Length = length;
}
public BlobReader GetReader()
{
return new BlobReader(Pointer, Length);
}
internal BlobReader GetReader(int offset, int size)
{
return new BlobReader(Pointer + offset, size);
}
}
public struct SectionHeader
{
public string Name;
public uint VirtualSize;
public uint VirtualAddress;
public uint RawDataSize;
public uint RawDataPtr;
}
}

2
ICSharpCode.Decompiler/Metadata/MetadataGenericContext.cs

@ -43,7 +43,7 @@ namespace ICSharpCode.Decompiler.Metadata
this.declaringType = metadata.GetMethodDefinition(method).GetDeclaringType(); this.declaringType = metadata.GetMethodDefinition(method).GetDeclaringType();
} }
public MetadataGenericContext(TypeDefinitionHandle declaringType, PEFile module) public MetadataGenericContext(TypeDefinitionHandle declaringType, MetadataFile module)
{ {
this.metadata = module.Metadata; this.metadata = module.Metadata;
this.method = default; this.method = default;

260
ICSharpCode.Decompiler/Metadata/PEFile.cs

@ -19,7 +19,6 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@ -28,62 +27,11 @@ using System.Reflection.Metadata;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Metadata namespace ICSharpCode.Decompiler.Metadata
{ {
public class MetadataFile
{
public enum MetadataFileKind
{
PortableExecutable,
ProgramDebugDatabase,
Metadata
}
public string FileName { get; }
public MetadataFileKind Kind { get; }
public MetadataReader Metadata { get; }
public virtual int MetadataOffset { get; }
public virtual bool IsEmbedded { get; }
public MetadataFile(string fileName, MetadataReaderProvider metadata, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, int metadataOffset = 0, bool isEmbedded = false)
{
this.FileName = fileName;
this.Metadata = metadata.GetMetadataReader(metadataOptions);
this.MetadataOffset = metadataOffset;
this.IsEmbedded = isEmbedded;
this.Kind = isEmbedded || Path.GetExtension(fileName).Equals(".pdb", StringComparison.OrdinalIgnoreCase) ? MetadataFileKind.ProgramDebugDatabase : MetadataFileKind.Metadata;
}
private protected MetadataFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
{
this.FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
_ = reader ?? throw new ArgumentNullException(nameof(reader));
if (!reader.HasMetadata)
throw new PEFileNotSupportedException("PE file does not contain any managed metadata.");
this.Metadata = reader.GetMetadataReader(metadataOptions);
this.Kind = MetadataFileKind.PortableExecutable;
}
}
/// <summary>
/// PEFile is the main class the decompiler uses to represent a metadata assembly/module.
/// Every file on disk can be loaded into a standalone PEFile instance.
///
/// A PEFile can be combined with its referenced assemblies/modules to form a type system,
/// in that case the <see cref="MetadataModule"/> class is used instead.
/// </summary>
/// <remarks>
/// In addition to wrapping a <c>System.Reflection.Metadata.PEReader</c>, this class
/// contains a few decompiler-specific caches to allow efficiently constructing a type
/// system from multiple PEFiles. This allows the caches to be shared across multiple
/// decompiled type systems.
/// </remarks>
[DebuggerDisplay("{FileName}")] [DebuggerDisplay("{FileName}")]
public class PEFile : MetadataFile, IDisposable, TypeSystem.IModuleReference public class PEFile : MetadataFile, IDisposable, IModuleReference
{ {
public PEReader Reader { get; } public PEReader Reader { get; }
@ -98,209 +46,59 @@ namespace ICSharpCode.Decompiler.Metadata
} }
public PEFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default) public PEFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
: base(fileName, reader, metadataOptions) : base(MetadataFileKind.PortableExecutable, fileName, reader, metadataOptions)
{ {
this.Reader = reader; this.Reader = reader;
} }
public bool IsAssembly => Metadata.IsAssembly;
public override bool IsEmbedded => false; public override bool IsEmbedded => false;
public override int MetadataOffset => Reader.PEHeaders.MetadataStartOffset; public override int MetadataOffset => Reader.PEHeaders.MetadataStartOffset;
string? name;
public string Name {
get {
var value = LazyInit.VolatileRead(ref name);
if (value == null)
{
var metadata = Metadata;
value = metadata.IsAssembly
? metadata.GetString(metadata.GetAssemblyDefinition().Name)
: metadata.GetString(metadata.GetModuleDefinition().Name);
value = LazyInit.GetOrSet(ref name, value);
}
return value;
}
}
string? fullName;
public string FullName {
get {
var value = LazyInit.VolatileRead(ref fullName);
if (value == null)
{
var metadata = Metadata;
value = metadata.IsAssembly ? metadata.GetFullAssemblyName() : Name;
value = LazyInit.GetOrSet(ref fullName, value);
}
return value;
}
}
public TargetRuntime GetRuntime()
{
string version = Metadata.MetadataVersion;
if (version == null || version.Length <= 1)
return TargetRuntime.Unknown;
switch (version[1])
{
case '1':
if (version.Length <= 3)
return TargetRuntime.Unknown;
if (version[3] == 1)
return TargetRuntime.Net_1_0;
else
return TargetRuntime.Net_1_1;
case '2':
return TargetRuntime.Net_2_0;
case '4':
return TargetRuntime.Net_4_0;
default:
return TargetRuntime.Unknown;
}
}
ImmutableArray<AssemblyReference> assemblyReferences;
public ImmutableArray<AssemblyReference> AssemblyReferences {
get {
var value = assemblyReferences;
if (value.IsDefault)
{
value = Metadata.AssemblyReferences.Select(r => new AssemblyReference(this, r)).ToImmutableArray();
assemblyReferences = value;
}
return value;
}
}
ImmutableArray<ModuleReferenceMetadata> moduleReferences;
public ImmutableArray<ModuleReferenceMetadata> ModuleReferences {
get {
var value = moduleReferences;
if (value.IsDefault)
{
value = Metadata.GetModuleReferences()
.Select(m => new ModuleReferenceMetadata(this, m))
.ToImmutableArray();
moduleReferences = value;
}
return value;
}
}
public ImmutableArray<Resource> Resources => GetResources().ToImmutableArray();
IEnumerable<Resource> GetResources()
{
var metadata = Metadata;
foreach (var h in metadata.ManifestResources)
{
yield return new MetadataResource(this, h);
}
}
public void Dispose() public void Dispose()
{ {
Reader.Dispose(); Reader.Dispose();
} }
Dictionary<TopLevelTypeName, TypeDefinitionHandle>? typeLookup; IModule TypeSystem.IModuleReference.Resolve(ITypeResolveContext context)
/// <summary>
/// Finds the top-level-type with the specified name.
/// </summary>
public TypeDefinitionHandle GetTypeDefinition(TopLevelTypeName typeName)
{ {
var lookup = LazyInit.VolatileRead(ref typeLookup); return new MetadataModule(context.Compilation, this, TypeSystemOptions.Default);
if (lookup == null)
{
lookup = new Dictionary<TopLevelTypeName, TypeDefinitionHandle>();
foreach (var handle in Metadata.TypeDefinitions)
{
var td = Metadata.GetTypeDefinition(handle);
if (!td.GetDeclaringType().IsNil)
{
continue; // nested type
}
var nsHandle = td.Namespace;
string ns = nsHandle.IsNil ? string.Empty : Metadata.GetString(nsHandle);
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(Metadata.GetString(td.Name), out int typeParameterCount);
lookup[new TopLevelTypeName(ns, name, typeParameterCount)] = handle;
}
lookup = LazyInit.GetOrSet(ref typeLookup, lookup);
}
if (lookup.TryGetValue(typeName, out var resultHandle))
return resultHandle;
else
return default;
} }
Dictionary<FullTypeName, ExportedTypeHandle>? typeForwarderLookup; public override MethodBodyBlock GetMethodBody(int rva)
/// <summary>
/// Finds the type forwarder with the specified name.
/// </summary>
public ExportedTypeHandle GetTypeForwarder(FullTypeName typeName)
{ {
var lookup = LazyInit.VolatileRead(ref typeForwarderLookup); return Reader.GetMethodBody(rva);
if (lookup == null)
{
lookup = new Dictionary<FullTypeName, ExportedTypeHandle>();
foreach (var handle in Metadata.ExportedTypes)
{
var td = Metadata.GetExportedType(handle);
lookup[td.GetFullTypeName(Metadata)] = handle;
}
lookup = LazyInit.GetOrSet(ref typeForwarderLookup, lookup);
}
if (lookup.TryGetValue(typeName, out var resultHandle))
return resultHandle;
else
return default;
} }
MethodSemanticsLookup? methodSemanticsLookup; public override SectionData GetSectionData(int rva)
internal MethodSemanticsLookup MethodSemanticsLookup {
get {
var r = LazyInit.VolatileRead(ref methodSemanticsLookup);
if (r != null)
return r;
else
return LazyInit.GetOrSet(ref methodSemanticsLookup, new MethodSemanticsLookup(Metadata));
}
}
public TypeSystem.IModuleReference WithOptions(TypeSystemOptions options)
{ {
return new PEFileWithOptions(this, options); return new SectionData(Reader.GetSectionData(rva));
} }
IModule TypeSystem.IModuleReference.Resolve(ITypeResolveContext context) public override int GetContainingSectionIndex(int rva)
{ {
return new MetadataModule(context.Compilation, this, TypeSystemOptions.Default); return Reader.PEHeaders.GetContainingSectionIndex(rva);
} }
private class PEFileWithOptions : TypeSystem.IModuleReference ImmutableArray<SectionHeader> sectionHeaders;
{ public override ImmutableArray<SectionHeader> SectionHeaders {
readonly PEFile peFile; get {
readonly TypeSystemOptions options; var value = sectionHeaders;
if (value.IsDefault)
public PEFileWithOptions(PEFile peFile, TypeSystemOptions options) {
{ value = Reader.PEHeaders.SectionHeaders
this.peFile = peFile; .Select(h => new SectionHeader {
this.options = options; Name = h.Name,
} RawDataPtr = unchecked((uint)h.PointerToRawData),
RawDataSize = unchecked((uint)h.SizeOfRawData),
IModule TypeSystem.IModuleReference.Resolve(ITypeResolveContext context) VirtualAddress = unchecked((uint)h.VirtualAddress),
{ VirtualSize = unchecked((uint)h.VirtualSize)
return new MetadataModule(context.Compilation, peFile, options); }).ToImmutableArray();
sectionHeaders = value;
}
return value;
} }
} }
public override CorHeader? CorHeader => Reader.PEHeaders.CorHeader;
} }
} }

19
ICSharpCode.Decompiler/Metadata/Resource.cs

@ -23,7 +23,6 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
namespace ICSharpCode.Decompiler.Metadata namespace ICSharpCode.Decompiler.Metadata
{ {
@ -67,11 +66,11 @@ namespace ICSharpCode.Decompiler.Metadata
sealed class MetadataResource : Resource sealed class MetadataResource : Resource
{ {
public PEFile Module { get; } public MetadataFile Module { get; }
public ManifestResourceHandle Handle { get; } public ManifestResourceHandle Handle { get; }
public bool IsNil => Handle.IsNil; public bool IsNil => Handle.IsNil;
public MetadataResource(PEFile module, ManifestResourceHandle handle) public MetadataResource(MetadataFile module, ManifestResourceHandle handle)
{ {
this.Module = module ?? throw new ArgumentNullException(nameof(module)); this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle; this.Handle = handle;
@ -117,15 +116,13 @@ namespace ICSharpCode.Decompiler.Metadata
// embedded resources cannot be read from this binary. // embedded resources cannot be read from this binary.
if (ResourceType != ResourceType.Embedded) if (ResourceType != ResourceType.Embedded)
return false; return false;
// get cor header if (Module.CorHeader == null)
var headers = Module.Reader.PEHeaders;
if (headers.CorHeader == null)
return false; return false;
var resources = headers.CorHeader.ResourcesDirectory; var resources = Module.CorHeader.ResourcesDirectory;
// validate resources directory, GetSectionData throws on negative RVAs // validate resources directory, GetSectionData throws on negative RVAs
if (resources.RelativeVirtualAddress <= 0) if (resources.RelativeVirtualAddress <= 0)
return false; return false;
var sectionData = Module.Reader.GetSectionData(resources.RelativeVirtualAddress); var sectionData = Module.GetSectionData(resources.RelativeVirtualAddress);
// validate section length: we need at least 4 bytes to extract // validate section length: we need at least 4 bytes to extract
// the actual length of the resource blob. // the actual length of the resource blob.
if (sectionData.Length < 4) if (sectionData.Length < 4)
@ -144,7 +141,7 @@ namespace ICSharpCode.Decompiler.Metadata
{ {
if (!TryReadResource(out var ptr, out var length)) if (!TryReadResource(out var ptr, out var length))
return null; return null;
return new ResourceMemoryStream(Module.Reader, ptr + sizeof(int), length); return new ResourceMemoryStream(Module, ptr + sizeof(int), length);
} }
public unsafe override long? TryGetLength() public unsafe override long? TryGetLength()
@ -158,10 +155,10 @@ namespace ICSharpCode.Decompiler.Metadata
sealed unsafe class ResourceMemoryStream : UnmanagedMemoryStream sealed unsafe class ResourceMemoryStream : UnmanagedMemoryStream
{ {
#pragma warning disable IDE0052 // Remove unread private members #pragma warning disable IDE0052 // Remove unread private members
readonly PEReader peReader; readonly MetadataFile peReader;
#pragma warning restore IDE0052 // Remove unread private members #pragma warning restore IDE0052 // Remove unread private members
public ResourceMemoryStream(PEReader peReader, byte* data, long length) public ResourceMemoryStream(MetadataFile peReader, byte* data, long length)
: base(data, length, length, FileAccess.Read) : base(data, length, length, FileAccess.Read)
{ {
// Keep the PEReader alive while the stream in in use. // Keep the PEReader alive while the stream in in use.

10
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -209,13 +209,13 @@ namespace ICSharpCode.Decompiler.Metadata
} }
#if !VSADDIN #if !VSADDIN
public PEFile? Resolve(IAssemblyReference name) public MetadataFile? Resolve(IAssemblyReference name)
{ {
var file = FindAssemblyFile(name); var file = FindAssemblyFile(name);
return CreatePEFileFromFileName(file, ex => new ResolutionException(name, file, ex)); return CreatePEFileFromFileName(file, ex => new ResolutionException(name, file, ex));
} }
public PEFile? ResolveModule(PEFile mainModule, string moduleName) public MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName)
{ {
string? baseDirectory = Path.GetDirectoryName(mainModule.FileName); string? baseDirectory = Path.GetDirectoryName(mainModule.FileName);
if (baseDirectory == null) if (baseDirectory == null)
@ -224,7 +224,7 @@ namespace ICSharpCode.Decompiler.Metadata
return CreatePEFileFromFileName(moduleFileName, ex => new ResolutionException(mainModule.FileName, moduleName, moduleFileName, ex)); return CreatePEFileFromFileName(moduleFileName, ex => new ResolutionException(mainModule.FileName, moduleName, moduleFileName, ex));
} }
private PEFile? CreatePEFileFromFileName(string? fileName, Func<Exception?, Exception> makeException) private MetadataFile? CreatePEFileFromFileName(string? fileName, Func<Exception?, Exception> makeException)
{ {
if (fileName == null) if (fileName == null)
{ {
@ -251,12 +251,12 @@ namespace ICSharpCode.Decompiler.Metadata
return null; return null;
} }
public Task<PEFile?> ResolveAsync(IAssemblyReference name) public Task<MetadataFile?> ResolveAsync(IAssemblyReference name)
{ {
return Task.Run(() => Resolve(name)); return Task.Run(() => Resolve(name));
} }
public Task<PEFile?> ResolveModuleAsync(PEFile mainModule, string moduleName) public Task<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName)
{ {
return Task.Run(() => ResolveModule(mainModule, moduleName)); return Task.Run(() => ResolveModule(mainModule, moduleName));
} }

2
ICSharpCode.Decompiler/NRExtensions.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.Decompiler
internal static string GetDocumentation(this IEntity entity) internal static string GetDocumentation(this IEntity entity)
{ {
var docProvider = XmlDocLoader.LoadDocumentation(entity.ParentModule.PEFile); var docProvider = XmlDocLoader.LoadDocumentation(entity.ParentModule.MetadataFile);
if (docProvider == null) if (docProvider == null)
return null; return null;
return docProvider.GetDocumentation(entity); return docProvider.GetDocumentation(entity);

9
ICSharpCode.Decompiler/SRMExtensions.cs

@ -5,6 +5,7 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
@ -624,7 +625,7 @@ namespace ICSharpCode.Decompiler
} }
#endregion #endregion
public static unsafe BlobReader GetInitialValue(this FieldDefinition field, PEReader pefile, public static unsafe BlobReader GetInitialValue(this FieldDefinition field, MetadataFile pefile,
ICompilation typeSystem) ICompilation typeSystem)
{ {
if (!field.HasFlag(FieldAttributes.HasFieldRVA)) if (!field.HasFlag(FieldAttributes.HasFieldRVA))
@ -650,10 +651,10 @@ namespace ICSharpCode.Decompiler
public FieldValueSizeDecoder(ICompilation typeSystem = null) public FieldValueSizeDecoder(ICompilation typeSystem = null)
{ {
this.module = (MetadataModule)typeSystem?.MainModule; this.module = (MetadataModule)typeSystem?.MainModule;
if (module == null) if (module?.MetadataFile is not PEFile pefile)
this.pointerSize = IntPtr.Size; this.pointerSize = IntPtr.Size;
else else
this.pointerSize = module.PEFile.Reader.PEHeaders.PEHeader.Magic == PEMagic.PE32 ? 4 : 8; this.pointerSize = pefile.Reader.PEHeaders.PEHeader.Magic == PEMagic.PE32 ? 4 : 8;
} }
public int GetArrayType(int elementType, ArrayShape shape) => public int GetArrayType(int elementType, ArrayShape shape) =>
@ -710,7 +711,7 @@ namespace ICSharpCode.Decompiler
var typeDef = module?.ResolveType(handle, new GenericContext()).GetDefinition(); var typeDef = module?.ResolveType(handle, new GenericContext()).GetDefinition();
if (typeDef == null || typeDef.MetadataToken.IsNil) if (typeDef == null || typeDef.MetadataToken.IsNil)
return 0; return 0;
reader = typeDef.ParentModule.PEFile.Metadata; reader = typeDef.ParentModule.MetadataFile.Metadata;
var td = reader.GetTypeDefinition((TypeDefinitionHandle)typeDef.MetadataToken); var td = reader.GetTypeDefinition((TypeDefinitionHandle)typeDef.MetadataToken);
return td.GetLayout().Size; return td.GetLayout().Size;
} }

20
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -208,17 +208,17 @@ namespace ICSharpCode.Decompiler.TypeSystem
{ {
} }
public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver) public DecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver)
: this(mainModule, assemblyResolver, TypeSystemOptions.Default) : this(mainModule, assemblyResolver, TypeSystemOptions.Default)
{ {
} }
public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver, DecompilerSettings settings) public DecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
: this(mainModule, assemblyResolver, GetOptions(settings ?? throw new ArgumentNullException(nameof(settings)))) : this(mainModule, assemblyResolver, GetOptions(settings ?? throw new ArgumentNullException(nameof(settings))))
{ {
} }
public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions) public DecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)
{ {
if (mainModule == null) if (mainModule == null)
throw new ArgumentNullException(nameof(mainModule)); throw new ArgumentNullException(nameof(mainModule));
@ -232,16 +232,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
"System.Runtime.CompilerServices.Unsafe" "System.Runtime.CompilerServices.Unsafe"
}; };
private async Task InitializeAsync(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions) private async Task InitializeAsync(MetadataFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)
{ {
// Load referenced assemblies and type-forwarder references. // Load referenced assemblies and type-forwarder references.
// This is necessary to make .NET Core/PCL binaries work better. // This is necessary to make .NET Core/PCL binaries work better.
var referencedAssemblies = new List<PEFile>(); var referencedAssemblies = new List<MetadataFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference, Task<PEFile> ResolveTask)>(); var assemblyReferenceQueue = new Queue<(bool IsAssembly, MetadataFile MainModule, object Reference, Task<MetadataFile> ResolveTask)>();
var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) => var comparer = KeyComparer.Create(((bool IsAssembly, MetadataFile MainModule, object Reference) reference) =>
reference.IsAssembly ? "A:" + ((IAssemblyReference)reference.Reference).FullName : reference.IsAssembly ? "A:" + ((IAssemblyReference)reference.Reference).FullName :
"M:" + reference.Reference); "M:" + reference.Reference);
var assemblyReferencesInQueue = new HashSet<(bool IsAssembly, PEFile Parent, object Reference)>(comparer); var assemblyReferencesInQueue = new HashSet<(bool IsAssembly, MetadataFile Parent, object Reference)>(comparer);
var mainMetadata = mainModule.Metadata; var mainMetadata = mainModule.Metadata;
var tfm = mainModule.DetectTargetFrameworkId(); var tfm = mainModule.DetectTargetFrameworkId();
var (identifier, version) = UniversalAssemblyResolver.ParseTargetFramework(tfm); var (identifier, version) = UniversalAssemblyResolver.ParseTargetFramework(tfm);
@ -334,13 +334,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
} }
this.mainModule = (MetadataModule)base.MainModule; this.mainModule = (MetadataModule)base.MainModule;
void AddToQueue(bool isAssembly, PEFile mainModule, object reference) void AddToQueue(bool isAssembly, MetadataFile mainModule, object reference)
{ {
if (assemblyReferencesInQueue.Add((isAssembly, mainModule, reference))) if (assemblyReferencesInQueue.Add((isAssembly, mainModule, reference)))
{ {
// Immediately start loading the referenced module as we add the entry to the queue. // Immediately start loading the referenced module as we add the entry to the queue.
// This allows loading multiple modules in parallel. // This allows loading multiple modules in parallel.
Task<PEFile> asm; Task<MetadataFile> asm;
if (isAssembly) if (isAssembly)
{ {
asm = assemblyResolver.ResolveAsync((IAssemblyReference)reference); asm = assemblyResolver.ResolveAsync((IAssemblyReference)reference);

2
ICSharpCode.Decompiler/TypeSystem/IAssembly.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary> /// <summary>
/// Gets the underlying metadata file. May return null, if the IAssembly was not created from a PE file. /// Gets the underlying metadata file. May return null, if the IAssembly was not created from a PE file.
/// </summary> /// </summary>
PEFile? PEFile { get; } MetadataFile? MetadataFile { get; }
/// <summary> /// <summary>
/// Gets whether this assembly is the main assembly of the compilation. /// Gets whether this assembly is the main assembly of the compilation.

4
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs

@ -168,14 +168,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
if (obj is MetadataEvent ev) if (obj is MetadataEvent ev)
{ {
return handle == ev.handle && module.PEFile == ev.module.PEFile; return handle == ev.handle && module.MetadataFile == ev.module.MetadataFile;
} }
return false; return false;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return 0x7937039a ^ module.PEFile.GetHashCode() ^ handle.GetHashCode(); return 0x7937039a ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();
} }
bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) bool IMember.Equals(IMember obj, TypeVisitor typeNormalization)

4
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs

@ -299,14 +299,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
if (obj is MetadataField f) if (obj is MetadataField f)
{ {
return handle == f.handle && module.PEFile == f.module.PEFile; return handle == f.handle && module.MetadataFile == f.module.MetadataFile;
} }
return false; return false;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return 0x11dda32b ^ module.PEFile.GetHashCode() ^ handle.GetHashCode(); return 0x11dda32b ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();
} }
bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) bool IMember.Equals(IMember obj, TypeVisitor typeNormalization)

6
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.attributes = def.Attributes; this.attributes = def.Attributes;
this.symbolKind = SymbolKind.Method; this.symbolKind = SymbolKind.Method;
var (accessorOwner, semanticsAttribute) = module.PEFile.MethodSemanticsLookup.GetSemantics(handle); var (accessorOwner, semanticsAttribute) = module.MetadataFile.MethodSemanticsLookup.GetSemantics(handle);
const MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig); const MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig);
this.typeParameters = MetadataTypeParameter.Create(module, this, def.GetGenericParameters()); this.typeParameters = MetadataTypeParameter.Create(module, this, def.GetGenericParameters());
if (semanticsAttribute != 0 && !accessorOwner.IsNil if (semanticsAttribute != 0 && !accessorOwner.IsNil
@ -606,14 +606,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
if (obj is MetadataMethod m) if (obj is MetadataMethod m)
{ {
return handle == m.handle && module.PEFile == m.module.PEFile; return handle == m.handle && module.MetadataFile == m.module.MetadataFile;
} }
return false; return false;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return 0x5a00d671 ^ module.PEFile.GetHashCode() ^ handle.GetHashCode(); return 0x5a00d671 ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();
} }
bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) bool IMember.Equals(IMember obj, TypeVisitor typeNormalization)

6
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs

@ -267,7 +267,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
// "protected internal" (ProtectedOrInternal) accessibility is "reduced" // "protected internal" (ProtectedOrInternal) accessibility is "reduced"
// to "protected" accessibility across assembly boundaries. // to "protected" accessibility across assembly boundaries.
if (baseMember.Accessibility == Accessibility.ProtectedOrInternal if (baseMember.Accessibility == Accessibility.ProtectedOrInternal
&& this.ParentModule?.PEFile != baseMember.ParentModule?.PEFile) && this.ParentModule?.MetadataFile != baseMember.ParentModule?.MetadataFile)
{ {
return Accessibility.Protected; return Accessibility.Protected;
} }
@ -302,14 +302,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
if (obj is MetadataProperty p) if (obj is MetadataProperty p)
{ {
return handle == p.handle && module.PEFile == p.module.PEFile; return handle == p.handle && module.MetadataFile == p.module.MetadataFile;
} }
return false; return false;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return 0x32b6a76c ^ module.PEFile.GetHashCode() ^ handle.GetHashCode(); return 0x32b6a76c ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();
} }
bool IMember.Equals(IMember obj, TypeVisitor typeNormalization) bool IMember.Equals(IMember obj, TypeVisitor typeNormalization)

6
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -258,7 +258,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var metadata = module.metadata; var metadata = module.metadata;
var methodsCollection = metadata.GetTypeDefinition(handle).GetMethods(); var methodsCollection = metadata.GetTypeDefinition(handle).GetMethods();
var methodsList = new List<IMethod>(methodsCollection.Count); var methodsList = new List<IMethod>(methodsCollection.Count);
var methodSemantics = module.PEFile.MethodSemanticsLookup; var methodSemantics = module.MetadataFile.MethodSemanticsLookup;
bool hasDefaultCtor = false; bool hasDefaultCtor = false;
foreach (MethodDefinitionHandle h in methodsCollection) foreach (MethodDefinitionHandle h in methodsCollection)
{ {
@ -553,14 +553,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{ {
if (obj is MetadataTypeDefinition td) if (obj is MetadataTypeDefinition td)
{ {
return handle == td.handle && module.PEFile == td.module.PEFile; return handle == td.handle && module.MetadataFile == td.module.MetadataFile;
} }
return false; return false;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return 0x2e0520f2 ^ module.PEFile.GetHashCode() ^ handle.GetHashCode(); return 0x2e0520f2 ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();
} }
bool IEquatable<IType>.Equals(IType other) bool IEquatable<IType>.Equals(IType other)

4
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs

@ -248,12 +248,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override int GetHashCode() public override int GetHashCode()
{ {
return 0x51fc5b83 ^ module.PEFile.GetHashCode() ^ handle.GetHashCode(); return 0x51fc5b83 ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();
} }
public override bool Equals(IType other) public override bool Equals(IType other)
{ {
return other is MetadataTypeParameter tp && handle == tp.handle && module.PEFile == tp.module.PEFile; return other is MetadataTypeParameter tp && handle == tp.handle && module.MetadataFile == tp.module.MetadataFile;
} }
public override string ToString() public override string ToString()

2
ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs

@ -62,7 +62,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
string ISymbol.Name => "corlib"; string ISymbol.Name => "corlib";
SymbolKind ISymbol.SymbolKind => SymbolKind.Module; SymbolKind ISymbol.SymbolKind => SymbolKind.Module;
Metadata.PEFile IModule.PEFile => null; Metadata.MetadataFile IModule.MetadataFile => null;
INamespace IModule.RootNamespace => rootNamespace; INamespace IModule.RootNamespace => rootNamespace;
public IEnumerable<ITypeDefinition> TopLevelTypeDefinitions => typeDefinitions.Where(td => td != null); public IEnumerable<ITypeDefinition> TopLevelTypeDefinitions => typeDefinitions.Where(td => td != null);

12
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

@ -51,10 +51,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
readonly MetadataEvent[] eventDefs; readonly MetadataEvent[] eventDefs;
readonly IModule[] referencedAssemblies; readonly IModule[] referencedAssemblies;
internal MetadataModule(ICompilation compilation, Metadata.PEFile peFile, TypeSystemOptions options) internal MetadataModule(ICompilation compilation, MetadataFile peFile, TypeSystemOptions options)
{ {
this.Compilation = compilation; this.Compilation = compilation;
this.PEFile = peFile; this.MetadataFile = peFile;
this.metadata = peFile.Metadata; this.metadata = peFile.Metadata;
this.options = options; this.options = options;
this.TypeProvider = new TypeProvider(this); this.TypeProvider = new TypeProvider(this);
@ -112,8 +112,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
public TypeSystemOptions TypeSystemOptions => options; public TypeSystemOptions TypeSystemOptions => options;
#region IAssembly interface #region IModule interface
public PEFile PEFile { get; } public MetadataFile MetadataFile { get; }
public bool IsMainModule => this == Compilation.MainModule; public bool IsMainModule => this == Compilation.MainModule;
@ -129,10 +129,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
public ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName) public ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName)
{ {
var typeDefHandle = PEFile.GetTypeDefinition(topLevelTypeName); var typeDefHandle = MetadataFile.GetTypeDefinition(topLevelTypeName);
if (typeDefHandle.IsNil) if (typeDefHandle.IsNil)
{ {
var forwarderHandle = PEFile.GetTypeForwarder(topLevelTypeName); var forwarderHandle = MetadataFile.GetTypeForwarder(topLevelTypeName);
if (!forwarderHandle.IsNil) if (!forwarderHandle.IsNil)
{ {
var forwarder = metadata.GetExportedType(forwarderHandle); var forwarder = metadata.GetExportedType(forwarderHandle);

4
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -699,14 +699,14 @@ namespace ICSharpCode.Decompiler.TypeSystem
public static bool IsDirectImportOf(this ITypeDefinition type, IModule module) public static bool IsDirectImportOf(this ITypeDefinition type, IModule module)
{ {
var moduleReference = type.ParentModule; var moduleReference = type.ParentModule;
foreach (var asmRef in module.PEFile.AssemblyReferences) foreach (var asmRef in module.MetadataFile.AssemblyReferences)
{ {
if (asmRef.FullName == moduleReference.FullAssemblyName) if (asmRef.FullName == moduleReference.FullAssemblyName)
return true; return true;
if (asmRef.Name == "netstandard" && asmRef.GetPublicKeyToken() != null) if (asmRef.Name == "netstandard" && asmRef.GetPublicKeyToken() != null)
{ {
var referencedModule = module.Compilation.FindModuleByReference(asmRef); var referencedModule = module.Compilation.FindModuleByReference(asmRef);
if (referencedModule != null && !referencedModule.PEFile.GetTypeForwarder(type.FullTypeName).IsNil) if (referencedModule != null && !referencedModule.MetadataFile.GetTypeForwarder(type.FullTypeName).IsNil)
return true; return true;
} }
} }

2
ICSharpCode.ILSpyX/Abstractions/ILanguage.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.ILSpyX.Abstractions
public interface ILanguage public interface ILanguage
{ {
bool ShowMember(IEntity member); bool ShowMember(IEntity member);
string GetEntityName(PEFile module, System.Reflection.Metadata.EntityHandle handle, bool fullName, bool omitGenerics); string GetEntityName(MetadataFile module, System.Reflection.Metadata.EntityHandle handle, bool fullName, bool omitGenerics);
string GetTooltip(IEntity entity); string GetTooltip(IEntity entity);
string TypeToString(IType type, bool includeNamespace); string TypeToString(IType type, bool includeNamespace);

2
ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpyX.Abstractions
public interface ITreeNodeFactory public interface ITreeNodeFactory
{ {
ITreeNode CreateResourcesList(PEFile module); ITreeNode CreateResourcesList(MetadataFile module);
ITreeNode Create(Resource resource); ITreeNode Create(Resource resource);
} }
} }

28
ICSharpCode.ILSpyX/AssemblyListSnapshot.cs

@ -33,9 +33,9 @@ namespace ICSharpCode.ILSpyX
class AssemblyListSnapshot class AssemblyListSnapshot
{ {
readonly ImmutableArray<LoadedAssembly> assemblies; readonly ImmutableArray<LoadedAssembly> assemblies;
Dictionary<string, PEFile>? asmLookupByFullName; Dictionary<string, MetadataFile>? asmLookupByFullName;
Dictionary<string, PEFile>? asmLookupByShortName; Dictionary<string, MetadataFile>? asmLookupByShortName;
Dictionary<string, List<(PEFile module, Version version)>>? asmLookupByShortNameGrouped; Dictionary<string, List<(MetadataFile module, Version version)>>? asmLookupByShortNameGrouped;
public ImmutableArray<LoadedAssembly> Assemblies => assemblies; public ImmutableArray<LoadedAssembly> Assemblies => assemblies;
public AssemblyListSnapshot(ImmutableArray<LoadedAssembly> assemblies) public AssemblyListSnapshot(ImmutableArray<LoadedAssembly> assemblies)
@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpyX
this.assemblies = assemblies; this.assemblies = assemblies;
} }
public async Task<PEFile?> TryGetModuleAsync(IAssemblyReference reference, string tfm) public async Task<MetadataFile?> TryGetModuleAsync(IAssemblyReference reference, string tfm)
{ {
bool isWinRT = reference.IsWindowsRuntime; bool isWinRT = reference.IsWindowsRuntime;
if (tfm.StartsWith(".NETFramework,Version=v4.", StringComparison.Ordinal)) if (tfm.StartsWith(".NETFramework,Version=v4.", StringComparison.Ordinal))
@ -57,12 +57,12 @@ namespace ICSharpCode.ILSpyX
lookup = await CreateLoadedAssemblyLookupAsync(shortNames: isWinRT).ConfigureAwait(false); lookup = await CreateLoadedAssemblyLookupAsync(shortNames: isWinRT).ConfigureAwait(false);
lookup = LazyInit.GetOrSet(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName, lookup); lookup = LazyInit.GetOrSet(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName, lookup);
} }
if (lookup.TryGetValue(key, out PEFile? module)) if (lookup.TryGetValue(key, out MetadataFile? module))
return module; return module;
return null; return null;
} }
public async Task<PEFile?> TryGetSimilarModuleAsync(IAssemblyReference reference) public async Task<MetadataFile?> TryGetSimilarModuleAsync(IAssemblyReference reference)
{ {
var lookup = LazyInit.VolatileRead(ref asmLookupByShortNameGrouped); var lookup = LazyInit.VolatileRead(ref asmLookupByShortNameGrouped);
if (lookup == null) if (lookup == null)
@ -76,14 +76,14 @@ namespace ICSharpCode.ILSpyX
return candidates.FirstOrDefault(c => c.version >= reference.Version).module ?? candidates.Last().module; return candidates.FirstOrDefault(c => c.version >= reference.Version).module ?? candidates.Last().module;
} }
private async Task<Dictionary<string, PEFile>> CreateLoadedAssemblyLookupAsync(bool shortNames) private async Task<Dictionary<string, MetadataFile>> CreateLoadedAssemblyLookupAsync(bool shortNames)
{ {
var result = new Dictionary<string, PEFile>(StringComparer.OrdinalIgnoreCase); var result = new Dictionary<string, MetadataFile>(StringComparer.OrdinalIgnoreCase);
foreach (LoadedAssembly loaded in assemblies) foreach (LoadedAssembly loaded in assemblies)
{ {
try try
{ {
var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false); var module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);
if (module == null) if (module == null)
continue; continue;
var reader = module.Metadata; var reader = module.Metadata;
@ -109,15 +109,15 @@ namespace ICSharpCode.ILSpyX
return result; return result;
} }
private async Task<Dictionary<string, List<(PEFile module, Version version)>>> CreateLoadedAssemblyShortNameGroupLookupAsync() private async Task<Dictionary<string, List<(MetadataFile module, Version version)>>> CreateLoadedAssemblyShortNameGroupLookupAsync()
{ {
var result = new Dictionary<string, List<(PEFile module, Version version)>>(StringComparer.OrdinalIgnoreCase); var result = new Dictionary<string, List<(MetadataFile module, Version version)>>(StringComparer.OrdinalIgnoreCase);
foreach (LoadedAssembly loaded in assemblies) foreach (LoadedAssembly loaded in assemblies)
{ {
try try
{ {
var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false); var module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);
var reader = module?.Metadata; var reader = module?.Metadata;
if (reader == null || !reader.IsAssembly) if (reader == null || !reader.IsAssembly)
continue; continue;
@ -128,7 +128,7 @@ namespace ICSharpCode.ILSpyX
if (!result.TryGetValue(asmDefName, out var existing)) if (!result.TryGetValue(asmDefName, out var existing))
{ {
existing = new List<(PEFile module, Version version)>(); existing = new List<(MetadataFile module, Version version)>();
result.Add(asmDefName, existing); result.Add(asmDefName, existing);
existing.Add(line); existing.Add(line);
continue; continue;
@ -170,7 +170,7 @@ namespace ICSharpCode.ILSpyX
{ {
AddDescendants(result.Package.RootFolder); AddDescendants(result.Package.RootFolder);
} }
else if (result.PEFile != null) else if (result.MetadataFile != null)
{ {
results.Add(asm); results.Add(asm);
} }

64
ICSharpCode.ILSpyX/LoadedAssembly.cs

@ -35,6 +35,9 @@ using ICSharpCode.ILSpyX.PdbProvider;
using K4os.Compression.LZ4; using K4os.Compression.LZ4;
using static ICSharpCode.Decompiler.Metadata.MetadataFile;
#nullable enable #nullable enable
namespace ICSharpCode.ILSpyX namespace ICSharpCode.ILSpyX
@ -133,7 +136,7 @@ namespace ICSharpCode.ILSpyX
var value = LazyInit.VolatileRead(ref targetFrameworkId); var value = LazyInit.VolatileRead(ref targetFrameworkId);
if (value == null) if (value == null)
{ {
var assembly = await GetPEFileAsync().ConfigureAwait(false); var assembly = await GetMetadataFileAsync().ConfigureAwait(false);
value = assembly.DetectTargetFrameworkId() ?? string.Empty; value = assembly.DetectTargetFrameworkId() ?? string.Empty;
value = LazyInit.GetOrSet(ref targetFrameworkId, value); value = LazyInit.GetOrSet(ref targetFrameworkId, value);
} }
@ -148,7 +151,7 @@ namespace ICSharpCode.ILSpyX
var value = LazyInit.VolatileRead(ref runtimePack); var value = LazyInit.VolatileRead(ref runtimePack);
if (value == null) if (value == null)
{ {
var assembly = await GetPEFileAsync().ConfigureAwait(false); var assembly = await GetMetadataFileAsync().ConfigureAwait(false);
value = assembly.DetectRuntimePack() ?? string.Empty; value = assembly.DetectRuntimePack() ?? string.Empty;
value = LazyInit.GetOrSet(ref runtimePack, value); value = LazyInit.GetOrSet(ref runtimePack, value);
} }
@ -169,13 +172,13 @@ namespace ICSharpCode.ILSpyX
} }
/// <summary> /// <summary>
/// Gets the <see cref="PEFile"/>. /// Gets the <see cref="MetadataFile"/>.
/// </summary> /// </summary>
public async Task<PEFile> GetPEFileAsync() public async Task<MetadataFile> GetMetadataFileAsync()
{ {
var loadResult = await loadingTask.ConfigureAwait(false); var loadResult = await loadingTask.ConfigureAwait(false);
if (loadResult.PEFile != null) if (loadResult.MetadataFile != null)
return loadResult.PEFile; return loadResult.MetadataFile;
else else
throw loadResult.FileLoadException!; throw loadResult.FileLoadException!;
} }
@ -184,12 +187,12 @@ namespace ICSharpCode.ILSpyX
/// Gets the <see cref="PEFile"/>. /// Gets the <see cref="PEFile"/>.
/// Returns null in case of load errors. /// Returns null in case of load errors.
/// </summary> /// </summary>
public PEFile? GetPEFileOrNull() public MetadataFile? GetMetadataFileOrNull()
{ {
try try
{ {
var loadResult = loadingTask.GetAwaiter().GetResult(); var loadResult = loadingTask.GetAwaiter().GetResult();
return loadResult.PEFile; return loadResult.MetadataFile;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -199,15 +202,15 @@ namespace ICSharpCode.ILSpyX
} }
/// <summary> /// <summary>
/// Gets the <see cref="PEFile"/>. /// Gets the <see cref="MetadataFile"/>.
/// Returns null in case of load errors. /// Returns null in case of load errors.
/// </summary> /// </summary>
public async Task<PEFile?> GetPEFileOrNullAsync() public async Task<MetadataFile?> GetMetadataFileOrNullAsync()
{ {
try try
{ {
var loadResult = await loadingTask.ConfigureAwait(false); var loadResult = await loadingTask.ConfigureAwait(false);
return loadResult.PEFile; return loadResult.MetadataFile;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -228,7 +231,7 @@ namespace ICSharpCode.ILSpyX
public ICompilation? GetTypeSystemOrNull() public ICompilation? GetTypeSystemOrNull()
{ {
return LazyInitializer.EnsureInitialized(ref this.typeSystem, () => { return LazyInitializer.EnsureInitialized(ref this.typeSystem, () => {
var module = GetPEFileOrNull(); var module = GetMetadataFileOrNull();
if (module == null) if (module == null)
return null!; return null!;
return new SimpleCompilation( return new SimpleCompilation(
@ -247,7 +250,7 @@ namespace ICSharpCode.ILSpyX
{ {
if (typeSystemWithOptions != null && options == currentTypeSystemOptions) if (typeSystemWithOptions != null && options == currentTypeSystemOptions)
return typeSystemWithOptions; return typeSystemWithOptions;
var module = GetPEFileOrNull(); var module = GetMetadataFileOrNull();
if (module == null) if (module == null)
return null; return null;
currentTypeSystemOptions = options; currentTypeSystemOptions = options;
@ -312,7 +315,7 @@ namespace ICSharpCode.ILSpyX
/// </summary> /// </summary>
public bool IsLoadedAsValidAssembly { public bool IsLoadedAsValidAssembly {
get { get {
return loadingTask.Status == TaskStatus.RanToCompletion && loadingTask.Result.PEFile != null; return loadingTask.Status == TaskStatus.RanToCompletion && loadingTask.Result.MetadataFile != null;
} }
} }
@ -356,7 +359,7 @@ namespace ICSharpCode.ILSpyX
return LoadAssembly(fileStream, PEStreamOptions.PrefetchEntireImage, applyWinRTProjections); return LoadAssembly(fileStream, PEStreamOptions.PrefetchEntireImage, applyWinRTProjections);
} }
} }
catch (PEFileNotSupportedException ex) catch (MetadataFileNotSupportedException ex)
{ {
loadAssemblyException = ex; loadAssemblyException = ex;
} }
@ -396,8 +399,9 @@ namespace ICSharpCode.ILSpyX
{ {
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{ {
var kind = Path.GetExtension(fileName).Equals(".pdb", StringComparison.OrdinalIgnoreCase) ? MetadataFileKind.ProgramDebugDatabase : MetadataFileKind.Metadata;
var metadata = MetadataReaderProvider.FromMetadataStream(fileStream, MetadataStreamOptions.PrefetchMetadata); var metadata = MetadataReaderProvider.FromMetadataStream(fileStream, MetadataStreamOptions.PrefetchMetadata);
var metadataFile = new MetadataFile(fileName, metadata); var metadataFile = new MetadataFile(kind, fileName, metadata);
lock (loadedAssemblies) lock (loadedAssemblies)
{ {
loadedAssemblies.Add(metadataFile, this); loadedAssemblies.Add(metadataFile, this);
@ -463,8 +467,12 @@ namespace ICSharpCode.ILSpyX
} }
} }
IDebugInfoProvider? LoadDebugInfo(PEFile module) IDebugInfoProvider? LoadDebugInfo(PEFile? module)
{ {
if (module == null)
{
return null;
}
if (useDebugSymbols) if (useDebugSymbols)
{ {
try try
@ -489,8 +497,8 @@ namespace ICSharpCode.ILSpyX
public async Task<IDebugInfoProvider?> LoadDebugInfo(string fileName) public async Task<IDebugInfoProvider?> LoadDebugInfo(string fileName)
{ {
this.PdbFileName = fileName; this.PdbFileName = fileName;
var assembly = await GetPEFileAsync().ConfigureAwait(false); var assembly = await GetMetadataFileAsync().ConfigureAwait(false);
debugInfoProvider = await Task.Run(() => LoadDebugInfo(assembly)); debugInfoProvider = await Task.Run(() => LoadDebugInfo(assembly as PEFile));
return debugInfoProvider; return debugInfoProvider;
} }
@ -525,7 +533,7 @@ namespace ICSharpCode.ILSpyX
this.referenceLoadInfo = parent.LoadedAssemblyReferencesInfo; this.referenceLoadInfo = parent.LoadedAssemblyReferencesInfo;
} }
public PEFile? Resolve(IAssemblyReference reference) public MetadataFile? Resolve(IAssemblyReference reference)
{ {
return ResolveAsync(reference).GetAwaiter().GetResult(); return ResolveAsync(reference).GetAwaiter().GetResult();
} }
@ -542,9 +550,9 @@ namespace ICSharpCode.ILSpyX
/// 8) search C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /// 8) search C:\Windows\Microsoft.NET\Framework64\v4.0.30319
/// 9) try to find match by asm name (no tfm/version) in loaded assemblies /// 9) try to find match by asm name (no tfm/version) in loaded assemblies
/// </summary> /// </summary>
public async Task<PEFile?> ResolveAsync(IAssemblyReference reference) public async Task<MetadataFile?> ResolveAsync(IAssemblyReference reference)
{ {
PEFile? module; MetadataFile? module;
// 0) if we're inside a package, look for filename.dll in parent directories // 0) if we're inside a package, look for filename.dll in parent directories
if (providedAssemblyResolver != null) if (providedAssemblyResolver != null)
{ {
@ -580,7 +588,7 @@ namespace ICSharpCode.ILSpyX
if (asm != null) if (asm != null)
{ {
referenceLoadInfo.AddMessage(reference.FullName, MessageKind.Info, "Success - Loading from: " + file); referenceLoadInfo.AddMessage(reference.FullName, MessageKind.Info, "Success - Loading from: " + file);
return await asm.GetPEFileOrNullAsync().ConfigureAwait(false); return await asm.GetMetadataFileOrNullAsync().ConfigureAwait(false);
} }
return null; return null;
} }
@ -600,12 +608,12 @@ namespace ICSharpCode.ILSpyX
} }
} }
public PEFile? ResolveModule(PEFile mainModule, string moduleName) public MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName)
{ {
return ResolveModuleAsync(mainModule, moduleName).GetAwaiter().GetResult(); return ResolveModuleAsync(mainModule, moduleName).GetAwaiter().GetResult();
} }
public async Task<PEFile?> ResolveModuleAsync(PEFile mainModule, string moduleName) public async Task<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName)
{ {
if (providedAssemblyResolver != null) if (providedAssemblyResolver != null)
{ {
@ -632,7 +640,7 @@ namespace ICSharpCode.ILSpyX
} }
if (asm != null) if (asm != null)
{ {
return await asm.GetPEFileOrNullAsync().ConfigureAwait(false); return await asm.GetMetadataFileOrNullAsync().ConfigureAwait(false);
} }
} }
} }
@ -640,7 +648,7 @@ namespace ICSharpCode.ILSpyX
// Module does not exist on disk, look for one with a matching name in the assemblylist: // Module does not exist on disk, look for one with a matching name in the assemblylist:
foreach (LoadedAssembly loaded in alreadyLoadedAssemblies.Assemblies) foreach (LoadedAssembly loaded in alreadyLoadedAssemblies.Assemblies)
{ {
var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false); var module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);
var reader = module?.Metadata; var reader = module?.Metadata;
if (reader == null || reader.IsAssembly) if (reader == null || reader.IsAssembly)
continue; continue;
@ -694,7 +702,7 @@ namespace ICSharpCode.ILSpyX
/// </summary> /// </summary>
public IDebugInfoProvider? GetDebugInfoOrNull() public IDebugInfoProvider? GetDebugInfoOrNull()
{ {
if (GetPEFileOrNull() == null) if (GetMetadataFileOrNull() == null)
return null; return null;
return debugInfoProvider; return debugInfoProvider;
} }

10
ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs

@ -27,27 +27,27 @@ namespace ICSharpCode.ILSpyX
return Mono.Cecil.ModuleDefinition.ReadModule(new UnmanagedMemoryStream(image.Pointer, image.Length)); return Mono.Cecil.ModuleDefinition.ReadModule(new UnmanagedMemoryStream(image.Pointer, image.Length));
} }
public static IAssemblyResolver GetAssemblyResolver(this PEFile file, bool loadOnDemand = true) public static IAssemblyResolver GetAssemblyResolver(this MetadataFile file, bool loadOnDemand = true)
{ {
return GetLoadedAssembly(file).GetAssemblyResolver(loadOnDemand); return GetLoadedAssembly(file).GetAssemblyResolver(loadOnDemand);
} }
internal static IAssemblyResolver GetAssemblyResolver(this PEFile file, AssemblyListSnapshot snapshot, bool loadOnDemand = true) internal static IAssemblyResolver GetAssemblyResolver(this MetadataFile file, AssemblyListSnapshot snapshot, bool loadOnDemand = true)
{ {
return GetLoadedAssembly(file).GetAssemblyResolver(snapshot, loadOnDemand); return GetLoadedAssembly(file).GetAssemblyResolver(snapshot, loadOnDemand);
} }
public static IDebugInfoProvider? GetDebugInfoOrNull(this PEFile file) public static IDebugInfoProvider? GetDebugInfoOrNull(this MetadataFile file)
{ {
return GetLoadedAssembly(file).GetDebugInfoOrNull(); return GetLoadedAssembly(file).GetDebugInfoOrNull();
} }
public static ICompilation? GetTypeSystemOrNull(this PEFile file) public static ICompilation? GetTypeSystemOrNull(this MetadataFile file)
{ {
return GetLoadedAssembly(file).GetTypeSystemOrNull(); return GetLoadedAssembly(file).GetTypeSystemOrNull();
} }
public static ICompilation? GetTypeSystemWithDecompilerSettingsOrNull(this PEFile file, DecompilerSettings settings) public static ICompilation? GetTypeSystemWithDecompilerSettingsOrNull(this MetadataFile file, DecompilerSettings settings)
{ {
return GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settings)); return GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settings));
} }

20
ICSharpCode.ILSpyX/LoadedPackage.cs

@ -273,52 +273,52 @@ namespace ICSharpCode.ILSpyX
public List<PackageFolder> Folders { get; } = new List<PackageFolder>(); public List<PackageFolder> Folders { get; } = new List<PackageFolder>();
public List<PackageEntry> Entries { get; } = new List<PackageEntry>(); public List<PackageEntry> Entries { get; } = new List<PackageEntry>();
public PEFile? Resolve(IAssemblyReference reference) public MetadataFile? Resolve(IAssemblyReference reference)
{ {
var asm = ResolveFileName(reference.Name + ".dll"); var asm = ResolveFileName(reference.Name + ".dll");
if (asm != null) if (asm != null)
{ {
return asm.GetPEFileOrNull(); return asm.GetMetadataFileOrNull();
} }
return parent?.Resolve(reference); return parent?.Resolve(reference);
} }
public Task<PEFile?> ResolveAsync(IAssemblyReference reference) public Task<MetadataFile?> ResolveAsync(IAssemblyReference reference)
{ {
var asm = ResolveFileName(reference.Name + ".dll"); var asm = ResolveFileName(reference.Name + ".dll");
if (asm != null) if (asm != null)
{ {
return asm.GetPEFileOrNullAsync(); return asm.GetMetadataFileOrNullAsync();
} }
if (parent != null) if (parent != null)
{ {
return parent.ResolveAsync(reference); return parent.ResolveAsync(reference);
} }
return Task.FromResult<PEFile?>(null); return Task.FromResult<MetadataFile?>(null);
} }
public PEFile? ResolveModule(PEFile mainModule, string moduleName) public MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName)
{ {
var asm = ResolveFileName(moduleName + ".dll"); var asm = ResolveFileName(moduleName + ".dll");
if (asm != null) if (asm != null)
{ {
return asm.GetPEFileOrNull(); return asm.GetMetadataFileOrNull();
} }
return parent?.ResolveModule(mainModule, moduleName); return parent?.ResolveModule(mainModule, moduleName);
} }
public Task<PEFile?> ResolveModuleAsync(PEFile mainModule, string moduleName) public Task<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName)
{ {
var asm = ResolveFileName(moduleName + ".dll"); var asm = ResolveFileName(moduleName + ".dll");
if (asm != null) if (asm != null)
{ {
return asm.GetPEFileOrNullAsync(); return asm.GetMetadataFileOrNullAsync();
} }
if (parent != null) if (parent != null)
{ {
return parent.ResolveModuleAsync(mainModule, moduleName); return parent.ResolveModuleAsync(mainModule, moduleName);
} }
return Task.FromResult<PEFile?>(null); return Task.FromResult<MetadataFile?>(null);
} }
readonly Dictionary<string, LoadedAssembly?> assemblies = new Dictionary<string, LoadedAssembly?>(StringComparer.OrdinalIgnoreCase); readonly Dictionary<string, LoadedAssembly?> assemblies = new Dictionary<string, LoadedAssembly?>(StringComparer.OrdinalIgnoreCase);

5
ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs

@ -26,6 +26,8 @@ using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using static ICSharpCode.Decompiler.Metadata.MetadataFile;
#nullable enable #nullable enable
namespace ICSharpCode.ILSpyX.PdbProvider namespace ICSharpCode.ILSpyX.PdbProvider
@ -240,7 +242,8 @@ namespace ICSharpCode.ILSpyX.PdbProvider
public MetadataFile ToMetadataFile() public MetadataFile ToMetadataFile()
{ {
return new MetadataFile(SourceFileName, provider, options, 0, IsEmbedded); var kind = IsEmbedded || Path.GetExtension(SourceFileName).Equals(".pdb", StringComparison.OrdinalIgnoreCase) ? MetadataFileKind.ProgramDebugDatabase : MetadataFileKind.Metadata;
return new MetadataFile(kind, SourceFileName, provider, options, 0, IsEmbedded);
} }
} }
} }

4
ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs

@ -67,8 +67,8 @@ namespace ICSharpCode.ILSpyX.Search
{ {
if (searchRequest.InAssembly != null) if (searchRequest.InAssembly != null)
{ {
if (entity.ParentModule?.PEFile == null || if (entity.ParentModule?.MetadataFile == null ||
!(Path.GetFileName(entity.ParentModule.PEFile.FileName).Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase) !(Path.GetFileName(entity.ParentModule.MetadataFile.FileName).Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)
|| entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase))) || entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)))
{ {
return false; return false;

2
ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.ILSpyX.Search
this.omitGenerics = request.OmitGenerics; this.omitGenerics = request.OmitGenerics;
} }
public abstract void Search(PEFile module, CancellationToken cancellationToken); public abstract void Search(MetadataFile module, CancellationToken cancellationToken);
protected virtual bool IsMatch(string name) protected virtual bool IsMatch(string name)
{ {

7
ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs

@ -15,7 +15,6 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
@ -35,7 +34,7 @@ namespace ICSharpCode.ILSpyX.Search
this.searchKind = searchKind; this.searchKind = searchKind;
} }
public override void Search(PEFile module, CancellationToken cancellationToken) public override void Search(MetadataFile module, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
@ -61,7 +60,7 @@ namespace ICSharpCode.ILSpyX.Search
OnFoundResult(module); OnFoundResult(module);
} }
string? GetNameToMatch(PEFile module, AssemblySearchKind kind) string? GetNameToMatch(MetadataFile module, AssemblySearchKind kind)
{ {
switch (kind) switch (kind)
{ {
@ -98,7 +97,7 @@ namespace ICSharpCode.ILSpyX.Search
return null; return null;
} }
void OnFoundResult(PEFile module) void OnFoundResult(MetadataFile module)
{ {
OnFoundResult(searchRequest.SearchResultFactory.Create(module)); OnFoundResult(searchRequest.SearchResultFactory.Create(module));
} }

8
ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs

@ -28,8 +28,6 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpyX.Abstractions; using ICSharpCode.ILSpyX.Abstractions;
using static System.Reflection.Metadata.PEReaderExtensions;
using ILOpCode = System.Reflection.Metadata.ILOpCode; using ILOpCode = System.Reflection.Metadata.ILOpCode;
namespace ICSharpCode.ILSpyX.Search namespace ICSharpCode.ILSpyX.Search
@ -78,7 +76,7 @@ namespace ICSharpCode.ILSpyX.Search
// Note: if searchTermLiteralType remains TypeCode.Empty, we'll do a substring search via base.IsMatch // Note: if searchTermLiteralType remains TypeCode.Empty, we'll do a substring search via base.IsMatch
} }
public override void Search(PEFile module, CancellationToken cancellationToken) public override void Search(MetadataFile module, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var metadata = module.Metadata; var metadata = module.Metadata;
@ -143,9 +141,9 @@ namespace ICSharpCode.ILSpyX.Search
} }
} }
bool MethodIsLiteralMatch(PEFile module, MethodDefinition methodDefinition) bool MethodIsLiteralMatch(MetadataFile module, MethodDefinition methodDefinition)
{ {
var blob = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress).GetILReader(); var blob = module.GetMethodBody(methodDefinition.RelativeVirtualAddress).GetILReader();
if (searchTermLiteralType == TypeCode.Int64) if (searchTermLiteralType == TypeCode.Int64)
{ {
Debug.Assert(searchTermLiteralValue != null); Debug.Assert(searchTermLiteralValue != null);

3
ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs

@ -15,7 +15,6 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading; using System.Threading;
@ -36,7 +35,7 @@ namespace ICSharpCode.ILSpyX.Search
this.searchKind = searchKind; this.searchKind = searchKind;
} }
public override void Search(PEFile module, CancellationToken cancellationToken) public override void Search(MetadataFile module, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var metadata = module.Metadata; var metadata = module.Metadata;

3
ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs

@ -15,7 +15,6 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Globalization; using System.Globalization;
using System.Reflection.Metadata; using System.Reflection.Metadata;
@ -44,7 +43,7 @@ namespace ICSharpCode.ILSpyX.Search
} }
} }
public override void Search(PEFile module, CancellationToken cancellationToken) public override void Search(MetadataFile module, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
if (searchTermToken.IsNil) if (searchTermToken.IsNil)

6
ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.ILSpyX.Search
{ {
} }
public override void Search(PEFile module, CancellationToken cancellationToken) public override void Search(MetadataFile module, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings); var typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings);
@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpyX.Search
Search(module, root); Search(module, root);
} }
private void Search(PEFile module, INamespace ns) private void Search(MetadataFile module, INamespace ns)
{ {
if (ns.Types.Any()) if (ns.Types.Any())
{ {
@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpyX.Search
Search(module, child); Search(module, child);
} }
void OnFoundResult(PEFile module, INamespace ns) void OnFoundResult(MetadataFile module, INamespace ns)
{ {
OnFoundResult(searchRequest.SearchResultFactory.Create(module, ns)); OnFoundResult(searchRequest.SearchResultFactory.Create(module, ns));
} }

7
ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs

@ -15,7 +15,6 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
@ -50,7 +49,7 @@ namespace ICSharpCode.ILSpyX.Search
return true; return true;
} }
public override void Search(PEFile module, CancellationToken cancellationToken) public override void Search(MetadataFile module, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var resourcesNode = treeNodeFactory.CreateResourcesList(module); var resourcesNode = treeNodeFactory.CreateResourcesList(module);
@ -59,7 +58,7 @@ namespace ICSharpCode.ILSpyX.Search
Search(module, resource, resourcesNode, treeNodeFactory.Create(resource), cancellationToken); Search(module, resource, resourcesNode, treeNodeFactory.Create(resource), cancellationToken);
} }
void Search(PEFile module, Resource resource, ITreeNode parent, ITreeNode node, CancellationToken cancellationToken) void Search(MetadataFile module, Resource resource, ITreeNode parent, ITreeNode node, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
@ -81,7 +80,7 @@ namespace ICSharpCode.ILSpyX.Search
Search(module, resource, node, child, cancellationToken); Search(module, resource, node, child, cancellationToken);
} }
void OnFoundResult(PEFile module, Resource resource, ITreeNode node, ITreeNode parent) void OnFoundResult(MetadataFile module, Resource resource, ITreeNode node, ITreeNode parent)
{ {
OnFoundResult(searchRequest.SearchResultFactory.Create(module, resource, node, parent)); OnFoundResult(searchRequest.SearchResultFactory.Create(module, resource, node, parent));
} }

8
ICSharpCode.ILSpyX/Search/SearchResult.cs

@ -28,9 +28,9 @@ namespace ICSharpCode.ILSpyX.Search
public interface ISearchResultFactory public interface ISearchResultFactory
{ {
MemberSearchResult Create(IEntity entity); MemberSearchResult Create(IEntity entity);
ResourceSearchResult Create(PEFile module, Resource resource, ITreeNode node, ITreeNode parent); ResourceSearchResult Create(MetadataFile module, Resource resource, ITreeNode node, ITreeNode parent);
AssemblySearchResult Create(PEFile module); AssemblySearchResult Create(MetadataFile module);
NamespaceSearchResult Create(PEFile module, INamespace @namespace); NamespaceSearchResult Create(MetadataFile module, INamespace @namespace);
} }
public class SearchResult public class SearchResult
@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpyX.Search
public class AssemblySearchResult : SearchResult public class AssemblySearchResult : SearchResult
{ {
#nullable disable #nullable disable
public PEFile Module { get; set; } public MetadataFile Module { get; set; }
public override object Reference => Module; public override object Reference => Module;
#nullable enable #nullable enable
} }

2
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -66,7 +66,7 @@ namespace ILSpy.BamlDecompiler
{ {
var asm = this.Ancestors().OfType<AssemblyTreeNode>().First().LoadedAssembly; var asm = this.Ancestors().OfType<AssemblyTreeNode>().First().LoadedAssembly;
using var data = OpenStream(); using var data = OpenStream();
BamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(asm.GetPEFileOrNull(), asm.GetAssemblyResolver()); BamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(asm.GetMetadataFileOrNull(), asm.GetAssemblyResolver());
var decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings()); var decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings());
decompiler.CancellationToken = cancellationToken; decompiler.CancellationToken = cancellationToken;
var result = decompiler.Decompile(data); var result = decompiler.Decompile(data);

2
ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs

@ -51,7 +51,7 @@ namespace ILSpy.BamlDecompiler
public string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, ResourceFileHandlerContext context) public string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, ResourceFileHandlerContext context)
{ {
BamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(assembly.GetPEFileOrNull(), assembly.GetAssemblyResolver()); BamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(assembly.GetMetadataFileOrNull(), assembly.GetAssemblyResolver());
var decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings() { var decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings() {
ThrowOnAssemblyResolveErrors = context.DecompilationOptions.DecompilerSettings.ThrowOnAssemblyResolveErrors ThrowOnAssemblyResolveErrors = context.DecompilationOptions.DecompilerSettings.ThrowOnAssemblyResolveErrors
}); });

43
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -30,7 +30,6 @@ using System.Runtime.CompilerServices;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Solution; using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -98,7 +97,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
[Export(typeof(Language))] [Export(typeof(Language))]
internal class ReadyToRunLanguage : Language internal class ReadyToRunLanguage : Language
{ {
private static readonly ConditionalWeakTable<PEFile, ReadyToRunReaderCacheEntry> readyToRunReaders = new ConditionalWeakTable<PEFile, ReadyToRunReaderCacheEntry>(); private static readonly ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry> readyToRunReaders = new ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry>();
public override string Name => "ReadyToRun"; public override string Name => "ReadyToRun";
@ -113,7 +112,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{ {
PEFile module = assembly.GetPEFileAsync().GetAwaiter().GetResult(); PEFile module = assembly.GetMetadataFileAsync().GetAwaiter().GetResult() as PEFile;
ReadyToRunReaderCacheEntry cacheEntry = GetReader(assembly, module); ReadyToRunReaderCacheEntry cacheEntry = GetReader(assembly, module);
if (cacheEntry.readyToRunReader == null) if (cacheEntry.readyToRunReader == null)
{ {
@ -136,7 +135,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{ {
PEFile module = method.ParentModule.PEFile; PEFile module = method.ParentModule.MetadataFile as PEFile;
ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module); ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);
if (cacheEntry.readyToRunReader == null) if (cacheEntry.readyToRunReader == null)
{ {
@ -196,7 +195,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
if (cacheEntry.compositeReadyToRunReader == null) if (cacheEntry.compositeReadyToRunReader == null)
{ {
disassemblingReader = reader; disassemblingReader = reader;
file = method.ParentModule.PEFile; file = method.ParentModule.MetadataFile as PEFile;
} }
else else
{ {
@ -220,33 +219,41 @@ namespace ICSharpCode.ILSpy.ReadyToRun
return Languages.ILLanguage.GetRichTextTooltip(entity); return Languages.ILLanguage.GetRichTextTooltip(entity);
} }
private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, PEFile module) private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, MetadataFile file)
{ {
ReadyToRunReaderCacheEntry result; ReadyToRunReaderCacheEntry result;
lock (readyToRunReaders) lock (readyToRunReaders)
{ {
if (!readyToRunReaders.TryGetValue(module, out result)) if (!readyToRunReaders.TryGetValue(file, out result))
{ {
result = new ReadyToRunReaderCacheEntry(); result = new ReadyToRunReaderCacheEntry();
try try
{ {
result.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), new StandaloneAssemblyMetadata(module.Reader), module.Reader, module.FileName); if (file is not PEFile module)
if (result.readyToRunReader.Machine != Machine.Amd64 && result.readyToRunReader.Machine != Machine.I386)
{ {
result.failureReason = $"Architecture {result.readyToRunReader.Machine} is not currently supported.";
result.readyToRunReader = null; result.readyToRunReader = null;
result.failureReason = "File is not a valid PE file.";
} }
else if (result.readyToRunReader.OwnerCompositeExecutable != null) else
{ {
string compositePath = Path.Combine(Path.GetDirectoryName(module.FileName), result.readyToRunReader.OwnerCompositeExecutable); result.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), new StandaloneAssemblyMetadata(module.Reader), module.Reader, module.FileName);
result.compositeReadyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), compositePath); if (result.readyToRunReader.Machine != Machine.Amd64 && result.readyToRunReader.Machine != Machine.I386)
{
result.failureReason = $"Architecture {result.readyToRunReader.Machine} is not currently supported.";
result.readyToRunReader = null;
}
else if (result.readyToRunReader.OwnerCompositeExecutable != null)
{
string compositePath = Path.Combine(Path.GetDirectoryName(module.FileName), result.readyToRunReader.OwnerCompositeExecutable);
result.compositeReadyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), compositePath);
}
} }
} }
catch (BadImageFormatException e) catch (BadImageFormatException e)
{ {
result.failureReason = e.Message; result.failureReason = e.Message;
} }
readyToRunReaders.Add(module, result); readyToRunReaders.Add(file, result);
} }
} }
return result; return result;
@ -270,18 +277,18 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public IAssemblyMetadata FindAssembly(string simpleName, string parentFile) public IAssemblyMetadata FindAssembly(string simpleName, string parentFile)
{ {
return GetAssemblyMetadata(assemblyResolver.ResolveModule(loadedAssembly.GetPEFileOrNull(), simpleName + ".dll")); return GetAssemblyMetadata(assemblyResolver.ResolveModule(loadedAssembly.GetMetadataFileOrNull(), simpleName + ".dll"));
} }
private IAssemblyMetadata GetAssemblyMetadata(PEFile module) private IAssemblyMetadata GetAssemblyMetadata(MetadataFile module)
{ {
if (module.Reader == null) if (module is not PEFile peFile || peFile.Reader == null)
{ {
return null; return null;
} }
else else
{ {
return new IlSpyAssemblyMetadata(module); return new IlSpyAssemblyMetadata(peFile);
} }
} }
} }

9
ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs

@ -16,16 +16,9 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.ILSpy.Analyzers; using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.Analyzers.Builtin; using ICSharpCode.ILSpy.Analyzers.Builtin;
using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX;
@ -47,7 +40,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers
{ {
assemblyList = new AssemblyList(); assemblyList = new AssemblyList();
testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location); testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
testAssemblyTypeSystem = new DecompilerTypeSystem(testAssembly.GetPEFileOrNull(), testAssembly.GetAssemblyResolver()); testAssemblyTypeSystem = new DecompilerTypeSystem(testAssembly.GetMetadataFileOrNull(), testAssembly.GetAssemblyResolver());
language = new CSharpLanguage(); language = new CSharpLanguage();
} }

8
ILSpy/Analyzers/AnalyzerContext.cs

@ -55,11 +55,11 @@ namespace ICSharpCode.ILSpy.Analyzers
{ {
if (!method.HasBody || method.MetadataToken.IsNil) if (!method.HasBody || method.MetadataToken.IsNil)
return null; return null;
var module = method.ParentModule.PEFile; var module = method.ParentModule.MetadataFile;
var md = module.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken); var md = module.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
try try
{ {
return module.Reader.GetMethodBody(md.RelativeVirtualAddress); return module.GetMethodBody(md.RelativeVirtualAddress);
} }
catch (BadImageFormatException) catch (BadImageFormatException)
{ {
@ -72,9 +72,9 @@ namespace ICSharpCode.ILSpy.Analyzers
return new AnalyzerScope(AssemblyList, entity); return new AnalyzerScope(AssemblyList, entity);
} }
readonly ConcurrentDictionary<PEFile, DecompilerTypeSystem> typeSystemCache = new ConcurrentDictionary<PEFile, DecompilerTypeSystem>(); readonly ConcurrentDictionary<MetadataFile, DecompilerTypeSystem> typeSystemCache = new();
public DecompilerTypeSystem GetOrCreateTypeSystem(PEFile module) public DecompilerTypeSystem GetOrCreateTypeSystem(MetadataFile module)
{ {
return typeSystemCache.GetOrAdd(module, m => new DecompilerTypeSystem(m, m.GetAssemblyResolver())); return typeSystemCache.GetOrAdd(module, m => new DecompilerTypeSystem(m, m.GetAssemblyResolver()));
} }

4
ILSpy/Analyzers/AnalyzerEntityTreeNode.cs

@ -41,14 +41,14 @@ namespace ICSharpCode.ILSpy.Analyzers
MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy"); MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy");
return; return;
} }
MainWindow.Instance.JumpToReference(new EntityReference(this.Member.ParentModule.PEFile, this.Member.MetadataToken)); MainWindow.Instance.JumpToReference(new EntityReference(this.Member.ParentModule.MetadataFile, this.Member.MetadataToken));
} }
public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies) public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)
{ {
foreach (LoadedAssembly asm in removedAssemblies) foreach (LoadedAssembly asm in removedAssemblies)
{ {
if (this.Member.ParentModule.PEFile == asm.GetPEFileOrNull()) if (this.Member.ParentModule.MetadataFile == asm.GetMetadataFileOrNull())
return false; // remove this node return false; // remove this node
} }
this.Children.RemoveAll( this.Children.RemoveAll(

6
ILSpy/Analyzers/AnalyzerHelpers.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.Analyzers
{ {
internal static class AnalyzerHelpers internal static class AnalyzerHelpers
{ {
public static bool IsPossibleReferenceTo(EntityHandle member, PEFile module, IMethod analyzedMethod) public static bool IsPossibleReferenceTo(EntityHandle member, MetadataFile module, IMethod analyzedMethod)
{ {
if (member.IsNil) if (member.IsNil)
return false; return false;
@ -34,7 +34,7 @@ namespace ICSharpCode.ILSpy.Analyzers
{ {
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
return member == analyzedMethod.MetadataToken return member == analyzedMethod.MetadataToken
&& module == analyzedMethod.ParentModule.PEFile; && module == analyzedMethod.ParentModule.MetadataFile;
case HandleKind.MemberReference: case HandleKind.MemberReference:
var mr = metadata.GetMemberReference((MemberReferenceHandle)member); var mr = metadata.GetMemberReference((MemberReferenceHandle)member);
if (mr.GetKind() != MemberReferenceKind.Method) if (mr.GetKind() != MemberReferenceKind.Method)
@ -50,7 +50,7 @@ namespace ICSharpCode.ILSpy.Analyzers
public static ISymbol GetParentEntity(DecompilerTypeSystem ts, CustomAttribute customAttribute) public static ISymbol GetParentEntity(DecompilerTypeSystem ts, CustomAttribute customAttribute)
{ {
var metadata = ts.MainModule.PEFile.Metadata; var metadata = ts.MainModule.MetadataFile.Metadata;
switch (customAttribute.Parent.Kind) switch (customAttribute.Parent.Kind)
{ {
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:

28
ILSpy/Analyzers/AnalyzerScope.cs

@ -58,25 +58,25 @@ namespace ICSharpCode.ILSpy.Analyzers
IsLocal = effectiveAccessibility.LessThanOrEqual(Accessibility.Private); IsLocal = effectiveAccessibility.LessThanOrEqual(Accessibility.Private);
} }
public IEnumerable<PEFile> GetModulesInScope(CancellationToken ct) public IEnumerable<MetadataFile> GetModulesInScope(CancellationToken ct)
{ {
if (IsLocal) if (IsLocal)
return new[] { TypeScope.ParentModule.PEFile }; return new[] { TypeScope.ParentModule.MetadataFile };
if (effectiveAccessibility.LessThanOrEqual(Accessibility.Internal)) if (effectiveAccessibility.LessThanOrEqual(Accessibility.Internal))
return GetModuleAndAnyFriends(TypeScope, ct); return GetModuleAndAnyFriends(TypeScope, ct);
return GetReferencingModules(TypeScope.ParentModule.PEFile, ct); return GetReferencingModules(TypeScope.ParentModule.MetadataFile, ct);
} }
public IEnumerable<PEFile> GetAllModules() public IEnumerable<MetadataFile> GetAllModules()
{ {
return assemblyListSnapshot.GetAllAssembliesAsync().GetAwaiter().GetResult() return assemblyListSnapshot.GetAllAssembliesAsync().GetAwaiter().GetResult()
.Select(asm => asm.GetPEFileOrNull()) .Select(asm => asm.GetMetadataFileOrNull())
.Where(x => x != null); .Where(x => x != null);
} }
public DecompilerTypeSystem ConstructTypeSystem(PEFile module) public DecompilerTypeSystem ConstructTypeSystem(MetadataFile module)
{ {
return new DecompilerTypeSystem(module, module.GetAssemblyResolver(assemblyListSnapshot, loadOnDemand: false)); return new DecompilerTypeSystem(module, module.GetAssemblyResolver(assemblyListSnapshot, loadOnDemand: false));
} }
@ -132,7 +132,7 @@ namespace ICSharpCode.ILSpy.Analyzers
} }
#region Find modules #region Find modules
IEnumerable<PEFile> GetReferencingModules(PEFile self, CancellationToken ct) IEnumerable<MetadataFile> GetReferencingModules(MetadataFile self, CancellationToken ct)
{ {
yield return self; yield return self;
@ -140,8 +140,8 @@ namespace ICSharpCode.ILSpy.Analyzers
if (typeScope.TypeParameterCount > 0) if (typeScope.TypeParameterCount > 0)
reflectionTypeScopeName += "`" + typeScope.TypeParameterCount; reflectionTypeScopeName += "`" + typeScope.TypeParameterCount;
var toWalkFiles = new Stack<PEFile>(); var toWalkFiles = new Stack<MetadataFile>();
var checkedFiles = new HashSet<PEFile>(); var checkedFiles = new HashSet<MetadataFile>();
toWalkFiles.Push(self); toWalkFiles.Push(self);
checkedFiles.Add(self); checkedFiles.Add(self);
@ -149,12 +149,12 @@ namespace ICSharpCode.ILSpy.Analyzers
do do
{ {
PEFile curFile = toWalkFiles.Pop(); MetadataFile curFile = toWalkFiles.Pop();
foreach (var assembly in assemblies) foreach (var assembly in assemblies)
{ {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
bool found = false; bool found = false;
var module = assembly.GetPEFileOrNull(); var module = assembly.GetMetadataFileOrNull();
if (module == null || !module.IsAssembly) if (module == null || !module.IsAssembly)
continue; continue;
if (checkedFiles.Contains(module)) if (checkedFiles.Contains(module))
@ -179,9 +179,9 @@ namespace ICSharpCode.ILSpy.Analyzers
} while (toWalkFiles.Count > 0); } while (toWalkFiles.Count > 0);
} }
IEnumerable<PEFile> GetModuleAndAnyFriends(ITypeDefinition typeScope, CancellationToken ct) IEnumerable<MetadataFile> GetModuleAndAnyFriends(ITypeDefinition typeScope, CancellationToken ct)
{ {
var self = typeScope.ParentModule.PEFile; var self = typeScope.ParentModule.MetadataFile;
yield return self; yield return self;
@ -206,7 +206,7 @@ namespace ICSharpCode.ILSpy.Analyzers
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
if (friendAssemblies.Contains(assembly.ShortName)) if (friendAssemblies.Contains(assembly.ShortName))
{ {
var module = assembly.GetPEFileOrNull(); var module = assembly.GetMetadataFileOrNull();
if (module == null) if (module == null)
continue; continue;
if (ModuleReferencesScopeType(module.Metadata, typeScope.Name, typeScope.Namespace)) if (ModuleReferencesScopeType(module.Metadata, typeScope.Name, typeScope.Namespace))

6
ILSpy/Analyzers/Builtin/EventImplementedByAnalyzer.cs

@ -46,15 +46,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
var token = analyzedEntity.MetadataToken; var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
var allTypes = type.GetAllBaseTypeDefinitions(); var allTypes = type.GetAllBaseTypeDefinitions();
if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.MetadataFile == module))
yield break; yield break;
foreach (var @event in type.Events) foreach (var @event in type.Events)
{ {
var baseMembers = InheritanceHelper.GetBaseMembers(@event, true); var baseMembers = InheritanceHelper.GetBaseMembers(@event, true);
if (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule.PEFile == module)) if (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule.MetadataFile == module))
yield return @event; yield return @event;
} }
} }

6
ILSpy/Analyzers/Builtin/EventOverriddenByAnalyzer.cs

@ -46,9 +46,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
var token = analyzedEntity.MetadataToken; var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
var allTypes = type.GetAllBaseTypeDefinitions(); var allTypes = type.GetAllBaseTypeDefinitions();
if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.MetadataFile == module))
yield break; yield break;
foreach (var @event in type.Events) foreach (var @event in type.Events)
@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (!@event.IsOverride) if (!@event.IsOverride)
continue; continue;
var baseMembers = InheritanceHelper.GetBaseMembers(@event, false); var baseMembers = InheritanceHelper.GetBaseMembers(@event, false);
if (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule.PEFile == module)) if (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule.MetadataFile == module))
{ {
yield return @event; yield return @event;
} }

13
ILSpy/Analyzers/Builtin/FieldAccessAnalyzer.cs

@ -17,20 +17,15 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Threading;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Analyzers;
using ILOpCode = System.Reflection.Metadata.ILOpCode; using ILOpCode = System.Reflection.Metadata.ILOpCode;
@ -79,7 +74,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
var scope = context.GetScopeOf((IEntity)analyzedSymbol); var scope = context.GetScopeOf((IEntity)analyzedSymbol);
foreach (var type in scope.GetTypesInScope(context.CancellationToken)) foreach (var type in scope.GetTypesInScope(context.CancellationToken))
{ {
var mappingInfo = context.Language.GetCodeMappingInfo(type.ParentModule.PEFile, type.MetadataToken); var mappingInfo = context.Language.GetCodeMappingInfo(type.ParentModule.MetadataFile, type.MetadataToken);
var methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>(); var methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>();
foreach (var method in methods) foreach (var method in methods)
{ {
@ -126,7 +121,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
if (method.MetadataToken.IsNil) if (method.MetadataToken.IsNil)
return false; return false;
var module = method.ParentModule.PEFile; var module = method.ParentModule.MetadataFile;
foreach (var part in mappingInfo.GetMethodParts((MethodDefinitionHandle)method.MetadataToken)) foreach (var part in mappingInfo.GetMethodParts((MethodDefinitionHandle)method.MetadataToken))
{ {
var md = module.Metadata.GetMethodDefinition(part); var md = module.Metadata.GetMethodDefinition(part);
@ -135,7 +130,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
MethodBodyBlock body; MethodBodyBlock body;
try try
{ {
body = module.Reader.GetMethodBody(md.RelativeVirtualAddress); body = module.GetMethodBody(md.RelativeVirtualAddress);
} }
catch (BadImageFormatException) catch (BadImageFormatException)
{ {
@ -188,7 +183,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
continue; continue;
if (field.MetadataToken == analyzedField.MetadataToken if (field.MetadataToken == analyzedField.MetadataToken
&& field.ParentModule.PEFile == analyzedField.ParentModule.PEFile) && field.ParentModule.MetadataFile == analyzedField.ParentModule.MetadataFile)
return true; return true;
} }

6
ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
class FindTypeInAttributeDecoder : ICustomAttributeTypeProvider<TokenSearchResult> class FindTypeInAttributeDecoder : ICustomAttributeTypeProvider<TokenSearchResult>
{ {
readonly PEFile declaringModule; readonly MetadataFile declaringModule;
readonly MetadataModule currentModule; readonly MetadataModule currentModule;
readonly TypeDefinitionHandle handle; readonly TypeDefinitionHandle handle;
readonly PrimitiveTypeCode primitiveType; readonly PrimitiveTypeCode primitiveType;
@ -65,7 +65,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
public FindTypeInAttributeDecoder(MetadataModule currentModule, ITypeDefinition type) public FindTypeInAttributeDecoder(MetadataModule currentModule, ITypeDefinition type)
{ {
this.currentModule = currentModule; this.currentModule = currentModule;
this.declaringModule = type.ParentModule?.PEFile ?? throw new InvalidOperationException("Cannot use MetadataModule without PEFile as context."); this.declaringModule = type.ParentModule?.MetadataFile ?? throw new InvalidOperationException("Cannot use MetadataModule without PEFile as context.");
this.handle = (TypeDefinitionHandle)type.MetadataToken; this.handle = (TypeDefinitionHandle)type.MetadataToken;
this.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode(); this.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode();
} }
@ -138,7 +138,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
result = TokenSearchResult.SystemType; result = TokenSearchResult.SystemType;
} }
if (td.MetadataToken == this.handle && td.ParentModule?.PEFile == declaringModule) if (td.MetadataToken == this.handle && td.ParentModule?.MetadataFile == declaringModule)
{ {
result |= TokenSearchResult.Found; result |= TokenSearchResult.Found;
} }

6
ILSpy/Analyzers/Builtin/MethodImplementedByAnalyzer.cs

@ -49,15 +49,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
var token = analyzedEntity.MetadataToken; var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
var allTypes = type.GetAllBaseTypeDefinitions(); var allTypes = type.GetAllBaseTypeDefinitions();
if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.MetadataFile == module))
yield break; yield break;
foreach (var method in type.Methods) foreach (var method in type.Methods)
{ {
var baseMembers = InheritanceHelper.GetBaseMembers(method, true); var baseMembers = InheritanceHelper.GetBaseMembers(method, true);
if (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule.PEFile == module)) if (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule.MetadataFile == module))
yield return method; yield return method;
} }
} }

6
ILSpy/Analyzers/Builtin/MethodOverriddenByAnalyzer.cs

@ -48,9 +48,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
var token = analyzedEntity.MetadataToken; var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
var allTypes = type.GetAllBaseTypeDefinitions(); var allTypes = type.GetAllBaseTypeDefinitions();
if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.MetadataFile == module))
yield break; yield break;
foreach (var method in type.Methods) foreach (var method in type.Methods)
@ -58,7 +58,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (!method.IsOverride) if (!method.IsOverride)
continue; continue;
var baseMembers = InheritanceHelper.GetBaseMembers(method, false); var baseMembers = InheritanceHelper.GetBaseMembers(method, false);
if (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule.PEFile == module)) if (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule.MetadataFile == module))
{ {
yield return method; yield return method;
} }

10
ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
var analyzedMethod = (IMethod)analyzedSymbol; var analyzedMethod = (IMethod)analyzedSymbol;
var analyzedBaseMethod = (IMethod)InheritanceHelper.GetBaseMember(analyzedMethod); var analyzedBaseMethod = (IMethod)InheritanceHelper.GetBaseMember(analyzedMethod);
var mapping = context.Language var mapping = context.Language
.GetCodeMappingInfo(analyzedMethod.ParentModule.PEFile, .GetCodeMappingInfo(analyzedMethod.ParentModule.MetadataFile,
analyzedMethod.DeclaringTypeDefinition.MetadataToken); analyzedMethod.DeclaringTypeDefinition.MetadataToken);
var parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken); var parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken);
@ -64,7 +64,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
if (IsUsedInMethod(analyzedMethod, analyzedBaseMethod, method, context)) if (IsUsedInMethod(analyzedMethod, analyzedBaseMethod, method, context))
{ {
mapping ??= context.Language.GetCodeMappingInfo(parentModule.PEFile, type.MetadataToken); mapping ??= context.Language.GetCodeMappingInfo(parentModule.MetadataFile, type.MetadataToken);
var parent = mapping.GetParentMethod((MethodDefinitionHandle)method.MetadataToken); var parent = mapping.GetParentMethod((MethodDefinitionHandle)method.MetadataToken);
yield return parentModule.GetDefinition(parent); yield return parentModule.GetDefinition(parent);
} }
@ -137,9 +137,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
return false; // unexpected end of blob return false; // unexpected end of blob
} }
var member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32()); var member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());
if (!AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.PEFile, analyzedMethod)) if (!AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.MetadataFile, analyzedMethod))
{ {
if (analyzedBaseMethod == null || !AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.PEFile, analyzedBaseMethod)) if (analyzedBaseMethod == null || !AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.MetadataFile, analyzedBaseMethod))
{ {
continue; continue;
} }
@ -192,7 +192,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
static bool IsSameMember(IMember analyzedMethod, IMember m) static bool IsSameMember(IMember analyzedMethod, IMember m)
{ {
return m.MetadataToken == analyzedMethod.MetadataToken return m.MetadataToken == analyzedMethod.MetadataToken
&& m.ParentModule.PEFile == analyzedMethod.ParentModule.PEFile; && m.ParentModule.MetadataFile == analyzedMethod.ParentModule.MetadataFile;
} }
} }
} }

10
ILSpy/Analyzers/Builtin/MethodUsesAnalyzer.cs

@ -38,10 +38,10 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
public IEnumerable<ISymbol> Analyze(ISymbol symbol, AnalyzerContext context) public IEnumerable<ISymbol> Analyze(ISymbol symbol, AnalyzerContext context)
{ {
if (symbol is IMethod method) if (symbol is IMethod method && method.ParentModule.MetadataFile is MetadataFile corFile)
{ {
var typeSystem = context.GetOrCreateTypeSystem(method.ParentModule.PEFile); var typeSystem = context.GetOrCreateTypeSystem(corFile);
return context.Language.GetCodeMappingInfo(method.ParentModule.PEFile, method.MetadataToken) return context.Language.GetCodeMappingInfo(corFile, method.MetadataToken)
.GetMethodParts((MethodDefinitionHandle)method.MetadataToken) .GetMethodParts((MethodDefinitionHandle)method.MetadataToken)
.SelectMany(h => ScanMethod(h, typeSystem)).Distinct(); .SelectMany(h => ScanMethod(h, typeSystem)).Distinct();
} }
@ -51,14 +51,14 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
IEnumerable<IEntity> ScanMethod(MethodDefinitionHandle handle, DecompilerTypeSystem typeSystem) IEnumerable<IEntity> ScanMethod(MethodDefinitionHandle handle, DecompilerTypeSystem typeSystem)
{ {
var module = typeSystem.MainModule; var module = typeSystem.MainModule;
var md = module.PEFile.Metadata.GetMethodDefinition(handle); var md = module.MetadataFile.Metadata.GetMethodDefinition(handle);
if (!md.HasBody()) if (!md.HasBody())
yield break; yield break;
BlobReader blob; BlobReader blob;
try try
{ {
blob = module.PEFile.Reader.GetMethodBody(md.RelativeVirtualAddress).GetILReader(); blob = module.MetadataFile.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
} }
catch (BadImageFormatException) catch (BadImageFormatException)
{ {

6
ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
Debug.Assert(analyzedSymbol is IMethod); Debug.Assert(analyzedSymbol is IMethod);
var analyzedMethod = (IMethod)analyzedSymbol; var analyzedMethod = (IMethod)analyzedSymbol;
var mapping = context.Language var mapping = context.Language
.GetCodeMappingInfo(analyzedMethod.ParentModule.PEFile, .GetCodeMappingInfo(analyzedMethod.ParentModule.MetadataFile,
analyzedMethod.DeclaringTypeDefinition.MetadataToken); analyzedMethod.DeclaringTypeDefinition.MetadataToken);
var parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken); var parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken);
@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
foreach (var type in scope.GetTypesInScope(context.CancellationToken)) foreach (var type in scope.GetTypesInScope(context.CancellationToken))
{ {
var parentModule = (MetadataModule)type.ParentModule; var parentModule = (MetadataModule)type.ParentModule;
mapping = context.Language.GetCodeMappingInfo(parentModule.PEFile, type.MetadataToken); mapping = context.Language.GetCodeMappingInfo(parentModule.MetadataFile, type.MetadataToken);
var methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>(); var methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>();
foreach (var method in methods) foreach (var method in methods)
{ {
@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
case HandleKind.MethodSpecification: case HandleKind.MethodSpecification:
case HandleKind.MemberReference: case HandleKind.MemberReference:
var m = (mainModule.ResolveEntity(member, genericContext) as IMember)?.MemberDefinition; var m = (mainModule.ResolveEntity(member, genericContext) as IMember)?.MemberDefinition;
if (m != null && m.MetadataToken == analyzedMethod.MetadataToken && m.ParentModule.PEFile == analyzedMethod.ParentModule.PEFile) if (m != null && m.MetadataToken == analyzedMethod.MetadataToken && m.ParentModule.MetadataFile == analyzedMethod.ParentModule.MetadataFile)
{ {
return true; return true;
} }

6
ILSpy/Analyzers/Builtin/PropertyImplementedByAnalyzer.cs

@ -46,15 +46,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
var token = analyzedEntity.MetadataToken; var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
var allTypes = type.GetAllBaseTypeDefinitions(); var allTypes = type.GetAllBaseTypeDefinitions();
if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.MetadataFile == module))
yield break; yield break;
foreach (var property in type.Properties) foreach (var property in type.Properties)
{ {
var baseMembers = InheritanceHelper.GetBaseMembers(property, true); var baseMembers = InheritanceHelper.GetBaseMembers(property, true);
if (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule.PEFile == module)) if (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule.MetadataFile == module))
yield return property; yield return property;
} }
} }

6
ILSpy/Analyzers/Builtin/PropertyOverriddenByAnalyzer.cs

@ -49,9 +49,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
var token = analyzedEntity.MetadataToken; var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken; var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile; var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
var allTypes = type.GetAllBaseTypeDefinitions(); var allTypes = type.GetAllBaseTypeDefinitions();
if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.PEFile == module)) if (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule.MetadataFile == module))
yield break; yield break;
foreach (var property in type.Properties) foreach (var property in type.Properties)
@ -59,7 +59,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (!property.IsOverride) if (!property.IsOverride)
continue; continue;
var baseMembers = InheritanceHelper.GetBaseMembers(property, false); var baseMembers = InheritanceHelper.GetBaseMembers(property, false);
if (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule.PEFile == module)) if (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule.MetadataFile == module))
{ {
yield return property; yield return property;
} }

2
ILSpy/Analyzers/Builtin/TypeExposedByAnalyzer.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{ {
if (analyzedType.Kind == TypeKind.Enum if (analyzedType.Kind == TypeKind.Enum
&& type.MetadataToken == analyzedType.MetadataToken && type.MetadataToken == analyzedType.MetadataToken
&& type.ParentModule.PEFile == analyzedType.ParentModule.PEFile) && type.ParentModule.MetadataFile == analyzedType.ParentModule.MetadataFile)
yield break; yield break;
if (!context.Language.ShowMember(type)) if (!context.Language.ShowMember(type))

2
ILSpy/Analyzers/Builtin/TypeExtensionMethodsAnalyzer.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
var firstParamType = method.Parameters[0].Type.GetDefinition(); var firstParamType = method.Parameters[0].Type.GetDefinition();
if (firstParamType != null && if (firstParamType != null &&
firstParamType.MetadataToken == analyzedType.MetadataToken && firstParamType.MetadataToken == analyzedType.MetadataToken &&
firstParamType.ParentModule.PEFile == analyzedType.ParentModule.PEFile) firstParamType.ParentModule.MetadataFile == analyzedType.ParentModule.MetadataFile)
yield return method; yield return method;
} }
} }

4
ILSpy/Analyzers/Builtin/TypeInstantiatedByAnalyzer.cs

@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
var scope = context.GetScopeOf((ITypeDefinition)analyzedSymbol); var scope = context.GetScopeOf((ITypeDefinition)analyzedSymbol);
foreach (var type in scope.GetTypesInScope(context.CancellationToken)) foreach (var type in scope.GetTypesInScope(context.CancellationToken))
{ {
var mappingInfo = context.Language.GetCodeMappingInfo(type.ParentModule.PEFile, type.MetadataToken); var mappingInfo = context.Language.GetCodeMappingInfo(type.ParentModule.MetadataFile, type.MetadataToken);
var methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>(); var methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>();
foreach (var method in methods) foreach (var method in methods)
{ {
@ -134,7 +134,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
continue; continue;
if (ctor.DeclaringTypeDefinition?.MetadataToken == analyzedEntity.MetadataToken if (ctor.DeclaringTypeDefinition?.MetadataToken == analyzedEntity.MetadataToken
&& ctor.ParentModule.PEFile == analyzedEntity.ParentModule.PEFile) && ctor.ParentModule.MetadataFile == analyzedEntity.ParentModule.MetadataFile)
return true; return true;
} }

10
ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
.AsParallel().AsOrdered() .AsParallel().AsOrdered()
.SelectMany(AnalyzeModuleAndFilter); .SelectMany(AnalyzeModuleAndFilter);
IEnumerable<ISymbol> AnalyzeModuleAndFilter(PEFile module) IEnumerable<ISymbol> AnalyzeModuleAndFilter(MetadataFile module)
{ {
return AnalyzeModule(analyzedType, scope, module) return AnalyzeModule(analyzedType, scope, module)
.Distinct() .Distinct()
@ -55,7 +55,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
} }
} }
static IEnumerable<ISymbol> AnalyzeModule(ITypeDefinition analyzedType, AnalyzerScope scope, PEFile module) static IEnumerable<ISymbol> AnalyzeModule(ITypeDefinition analyzedType, AnalyzerScope scope, MetadataFile module)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
var typeSystem = scope.ConstructTypeSystem(module); var typeSystem = scope.ConstructTypeSystem(module);
@ -241,12 +241,12 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
} }
} }
static bool ScanMethodBody(ITypeDefinition analyzedType, PEFile module, in MethodDefinition md, FindTypeDecoder decoder) static bool ScanMethodBody(ITypeDefinition analyzedType, MetadataFile module, in MethodDefinition md, FindTypeDecoder decoder)
{ {
if (!md.HasBody()) if (!md.HasBody())
return false; return false;
var methodBody = module.Reader.GetMethodBody(md.RelativeVirtualAddress); var methodBody = module.GetMethodBody(md.RelativeVirtualAddress);
var metadata = module.Metadata; var metadata = module.Metadata;
if (!methodBody.LocalSignature.IsNil) if (!methodBody.LocalSignature.IsNil)
@ -408,7 +408,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
public override IType VisitTypeDefinition(ITypeDefinition type) public override IType VisitTypeDefinition(ITypeDefinition type)
{ {
Found |= TypeDefinition.MetadataToken == type.MetadataToken Found |= TypeDefinition.MetadataToken == type.MetadataToken
&& TypeDefinition.ParentModule.PEFile == type.ParentModule.PEFile; && TypeDefinition.ParentModule.MetadataFile == type.ParentModule.MetadataFile;
return base.VisitTypeDefinition(type); return base.VisitTypeDefinition(type);
} }

4
ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs

@ -54,12 +54,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
public override void ActivateItem(RoutedEventArgs e) public override void ActivateItem(RoutedEventArgs e)
{ {
e.Handled = true; e.Handled = true;
if (analyzedModule.PEFile == null) if (analyzedModule.MetadataFile == null)
{ {
MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy"); MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy");
return; return;
} }
MainWindow.Instance.JumpToReference(analyzedModule.PEFile); MainWindow.Instance.JumpToReference(analyzedModule.MetadataFile);
} }
public override IEntity Member => null; public override IEntity Member => null;

3
ILSpy/Commands/GeneratePdbContextMenuEntry.cs

@ -27,6 +27,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp; using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.DebugInfo; using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
@ -58,7 +59,7 @@ namespace ICSharpCode.ILSpy
internal static void GeneratePdbForAssembly(LoadedAssembly assembly) internal static void GeneratePdbForAssembly(LoadedAssembly assembly)
{ {
var file = assembly.GetPEFileOrNull(); var file = assembly.GetMetadataFileOrNull() as PEFile;
if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file)) if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file))
{ {
MessageBox.Show(string.Format(Resources.CannotCreatePDBFile, Path.GetFileName(assembly.FileName))); MessageBox.Show(string.Format(Resources.CannotCreatePDBFile, Path.GetFileName(assembly.FileName)));

2
ILSpy/EntityReference.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy
public MetadataFile? ResolveAssembly(AssemblyList context) public MetadataFile? ResolveAssembly(AssemblyList context)
{ {
return peFile ?? context.FindAssembly(Module)?.GetPEFileOrNull(); return peFile ?? context.FindAssembly(Module)?.GetMetadataFileOrNull();
} }
} }
} }

8
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -23,8 +23,6 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Threading;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
@ -64,7 +62,7 @@ namespace ICSharpCode.ILSpy
}; };
} }
static CSharpDecompiler CreateDecompiler(PEFile module, DecompilationOptions options) static CSharpDecompiler CreateDecompiler(MetadataFile module, DecompilationOptions options)
{ {
CSharpDecompiler decompiler = new CSharpDecompiler(module, module.GetAssemblyResolver(), options.DecompilerSettings); CSharpDecompiler decompiler = new CSharpDecompiler(module, module.GetAssemblyResolver(), options.DecompilerSettings);
decompiler.CancellationToken = options.CancellationToken; decompiler.CancellationToken = options.CancellationToken;
@ -93,7 +91,7 @@ namespace ICSharpCode.ILSpy
this.options = options; this.options = options;
} }
public override void Disassemble(PEFile module, MethodDefinitionHandle handle) public override void Disassemble(MetadataFile module, MethodDefinitionHandle handle)
{ {
try try
{ {
@ -113,7 +111,7 @@ namespace ICSharpCode.ILSpy
} }
} }
protected override void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva) protected override void WriteInstruction(ITextOutput output, MetadataFile metadata, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva)
{ {
int index = sequencePoints.BinarySearch(blob.Offset, seq => seq.Offset); int index = sequencePoints.BinarySearch(blob.Offset, seq => seq.Offset);
if (index >= 0) if (index >= 0)

30
ILSpy/Languages/CSharpLanguage.cs

@ -120,7 +120,7 @@ namespace ICSharpCode.ILSpy
} }
} }
CSharpDecompiler CreateDecompiler(PEFile module, DecompilationOptions options) CSharpDecompiler CreateDecompiler(MetadataFile module, DecompilationOptions options)
{ {
CSharpDecompiler decompiler = new CSharpDecompiler(module, module.GetAssemblyResolver(options.DecompilerSettings.AutoLoadAssemblyReferences), options.DecompilerSettings); CSharpDecompiler decompiler = new CSharpDecompiler(module, module.GetAssemblyResolver(options.DecompilerSettings.AutoLoadAssemblyReferences), options.DecompilerSettings);
decompiler.CancellationToken = options.CancellationToken; decompiler.CancellationToken = options.CancellationToken;
@ -148,7 +148,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{ {
PEFile assembly = method.ParentModule.PEFile; MetadataFile assembly = method.ParentModule.MetadataFile;
CSharpDecompiler decompiler = CreateDecompiler(assembly, options); CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
AddReferenceAssemblyWarningMessage(assembly, output); AddReferenceAssemblyWarningMessage(assembly, output);
AddReferenceWarningMessage(assembly, output); AddReferenceWarningMessage(assembly, output);
@ -230,7 +230,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options) public override void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options)
{ {
PEFile assembly = property.ParentModule.PEFile; MetadataFile assembly = property.ParentModule.MetadataFile;
CSharpDecompiler decompiler = CreateDecompiler(assembly, options); CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
AddReferenceAssemblyWarningMessage(assembly, output); AddReferenceAssemblyWarningMessage(assembly, output);
AddReferenceWarningMessage(assembly, output); AddReferenceWarningMessage(assembly, output);
@ -241,7 +241,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileField(IField field, ITextOutput output, DecompilationOptions options) public override void DecompileField(IField field, ITextOutput output, DecompilationOptions options)
{ {
PEFile assembly = field.ParentModule.PEFile; MetadataFile assembly = field.ParentModule.MetadataFile;
CSharpDecompiler decompiler = CreateDecompiler(assembly, options); CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
AddReferenceAssemblyWarningMessage(assembly, output); AddReferenceAssemblyWarningMessage(assembly, output);
AddReferenceWarningMessage(assembly, output); AddReferenceWarningMessage(assembly, output);
@ -310,7 +310,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileEvent(IEvent @event, ITextOutput output, DecompilationOptions options) public override void DecompileEvent(IEvent @event, ITextOutput output, DecompilationOptions options)
{ {
PEFile assembly = @event.ParentModule.PEFile; MetadataFile assembly = @event.ParentModule.MetadataFile;
CSharpDecompiler decompiler = CreateDecompiler(assembly, options); CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
AddReferenceAssemblyWarningMessage(assembly, output); AddReferenceAssemblyWarningMessage(assembly, output);
AddReferenceWarningMessage(assembly, output); AddReferenceWarningMessage(assembly, output);
@ -321,7 +321,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options) public override void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options)
{ {
PEFile assembly = type.ParentModule.PEFile; MetadataFile assembly = type.ParentModule.MetadataFile;
CSharpDecompiler decompiler = CreateDecompiler(assembly, options); CSharpDecompiler decompiler = CreateDecompiler(assembly, options);
AddReferenceAssemblyWarningMessage(assembly, output); AddReferenceAssemblyWarningMessage(assembly, output);
AddReferenceWarningMessage(assembly, output); AddReferenceWarningMessage(assembly, output);
@ -330,9 +330,9 @@ namespace ICSharpCode.ILSpy
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(type.MetadataToken), decompiler.TypeSystem); WriteCode(output, options.DecompilerSettings, decompiler.Decompile(type.MetadataToken), decompiler.TypeSystem);
} }
void AddReferenceWarningMessage(PEFile module, ITextOutput output) void AddReferenceWarningMessage(MetadataFile module, ITextOutput output)
{ {
var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetPEFileOrNull() == module); var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetMetadataFileOrNull() == module);
if (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors) if (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors)
return; return;
string line1 = Properties.Resources.WarningSomeAssemblyReference; string line1 = Properties.Resources.WarningSomeAssemblyReference;
@ -344,7 +344,7 @@ namespace ICSharpCode.ILSpy
}); });
} }
void AddReferenceAssemblyWarningMessage(PEFile module, ITextOutput output) void AddReferenceAssemblyWarningMessage(MetadataFile module, ITextOutput output)
{ {
var metadata = module.Metadata; var metadata = module.Metadata;
if (!metadata.GetCustomAttributes(Handle.AssemblyDefinition).HasKnownAttribute(metadata, KnownAttribute.ReferenceAssembly)) if (!metadata.GetCustomAttributes(Handle.AssemblyDefinition).HasKnownAttribute(metadata, KnownAttribute.ReferenceAssembly))
@ -353,7 +353,7 @@ namespace ICSharpCode.ILSpy
AddWarningMessage(module, output, line1); AddWarningMessage(module, output, line1);
} }
void AddWarningMessage(PEFile module, ITextOutput output, string line1, string line2 = null, void AddWarningMessage(MetadataFile module, ITextOutput output, string line1, string line2 = null,
string buttonText = null, System.Windows.Media.ImageSource buttonImage = null, RoutedEventHandler buttonClickHandler = null) string buttonText = null, System.Windows.Media.ImageSource buttonImage = null, RoutedEventHandler buttonClickHandler = null)
{ {
if (output is ISmartTextOutput fancyOutput) if (output is ISmartTextOutput fancyOutput)
@ -393,7 +393,7 @@ namespace ICSharpCode.ILSpy
public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{ {
var module = assembly.GetPEFileOrNull(); var module = assembly.GetMetadataFileOrNull() as PEFile;
if (module == null) if (module == null)
{ {
return null; return null;
@ -426,7 +426,7 @@ namespace ICSharpCode.ILSpy
output.WriteLine(); output.WriteLine();
} }
var metadata = module.Metadata; var metadata = module.Metadata;
var corHeader = module.Reader.PEHeaders.CorHeader; var corHeader = module.CorHeader;
var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress); var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress);
if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition) if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition)
{ {
@ -664,7 +664,7 @@ namespace ICSharpCode.ILSpy
} }
} }
public override string GetEntityName(PEFile module, EntityHandle handle, bool fullName, bool omitGenerics) public override string GetEntityName(MetadataFile module, EntityHandle handle, bool fullName, bool omitGenerics)
{ {
MetadataReader metadata = module.Metadata; MetadataReader metadata = module.Metadata;
switch (handle.Kind) switch (handle.Kind)
@ -737,7 +737,7 @@ namespace ICSharpCode.ILSpy
public override bool ShowMember(IEntity member) public override bool ShowMember(IEntity member)
{ {
PEFile assembly = member.ParentModule.PEFile; MetadataFile assembly = member.ParentModule.MetadataFile;
return showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, MainWindow.Instance.CurrentDecompilerSettings); return showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, MainWindow.Instance.CurrentDecompilerSettings);
} }
@ -782,7 +782,7 @@ namespace ICSharpCode.ILSpy
return new RichText(output.ToString(), writer.HighlightingModel); return new RichText(output.ToString(), writer.HighlightingModel);
} }
public override CodeMappingInfo GetCodeMappingInfo(PEFile module, EntityHandle member) public override CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)
{ {
return CSharpDecompiler.GetCodeMappingInfo(module, member); return CSharpDecompiler.GetCodeMappingInfo(module, member);
} }

14
ILSpy/Languages/ILAstLanguage.cs

@ -18,8 +18,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp; using ICSharpCode.Decompiler.CSharp;
@ -31,8 +29,6 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX;
using static System.Reflection.Metadata.PEReaderExtensions;
using SRM = System.Reflection.Metadata; using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
@ -77,7 +73,7 @@ namespace ICSharpCode.ILSpy
{ {
base.DecompileMethod(method, output, options); base.DecompileMethod(method, output, options);
new ReflectionDisassembler(output, options.CancellationToken) new ReflectionDisassembler(output, options.CancellationToken)
.DisassembleMethodHeader(method.ParentModule.PEFile, (SRM.MethodDefinitionHandle)method.MetadataToken); .DisassembleMethodHeader(method.ParentModule.MetadataFile, (SRM.MethodDefinitionHandle)method.MetadataToken);
output.WriteLine(); output.WriteLine();
output.WriteLine(); output.WriteLine();
} }
@ -89,13 +85,13 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{ {
base.DecompileMethod(method, output, options); base.DecompileMethod(method, output, options);
var module = method.ParentModule.PEFile; var module = method.ParentModule.MetadataFile;
var methodDef = module.Metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)method.MetadataToken); var methodDef = module.Metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)method.MetadataToken);
if (!methodDef.HasBody()) if (!methodDef.HasBody())
return; return;
var typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver()); var typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
ILReader reader = new ILReader(typeSystem.MainModule); ILReader reader = new ILReader(typeSystem.MainModule);
var methodBody = module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress); var methodBody = module.GetMethodBody(methodDef.RelativeVirtualAddress);
reader.WriteTypedIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, output, cancellationToken: options.CancellationToken); reader.WriteTypedIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, output, cancellationToken: options.CancellationToken);
} }
} }
@ -112,7 +108,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{ {
base.DecompileMethod(method, output, options); base.DecompileMethod(method, output, options);
var module = method.ParentModule.PEFile; var module = method.ParentModule.MetadataFile;
var metadata = module.Metadata; var metadata = module.Metadata;
var methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)method.MetadataToken); var methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)method.MetadataToken);
if (!methodDef.HasBody()) if (!methodDef.HasBody())
@ -121,7 +117,7 @@ namespace ICSharpCode.ILSpy
var typeSystem = new DecompilerTypeSystem(module, assemblyResolver); var typeSystem = new DecompilerTypeSystem(module, assemblyResolver);
var reader = new ILReader(typeSystem.MainModule); var reader = new ILReader(typeSystem.MainModule);
reader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols; reader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols;
var methodBody = module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress); var methodBody = module.GetMethodBody(methodDef.RelativeVirtualAddress);
ILFunction il = reader.ReadIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, kind: ILFunctionKind.TopLevelFunction, cancellationToken: options.CancellationToken); ILFunction il = reader.ReadIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, kind: ILFunctionKind.TopLevelFunction, cancellationToken: options.CancellationToken);
var decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings) { CancellationToken = options.CancellationToken }; var decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings) { CancellationToken = options.CancellationToken };
ILTransformContext context = decompiler.CreateILTransformContext(il); ILTransformContext context = decompiler.CreateILTransformContext(il);

26
ILSpy/Languages/ILLanguage.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
PEFile module = method.ParentModule.PEFile; MetadataFile module = method.ParentModule.MetadataFile;
dis.AssemblyResolver = module.GetAssemblyResolver(); dis.AssemblyResolver = module.GetAssemblyResolver();
dis.DebugInfo = module.GetDebugInfoOrNull(); dis.DebugInfo = module.GetDebugInfoOrNull();
dis.DisassembleMethod(module, (MethodDefinitionHandle)method.MetadataToken); dis.DisassembleMethod(module, (MethodDefinitionHandle)method.MetadataToken);
@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileField(IField field, ITextOutput output, DecompilationOptions options) public override void DecompileField(IField field, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
PEFile module = field.ParentModule.PEFile; MetadataFile module = field.ParentModule.MetadataFile;
dis.AssemblyResolver = module.GetAssemblyResolver(); dis.AssemblyResolver = module.GetAssemblyResolver();
dis.DebugInfo = module.GetDebugInfoOrNull(); dis.DebugInfo = module.GetDebugInfoOrNull();
dis.DisassembleField(module, (FieldDefinitionHandle)field.MetadataToken); dis.DisassembleField(module, (FieldDefinitionHandle)field.MetadataToken);
@ -89,7 +89,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options) public override void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
PEFile module = property.ParentModule.PEFile; MetadataFile module = property.ParentModule.MetadataFile;
dis.AssemblyResolver = module.GetAssemblyResolver(); dis.AssemblyResolver = module.GetAssemblyResolver();
dis.DebugInfo = module.GetDebugInfoOrNull(); dis.DebugInfo = module.GetDebugInfoOrNull();
dis.DisassembleProperty(module, (PropertyDefinitionHandle)property.MetadataToken); dis.DisassembleProperty(module, (PropertyDefinitionHandle)property.MetadataToken);
@ -115,7 +115,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileEvent(IEvent ev, ITextOutput output, DecompilationOptions options) public override void DecompileEvent(IEvent ev, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
PEFile module = ev.ParentModule.PEFile; MetadataFile module = ev.ParentModule.MetadataFile;
dis.AssemblyResolver = module.GetAssemblyResolver(); dis.AssemblyResolver = module.GetAssemblyResolver();
dis.DebugInfo = module.GetDebugInfoOrNull(); dis.DebugInfo = module.GetDebugInfoOrNull();
dis.DisassembleEvent(module, (EventDefinitionHandle)ev.MetadataToken); dis.DisassembleEvent(module, (EventDefinitionHandle)ev.MetadataToken);
@ -146,7 +146,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options) public override void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
PEFile module = type.ParentModule.PEFile; MetadataFile module = type.ParentModule.MetadataFile;
dis.AssemblyResolver = module.GetAssemblyResolver(); dis.AssemblyResolver = module.GetAssemblyResolver();
dis.DebugInfo = module.GetDebugInfoOrNull(); dis.DebugInfo = module.GetDebugInfoOrNull();
dis.DisassembleType(module, (TypeDefinitionHandle)type.MetadataToken); dis.DisassembleType(module, (TypeDefinitionHandle)type.MetadataToken);
@ -155,7 +155,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileNamespace(string nameSpace, IEnumerable<ITypeDefinition> types, ITextOutput output, DecompilationOptions options) public override void DecompileNamespace(string nameSpace, IEnumerable<ITypeDefinition> types, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
PEFile module = types.FirstOrDefault()?.ParentModule.PEFile; MetadataFile module = types.FirstOrDefault()?.ParentModule.MetadataFile;
dis.AssemblyResolver = module.GetAssemblyResolver(); dis.AssemblyResolver = module.GetAssemblyResolver();
dis.DebugInfo = module.GetDebugInfoOrNull(); dis.DebugInfo = module.GetDebugInfoOrNull();
dis.DisassembleNamespace(nameSpace, module, types.Select(t => (TypeDefinitionHandle)t.MetadataToken)); dis.DisassembleNamespace(nameSpace, module, types.Select(t => (TypeDefinitionHandle)t.MetadataToken));
@ -165,15 +165,21 @@ namespace ICSharpCode.ILSpy
{ {
output.WriteLine("// " + assembly.FileName); output.WriteLine("// " + assembly.FileName);
output.WriteLine(); output.WriteLine();
var module = assembly.GetPEFileAsync().GetAwaiter().GetResult(); var module = assembly.GetMetadataFileOrNull() as PEFile;
var metadata = module.Metadata;
var dis = CreateDisassembler(output, options); if (module == null)
{
throw new NotSupportedException("This file is not a PE file");
}
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) if (options.FullDecompilation && options.SaveAsProjectDirectory != null)
{ {
throw new NotSupportedException($"Language '{Name}' does not support exporting assemblies as projects!"); throw new NotSupportedException($"Language '{Name}' does not support exporting assemblies as projects!");
} }
var metadata = module.Metadata;
var dis = CreateDisassembler(output, options);
// don't automatically load additional assemblies when an assembly node is selected in the tree view // don't automatically load additional assemblies when an assembly node is selected in the tree view
dis.AssemblyResolver = module.GetAssemblyResolver(loadOnDemand: options.FullDecompilation); dis.AssemblyResolver = module.GetAssemblyResolver(loadOnDemand: options.FullDecompilation);
dis.DebugInfo = module.GetDebugInfoOrNull(); dis.DebugInfo = module.GetDebugInfoOrNull();
@ -196,7 +202,7 @@ namespace ICSharpCode.ILSpy
{ {
var output = new AvalonEditTextOutput() { IgnoreNewLineAndIndent = true }; var output = new AvalonEditTextOutput() { IgnoreNewLineAndIndent = true };
var disasm = CreateDisassembler(output, MainWindow.Instance.CreateDecompilationOptions()); var disasm = CreateDisassembler(output, MainWindow.Instance.CreateDecompilationOptions());
PEFile module = entity.ParentModule?.PEFile; MetadataFile module = entity.ParentModule?.MetadataFile;
if (module == null) if (module == null)
{ {
return null; return null;

8
ILSpy/Languages/Language.cs

@ -110,7 +110,7 @@ namespace ICSharpCode.ILSpy
public virtual ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) public virtual ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{ {
WriteCommentLine(output, assembly.FileName); WriteCommentLine(output, assembly.FileName);
var asm = assembly.GetPEFileOrNull(); var asm = assembly.GetMetadataFileOrNull();
if (asm == null) if (asm == null)
return null; return null;
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) if (options.FullDecompilation && options.SaveAsProjectDirectory != null)
@ -442,7 +442,7 @@ namespace ICSharpCode.ILSpy
string entityName; string entityName;
if (entity is ITypeDefinition t && !t.MetadataToken.IsNil) if (entity is ITypeDefinition t && !t.MetadataToken.IsNil)
{ {
MetadataReader metadata = t.ParentModule.PEFile.Metadata; MetadataReader metadata = t.ParentModule.MetadataFile.Metadata;
var typeDef = metadata.GetTypeDefinition((TypeDefinitionHandle)t.MetadataToken); var typeDef = metadata.GetTypeDefinition((TypeDefinitionHandle)t.MetadataToken);
entityName = EscapeName(metadata.GetString(typeDef.Name)); entityName = EscapeName(metadata.GetString(typeDef.Name));
} }
@ -478,7 +478,7 @@ namespace ICSharpCode.ILSpy
/// <summary> /// <summary>
/// This should produce a string representation of the entity for search to match search strings against. /// This should produce a string representation of the entity for search to match search strings against.
/// </summary> /// </summary>
public virtual string GetEntityName(PEFile module, EntityHandle handle, bool fullName, bool omitGenerics) public virtual string GetEntityName(MetadataFile module, EntityHandle handle, bool fullName, bool omitGenerics)
{ {
MetadataReader metadata = module.Metadata; MetadataReader metadata = module.Metadata;
switch (handle.Kind) switch (handle.Kind)
@ -522,7 +522,7 @@ namespace ICSharpCode.ILSpy
} }
} }
public virtual CodeMappingInfo GetCodeMappingInfo(PEFile module, EntityHandle member) public virtual CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)
{ {
var declaringType = (TypeDefinitionHandle)member.GetDeclaringType(module.Metadata); var declaringType = (TypeDefinitionHandle)member.GetDeclaringType(module.Metadata);

16
ILSpy/MainWindow.xaml.cs

@ -710,7 +710,7 @@ namespace ICSharpCode.ILSpy
{ {
// FindNamespaceNode() blocks the UI if the assembly is not yet loaded, // FindNamespaceNode() blocks the UI if the assembly is not yet loaded,
// so use an async wait instead. // so use an async wait instead.
await asm.GetPEFileAsync().Catch<Exception>(ex => { }); await asm.GetMetadataFileAsync().Catch<Exception>(ex => { });
NamespaceTreeNode nsNode = asmNode.FindNamespaceNode(namespaceName); NamespaceTreeNode nsNode = asmNode.FindNamespaceNode(namespaceName);
if (nsNode != null) if (nsNode != null)
{ {
@ -736,7 +736,7 @@ namespace ICSharpCode.ILSpy
// Make sure we wait for assemblies being loaded... // Make sure we wait for assemblies being loaded...
// BeginInvoke in LoadedAssembly.LookupReferencedAssemblyInternal // BeginInvoke in LoadedAssembly.LookupReferencedAssemblyInternal
await Dispatcher.InvokeAsync(delegate { }, DispatcherPriority.Normal); await Dispatcher.InvokeAsync(delegate { }, DispatcherPriority.Normal);
if (mr != null && mr.ParentModule.PEFile != null) if (mr != null && mr.ParentModule.MetadataFile != null)
{ {
found = true; found = true;
if (AssemblyTreeView.SelectedItem == initialSelection) if (AssemblyTreeView.SelectedItem == initialSelection)
@ -773,7 +773,7 @@ namespace ICSharpCode.ILSpy
{ {
// FindNodeByPath() blocks the UI if the assembly is not yet loaded, // FindNodeByPath() blocks the UI if the assembly is not yet loaded,
// so use an async wait instead. // so use an async wait instead.
await asm.GetPEFileAsync().Catch<Exception>(ex => { }); await asm.GetMetadataFileAsync().Catch<Exception>(ex => { });
} }
} }
node = FindNodeByPath(activeTreeViewPath, true); node = FindNodeByPath(activeTreeViewPath, true);
@ -810,12 +810,12 @@ namespace ICSharpCode.ILSpy
} }
foreach (LoadedAssembly asm in relevantAssemblies.ToList()) foreach (LoadedAssembly asm in relevantAssemblies.ToList())
{ {
var module = asm.GetPEFileOrNull(); var module = asm.GetMetadataFileOrNull();
if (CanResolveTypeInPEFile(module, typeRef, out var typeHandle)) if (CanResolveTypeInPEFile(module, typeRef, out var typeHandle))
{ {
ICompilation compilation = typeHandle.Kind == HandleKind.ExportedType ICompilation compilation = typeHandle.Kind == HandleKind.ExportedType
? new DecompilerTypeSystem(module, module.GetAssemblyResolver()) ? new DecompilerTypeSystem(module, module.GetAssemblyResolver())
: new SimpleCompilation(module, MinimalCorlib.Instance); : new SimpleCompilation((PEFile)module, MinimalCorlib.Instance);
return memberRef == null return memberRef == null
? typeRef.Resolve(new SimpleTypeResolveContext(compilation)) as ITypeDefinition ? typeRef.Resolve(new SimpleTypeResolveContext(compilation)) as ITypeDefinition
: (IEntity)memberRef.Resolve(new SimpleTypeResolveContext(compilation)); : (IEntity)memberRef.Resolve(new SimpleTypeResolveContext(compilation));
@ -824,9 +824,9 @@ namespace ICSharpCode.ILSpy
return null; return null;
} }
static bool CanResolveTypeInPEFile(PEFile module, ITypeReference typeRef, out EntityHandle typeHandle) static bool CanResolveTypeInPEFile(MetadataFile module, ITypeReference typeRef, out EntityHandle typeHandle)
{ {
if (module == null) if (module is not PEFile)
{ {
typeHandle = default; typeHandle = default;
return false; return false;
@ -1259,7 +1259,7 @@ namespace ICSharpCode.ILSpy
{ {
case LoadedAssembly lasm: case LoadedAssembly lasm:
return assemblyListTreeNode.FindAssemblyNode(lasm); return assemblyListTreeNode.FindAssemblyNode(lasm);
case PEFile asm: case MetadataFile asm:
return assemblyListTreeNode.FindAssemblyNode(asm); return assemblyListTreeNode.FindAssemblyNode(asm);
case Resource res: case Resource res:
return assemblyListTreeNode.FindResourceNode(res); return assemblyListTreeNode.FindResourceNode(res);

2
ILSpy/Metadata/DebugDirectoryTreeNode.cs

@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy.Metadata
case DebugDirectoryEntryType.EmbeddedPortablePdb: case DebugDirectoryEntryType.EmbeddedPortablePdb:
var embeddedPortablePdbProvider = module.Reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry); var embeddedPortablePdbProvider = module.Reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry);
var embeddedPortablePdbMetadataFile = new MetadataFile(module.FileName, embeddedPortablePdbProvider, isEmbedded: true); var embeddedPortablePdbMetadataFile = new MetadataFile(MetadataFile.MetadataFileKind.ProgramDebugDatabase, module.FileName, embeddedPortablePdbProvider, isEmbedded: true);
this.Children.Add(new MetadataTreeNode(embeddedPortablePdbMetadataFile, "Debug Metadata (Embedded)")); this.Children.Add(new MetadataTreeNode(embeddedPortablePdbMetadataFile, "Debug Metadata (Embedded)"));
break; break;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save