Browse Source

Merge pull request #3184 from icsharpcode/webcil

Add minimal WebCIL support
pull/3186/head
Siegfried Pammer 1 year ago committed by GitHub
parent
commit
3ebeb7d86c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  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. 2
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs
  7. 37
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs
  8. 28
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs
  9. 10
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs
  10. 32
      ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
  11. 2
      ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs
  12. 7
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs
  13. 2
      ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs
  14. 7
      ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs
  15. 4
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  16. 6
      ICSharpCode.Decompiler/DecompilerException.cs
  17. 8
      ICSharpCode.Decompiler/Disassembler/ILStructure.cs
  18. 19
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  19. 117
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  20. 2
      ICSharpCode.Decompiler/Documentation/GetPotentiallyNestedClassTypeReference.cs
  21. 4
      ICSharpCode.Decompiler/Documentation/XmlDocLoader.cs
  22. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  23. 6
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  24. 4
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs
  25. 2
      ICSharpCode.Decompiler/IL/ILReader.cs
  26. 2
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  27. 2
      ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs
  28. 12
      ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
  29. 2
      ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs
  30. 8
      ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs
  31. 8
      ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs
  32. 10
      ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs
  33. 4
      ICSharpCode.Decompiler/Metadata/CodeMappingInfo.cs
  34. 16
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs
  35. 10
      ICSharpCode.Decompiler/Metadata/EnumUnderlyingTypeResolveException.cs
  36. 8
      ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs
  37. 39
      ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
  38. 332
      ICSharpCode.Decompiler/Metadata/MetadataFile.cs
  39. 2
      ICSharpCode.Decompiler/Metadata/MetadataGenericContext.cs
  40. 260
      ICSharpCode.Decompiler/Metadata/PEFile.cs
  41. 19
      ICSharpCode.Decompiler/Metadata/Resource.cs
  42. 10
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  43. 284
      ICSharpCode.Decompiler/Metadata/WebCilFile.cs
  44. 2
      ICSharpCode.Decompiler/NRExtensions.cs
  45. 17
      ICSharpCode.Decompiler/SRMExtensions.cs
  46. 8
      ICSharpCode.Decompiler/SingleFileBundle.cs
  47. 20
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  48. 2
      ICSharpCode.Decompiler/TypeSystem/IAssembly.cs
  49. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs
  50. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs
  51. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  52. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs
  53. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs
  54. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs
  55. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs
  56. 12
      ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs
  57. 4
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  58. 2
      ICSharpCode.ILSpyX/Abstractions/ILanguage.cs
  59. 2
      ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs
  60. 28
      ICSharpCode.ILSpyX/AssemblyListSnapshot.cs
  61. 74
      ICSharpCode.ILSpyX/LoadedAssembly.cs
  62. 10
      ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs
  63. 20
      ICSharpCode.ILSpyX/LoadedPackage.cs
  64. 5
      ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs
  65. 4
      ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs
  66. 2
      ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs
  67. 7
      ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs
  68. 8
      ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs
  69. 3
      ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs
  70. 3
      ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs
  71. 6
      ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs
  72. 7
      ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs
  73. 8
      ICSharpCode.ILSpyX/Search/SearchResult.cs
  74. 2
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  75. 2
      ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
  76. 43
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  77. 9
      ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
  78. 8
      ILSpy/Analyzers/AnalyzerContext.cs
  79. 4
      ILSpy/Analyzers/AnalyzerEntityTreeNode.cs
  80. 6
      ILSpy/Analyzers/AnalyzerHelpers.cs
  81. 28
      ILSpy/Analyzers/AnalyzerScope.cs
  82. 6
      ILSpy/Analyzers/Builtin/EventImplementedByAnalyzer.cs
  83. 6
      ILSpy/Analyzers/Builtin/EventOverriddenByAnalyzer.cs
  84. 13
      ILSpy/Analyzers/Builtin/FieldAccessAnalyzer.cs
  85. 6
      ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs
  86. 6
      ILSpy/Analyzers/Builtin/MethodImplementedByAnalyzer.cs
  87. 6
      ILSpy/Analyzers/Builtin/MethodOverriddenByAnalyzer.cs
  88. 10
      ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs
  89. 10
      ILSpy/Analyzers/Builtin/MethodUsesAnalyzer.cs
  90. 6
      ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs
  91. 6
      ILSpy/Analyzers/Builtin/PropertyImplementedByAnalyzer.cs
  92. 6
      ILSpy/Analyzers/Builtin/PropertyOverriddenByAnalyzer.cs
  93. 2
      ILSpy/Analyzers/Builtin/TypeExposedByAnalyzer.cs
  94. 2
      ILSpy/Analyzers/Builtin/TypeExtensionMethodsAnalyzer.cs
  95. 4
      ILSpy/Analyzers/Builtin/TypeInstantiatedByAnalyzer.cs
  96. 10
      ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs
  97. 4
      ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs
  98. 3
      ILSpy/Commands/GeneratePdbContextMenuEntry.cs
  99. 26
      ILSpy/Commands/IProtocolHandler.cs
  100. 2
      ILSpy/EntityReference.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 @@ -59,7 +59,7 @@ namespace ICSharpCode.BamlDecompiler.Baml
}
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 @@ -40,7 +40,7 @@ namespace ICSharpCode.BamlDecompiler
"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)
throw new ArgumentNullException(nameof(mainModule));
@ -48,8 +48,8 @@ namespace ICSharpCode.BamlDecompiler @@ -48,8 +48,8 @@ namespace ICSharpCode.BamlDecompiler
throw new ArgumentNullException(nameof(assemblyResolver));
// Load referenced assemblies and type-forwarder references.
// This is necessary to make .NET Core/PCL binaries work better.
var referencedAssemblies = new List<PEFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference)>();
var referencedAssemblies = new List<MetadataFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, MetadataFile MainModule, object Reference)>();
var mainMetadata = mainModule.Metadata;
foreach (var h in mainMetadata.GetModuleReferences())
{
@ -73,16 +73,16 @@ namespace ICSharpCode.BamlDecompiler @@ -73,16 +73,16 @@ namespace ICSharpCode.BamlDecompiler
{
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 :
"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)
{
var asmRef = assemblyReferenceQueue.Dequeue();
if (!processedAssemblyReferences.Add(asmRef))
continue;
PEFile asm;
MetadataFile asm;
if (asmRef.IsAssembly)
{
asm = assemblyResolver.Resolve((IAssemblyReference)asmRef.Reference);

6
ICSharpCode.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs

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

3
ICSharpCode.Decompiler.PowerShell/GetDecompiledProjectCmdlet.cs

@ -1,5 +1,4 @@ @@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Management.Automation;
using System.Threading;
@ -89,7 +88,7 @@ namespace ICSharpCode.Decompiler.PowerShell @@ -89,7 +88,7 @@ namespace ICSharpCode.Decompiler.PowerShell
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());
WholeProjectDecompiler decompiler = new WholeProjectDecompiler(assemblyResolver);
decompiler.ProgressIndicator = this;

28
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -251,7 +251,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -251,7 +251,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// <summary>
/// Creates a new <see cref="CSharpDecompiler"/> instance from the given <paramref name="module"/> using the given <paramref name="assemblyResolver"/> and <paramref name="settings"/>.
/// </summary>
public CSharpDecompiler(PEFile module, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
public CSharpDecompiler(MetadataFile module, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
: this(new DecompilerTypeSystem(module, assemblyResolver, settings), settings)
{
}
@ -264,7 +264,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -264,7 +264,7 @@ namespace ICSharpCode.Decompiler.CSharp
this.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));
this.settings = settings;
this.module = typeSystem.MainModule;
this.metadata = module.PEFile.Metadata;
this.metadata = module.MetadataFile.Metadata;
if (module.TypeSystemOptions.HasFlag(TypeSystemOptions.Uncached))
throw new ArgumentException("Cannot use an uncached type system in the decompiler.");
}
@ -276,7 +276,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -276,7 +276,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// <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="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)
return false;
@ -539,7 +539,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -539,7 +539,7 @@ namespace ICSharpCode.Decompiler.CSharp
{
try
{
return XmlDocLoader.LoadDocumentation(module.PEFile);
return XmlDocLoader.LoadDocumentation(module.MetadataFile);
}
catch (System.Xml.XmlException)
{
@ -633,7 +633,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -633,7 +633,7 @@ namespace ICSharpCode.Decompiler.CSharp
var typeDef = module.GetDefinition(typeDefHandle);
if (typeDef.Name == "<Module>" && typeDef.Members.Count == 0)
continue;
if (MemberIsHidden(module.PEFile, typeDefHandle, settings))
if (MemberIsHidden(module.MetadataFile, typeDefHandle, settings))
continue;
if (string.IsNullOrEmpty(typeDef.Namespace))
{
@ -702,7 +702,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -702,7 +702,7 @@ namespace ICSharpCode.Decompiler.CSharp
/// <summary>
/// Determines the "code-mappings" for a given TypeDef or MethodDef. See <see cref="CodeMappingInfo"/> for more information.
/// </summary>
public static CodeMappingInfo GetCodeMappingInfo(PEFile module, EntityHandle member)
public static CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)
{
var declaringType = (TypeDefinitionHandle)member.GetDeclaringType(module.Metadata);
@ -744,7 +744,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -744,7 +744,7 @@ namespace ICSharpCode.Decompiler.CSharp
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);
@ -756,7 +756,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -756,7 +756,7 @@ namespace ICSharpCode.Decompiler.CSharp
var declaringType = md.GetDeclaringType();
var blob = module.Reader.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
var blob = module.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
while (blob.RemainingBytes > 0)
{
var code = blob.DecodeOpCode();
@ -1357,7 +1357,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1357,7 +1357,7 @@ namespace ICSharpCode.Decompiler.CSharp
// Decompile members that are not compiler-generated.
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;
}
@ -1403,7 +1403,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1403,7 +1403,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (typeDecl.ClassType == ClassType.Enum)
{
Debug.Assert(typeDef.Kind == TypeKind.Enum);
EnumValueDisplayMode displayMode = DetectBestEnumValueDisplayMode(typeDef, module.PEFile);
EnumValueDisplayMode displayMode = DetectBestEnumValueDisplayMode(typeDef, module.MetadataFile);
switch (displayMode)
{
case EnumValueDisplayMode.FirstOnly:
@ -1532,7 +1532,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -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))
return EnumValueDisplayMode.AllHex;
@ -1608,7 +1608,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1608,7 +1608,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
FixParameterNames(methodDecl);
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,
// reduce the visibility of the method to private,
@ -1701,7 +1701,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1701,7 +1701,7 @@ namespace ICSharpCode.Decompiler.CSharp
MethodBodyBlock methodBody;
try
{
methodBody = module.PEFile.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
methodBody = module.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
}
catch (BadImageFormatException ex)
{
@ -1980,7 +1980,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1980,7 +1980,7 @@ namespace ICSharpCode.Decompiler.CSharp
string message;
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('-', ' '));
}
catch (BadImageFormatException ex)

2
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs

@ -36,6 +36,6 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -36,6 +36,6 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
/// <param name="project">The information about the project being created.</param>
/// <param name="files">A collection of source files to be included into the project.</param>
/// <param name="module">The module being decompiled.</param>
void Write(TextWriter target, IProjectInfoProvider project, IEnumerable<ProjectItemInfo> files, PEFile module);
void Write(TextWriter target, IProjectInfoProvider project, IEnumerable<ProjectItemInfo> files, MetadataFile module);
}
}

37
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs

@ -45,10 +45,10 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -45,10 +45,10 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
TextWriter target,
IProjectInfoProvider project,
IEnumerable<ProjectItemInfo> files,
PEFile module)
MetadataFile module)
{
const string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
string platformName = TargetServices.GetPlatformName(module);
string platformName = module is PEFile peFile ? TargetServices.GetPlatformName(peFile) : "AnyCPU";
var targetFramework = TargetServices.DetectTargetFramework(module);
if (targetFramework.Identifier == ".NETFramework" && targetFramework.VersionNumber == 200)
targetFramework = TargetServices.DetectTargetFrameworkNET20(module, project.AssemblyResolver, targetFramework);
@ -80,26 +80,22 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -80,26 +80,22 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
w.WriteValue(platformName);
w.WriteEndElement(); // </Platform>
if (module.Reader.PEHeaders.IsDll)
{
w.WriteElementString("OutputType", "Library");
}
else
string outputType;
switch ((module as PEFile)?.Reader.PEHeaders.PEHeader.Subsystem)
{
switch (module.Reader.PEHeaders.PEHeader.Subsystem)
{
case Subsystem.WindowsGui:
w.WriteElementString("OutputType", "WinExe");
break;
case Subsystem.WindowsCui:
w.WriteElementString("OutputType", "Exe");
break;
default:
w.WriteElementString("OutputType", "Library");
break;
}
case Subsystem.WindowsGui:
outputType = "WinExe";
break;
case Subsystem.WindowsCui:
outputType = "Exe";
break;
default:
outputType = "Library";
break;
}
w.WriteElementString("OutputType", outputType);
w.WriteElementString("LangVersion", project.LanguageVersion.ToString().Replace("CSharp", "").Replace('_', '.'));
w.WriteElementString("AssemblyName", module.Name);
@ -123,7 +119,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -123,7 +119,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
w.WriteStartElement("PropertyGroup"); // platform-specific
w.WriteAttributeString("Condition", " '$(Platform)' == '" + platformName + "' ");
w.WriteElementString("PlatformTarget", platformName);
if (targetFramework.VersionNumber > 400 && platformName == "AnyCPU" && (module.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) == 0)
if (targetFramework.VersionNumber > 400 && platformName == "AnyCPU"
&& ((module as PEFile)?.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) == 0)
{
w.WriteElementString("Prefer32Bit", "false");
}

28
ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs

@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
TextWriter target,
IProjectInfoProvider project,
IEnumerable<ProjectItemInfo> files,
PEFile module)
MetadataFile module)
{
using (XmlTextWriter xmlWriter = new XmlTextWriter(target))
{
@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
}
static void Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable<ProjectItemInfo> files, PEFile module)
static void Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable<ProjectItemInfo> files, MetadataFile module)
{
xml.WriteStartElement("Project");
@ -105,18 +105,30 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -105,18 +105,30 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
}
static void WriteAssemblyInfo(XmlTextWriter xml, PEFile module, IProjectInfoProvider project, ProjectType projectType)
static void WriteAssemblyInfo(XmlTextWriter xml, MetadataFile module, IProjectInfoProvider project, ProjectType projectType)
{
xml.WriteElementString("AssemblyName", module.Name);
// Since we create AssemblyInfo.cs manually, we need to disable the auto-generation
xml.WriteElementString("GenerateAssemblyInfo", FalseString);
WriteOutputType(xml, module.Reader.PEHeaders.IsDll, module.Reader.PEHeaders.PEHeader.Subsystem, projectType);
string platformName;
CorFlags flags;
if (module is PEFile { Reader.PEHeaders: var headers } peFile)
{
WriteOutputType(xml, headers.IsDll, headers.PEHeader.Subsystem, projectType);
platformName = TargetServices.GetPlatformName(peFile);
flags = headers.CorHeader.Flags;
}
else
{
WriteOutputType(xml, isDll: true, Subsystem.Unknown, projectType);
platformName = AnyCpuString;
flags = 0;
}
WriteDesktopExtensions(xml, projectType);
string platformName = TargetServices.GetPlatformName(module);
var targetFramework = TargetServices.DetectTargetFramework(module);
if (targetFramework.Identifier == ".NETFramework" && targetFramework.VersionNumber == 200)
targetFramework = TargetServices.DetectTargetFrameworkNET20(module, project.AssemblyResolver, targetFramework);
@ -134,7 +146,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -134,7 +146,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
xml.WriteElementString("PlatformTarget", platformName);
}
if (platformName == AnyCpuString && (module.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) != 0)
if (platformName == AnyCpuString && (flags & CorFlags.Prefers32Bit) != 0)
{
xml.WriteElementString("Prefer32Bit", TrueString);
}
@ -238,7 +250,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -238,7 +250,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
}
static void WriteReferences(XmlTextWriter xml, PEFile module, IProjectInfoProvider project, ProjectType projectType)
static void WriteReferences(XmlTextWriter xml, MetadataFile module, IProjectInfoProvider project, ProjectType projectType)
{
bool isNetCoreApp = TargetServices.DetectTargetFramework(module).Identifier == ".NETCoreApp";
var targetPacks = new HashSet<string>();
@ -292,7 +304,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -292,7 +304,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
}
static ProjectType GetProjectType(PEFile module)
static ProjectType GetProjectType(MetadataFile module)
{
foreach (var referenceName in module.AssemblyReferences.Select(r => r.Name))
{

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

@ -39,7 +39,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -39,7 +39,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
/// <param name="module">The module to get the target framework description for. Cannot be null.</param>
/// <returns>A new instance of the <see cref="TargetFramework"/> class that describes the specified <paramref name="module"/>.
/// </returns>
public static TargetFramework DetectTargetFramework(PEFile module)
public static TargetFramework DetectTargetFramework(MetadataFile module)
{
if (module is null)
{
@ -216,9 +216,9 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -216,9 +216,9 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
};
/// <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>
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>();
int version = 200;
@ -226,7 +226,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -226,7 +226,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
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)
{
@ -245,7 +245,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -245,7 +245,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
break;
}
PEFile resolvedReference;
MetadataFile resolvedReference;
try
{
resolvedReference = assemblyResolver.Resolve(reference);

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

@ -37,8 +37,6 @@ using ICSharpCode.Decompiler.Solution; @@ -37,8 +37,6 @@ using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using Microsoft.Win32;
using static ICSharpCode.Decompiler.Metadata.MetadataExtensions;
namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
@ -133,16 +131,16 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -133,16 +131,16 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
HashSet<string> directories = new HashSet<string>(Platform.FileNameComparer);
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");
string projectFileName = Path.Combine(targetDirectory, CleanUpFileName(file.Name) + ".csproj");
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 (string.IsNullOrEmpty(targetDirectory))
{
@ -150,23 +148,27 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -150,23 +148,27 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
TargetDirectory = targetDirectory;
directories.Clear();
var resources = WriteResourceFilesInProject(moduleDefinition).ToList();
var files = WriteCodeFilesInProject(moduleDefinition, resources.SelectMany(r => r.PartialTypes ?? Enumerable.Empty<PartialTypeInfo>()).ToList(), cancellationToken).ToList();
var resources = WriteResourceFilesInProject(file).ToList();
var files = WriteCodeFilesInProject(file, resources.SelectMany(r => r.PartialTypes ?? Enumerable.Empty<PartialTypeInfo>()).ToList(), cancellationToken).ToList();
files.AddRange(resources);
files.AddRange(WriteMiscellaneousFilesInProject(moduleDefinition));
var module = file as PEFile;
if (module != null)
{
files.AddRange(WriteMiscellaneousFilesInProject(module));
}
if (StrongNameKeyFile != null)
{
File.Copy(StrongNameKeyFile, Path.Combine(targetDirectory, Path.GetFileName(StrongNameKeyFile)), overwrite: true);
}
projectWriter.Write(projectFileWriter, this, files, moduleDefinition);
projectWriter.Write(projectFileWriter, this, files, file);
string platformName = TargetServices.GetPlatformName(moduleDefinition);
string platformName = module != null ? TargetServices.GetPlatformName(module) : "AnyCPU";
return new ProjectId(platformName, ProjectGuid, ProjectTypeGuids.CSharpWindows);
}
#region WriteCodeFilesInProject
protected virtual bool IncludeTypeWhenDecompilingProject(PEFile module, TypeDefinitionHandle type)
protected virtual bool IncludeTypeWhenDecompilingProject(MetadataFile module, TypeDefinitionHandle type)
{
var metadata = module.Metadata;
var typeDef = metadata.GetTypeDefinition(type);
@ -208,7 +210,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -208,7 +210,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
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 files = module.Metadata.GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td))
@ -306,7 +308,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -306,7 +308,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
#endregion
#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))
{
@ -758,7 +760,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler @@ -758,7 +760,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
}
}
public static bool CanUseSdkStyleProjectFormat(PEFile module)
public static bool CanUseSdkStyleProjectFormat(MetadataFile module)
{
return TargetServices.DetectTargetFramework(module).Moniker != null;
}

2
ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

@ -1100,7 +1100,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1100,7 +1100,7 @@ namespace ICSharpCode.Decompiler.CSharp
var genericContext = new GenericContext(
classTypeParameters: recordTypeDef.TypeParameters,
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 il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken);
var settings = new DecompilerSettings(LanguageVersion.CSharp1);

7
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

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

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

@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
IMethod ctorMethod = staticCtor.GetSymbol() as IMethod;
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.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType());
bool declaringTypeIsBeforeFieldInit = declaringType.HasFlag(TypeAttributes.BeforeFieldInit);

7
ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs

@ -19,15 +19,12 @@ @@ -19,15 +19,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -231,11 +228,11 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -231,11 +228,11 @@ namespace ICSharpCode.Decompiler.DebugInfo
this.functions.Add(function);
var method = function.MoveNextMethod ?? function.Method;
MethodDefinitionHandle handle = (MethodDefinitionHandle)method.MetadataToken;
var file = typeSystem.MainModule.PEFile;
var file = typeSystem.MainModule.MetadataFile;
MethodDefinition md = file.Metadata.GetMethodDefinition(handle);
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; @@ -26,10 +26,8 @@ using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Runtime;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
@ -49,7 +47,7 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -49,7 +47,7 @@ namespace ICSharpCode.Decompiler.DebugInfo
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)

6
ICSharpCode.Decompiler/DecompilerException.cs

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

8
ICSharpCode.Decompiler/Disassembler/ILStructure.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary>
public class ILStructure
{
public readonly PEFile Module;
public readonly MetadataFile Module;
public readonly MethodDefinitionHandle MethodHandle;
public readonly MetadataGenericContext GenericContext;
public readonly ILStructureType Type;
@ -88,7 +88,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -88,7 +88,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary>
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)
{
// Build the tree of exception structures:
@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Disassembler
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);
this.Module = module;
@ -154,7 +154,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -154,7 +154,7 @@ namespace ICSharpCode.Decompiler.Disassembler
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);
this.Module = module;

19
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -72,7 +72,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -72,7 +72,7 @@ namespace ICSharpCode.Decompiler.Disassembler
int nextSequencePointIndex;
// cache info
PEFile module;
MetadataFile module;
MetadataReader metadata;
MetadataGenericContext genericContext;
DisassemblerSignatureTypeProvider signatureDecoder;
@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.Disassembler
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));
metadata = module.Metadata;
@ -105,8 +105,8 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -105,8 +105,8 @@ namespace ICSharpCode.Decompiler.Disassembler
BlobReader bodyBlockReader;
try
{
body = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress);
bodyBlockReader = module.Reader.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader();
body = module.GetMethodBody(methodDefinition.RelativeVirtualAddress);
bodyBlockReader = module.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader();
}
catch (BadImageFormatException ex)
{
@ -119,7 +119,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -119,7 +119,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine("// Code size: {0} (0x{0:x})", blob.Length);
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)
output.WriteLine(".entrypoint");
@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.Disassembler
while (blob.RemainingBytes > 0)
{
cancellationToken.ThrowIfCancellationRequested();
WriteInstruction(output, metadata, handle, ref blob, methodDefinition.RelativeVirtualAddress);
WriteInstruction(output, module, handle, ref blob, methodDefinition.RelativeVirtualAddress);
}
WriteExceptionHandlers(module, handle, body);
}
@ -195,7 +195,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -195,7 +195,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine(")");
}
internal void WriteExceptionHandlers(PEFile module, MethodDefinitionHandle handle, MethodBodyBlock body)
internal void WriteExceptionHandlers(MetadataFile module, MethodDefinitionHandle handle, MethodBodyBlock body)
{
this.module = module;
metadata = module.Metadata;
@ -291,7 +291,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -291,7 +291,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
var currentOpCode = ILParser.DecodeOpCode(ref body);
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()
|| currentOpCode.IsReturn()
|| currentOpCode == ILOpCode.Throw
@ -324,8 +324,9 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -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;
if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count)
{

117
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -143,7 +143,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -143,7 +143,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ MethodImplAttributes.AggressiveInlining, "aggressiveinlining" },
};
public void DisassembleMethod(PEFile module, MethodDefinitionHandle handle)
public void DisassembleMethod(MetadataFile module, MethodDefinitionHandle handle)
{
var genericContext = new MetadataGenericContext(handle, module);
// write method header
@ -153,7 +153,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -153,7 +153,7 @@ namespace ICSharpCode.Decompiler.Disassembler
DisassembleMethodBlock(module, handle, genericContext);
}
public void DisassembleMethodHeader(PEFile module, MethodDefinitionHandle handle)
public void DisassembleMethodHeader(MetadataFile module, MethodDefinitionHandle handle)
{
var genericContext = new MetadataGenericContext(handle, module);
// write method header
@ -162,7 +162,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -162,7 +162,7 @@ namespace ICSharpCode.Decompiler.Disassembler
DisassembleMethodHeaderInternal(module, handle, genericContext);
}
void DisassembleMethodHeaderInternal(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext)
void DisassembleMethodHeaderInternal(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext)
{
var metadata = module.Metadata;
@ -310,7 +310,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -310,7 +310,7 @@ namespace ICSharpCode.Decompiler.Disassembler
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)
{
// 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 @@ -344,7 +344,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
void DisassembleMethodBlock(PEFile module, MethodDefinitionHandle handle,
void DisassembleMethodBlock(MetadataFile module, MethodDefinitionHandle handle,
MetadataGenericContext genericContext)
{
var metadata = module.Metadata;
@ -380,7 +380,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -380,7 +380,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
#region Write Security Declarations
void WriteSecurityDeclarations(PEFile module, DeclarativeSecurityAttributeHandleCollection secDeclProvider)
void WriteSecurityDeclarations(MetadataFile module, DeclarativeSecurityAttributeHandleCollection secDeclProvider)
{
if (secDeclProvider.Count == 0)
return;
@ -479,9 +479,9 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -479,9 +479,9 @@ namespace ICSharpCode.Decompiler.Disassembler
{
readonly ITextOutput output;
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.resolver = resolver;
@ -535,11 +535,11 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -535,11 +535,11 @@ namespace ICSharpCode.Decompiler.Disassembler
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[] typeNameParts = nameParts[0].Split('.');
PEFile containingModule = null;
MetadataFile containingModule = null;
TypeDefinitionHandle typeDefHandle = default;
// if we deal with an assembly-qualified name, resolve the assembly
if (nameParts.Length == 2)
@ -564,7 +564,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -564,7 +564,7 @@ namespace ICSharpCode.Decompiler.Disassembler
return (containingModule, typeDefHandle);
TypeDefinitionHandle FindType(PEFile currentModule, string[] name)
TypeDefinitionHandle FindType(MetadataFile currentModule, string[] name)
{
var metadata = currentModule.Metadata;
var currentNamespace = metadata.GetNamespaceDefinitionRoot();
@ -618,9 +618,9 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -618,9 +618,9 @@ namespace ICSharpCode.Decompiler.Disassembler
return typeCode;
}
PEFile mscorlib;
MetadataFile mscorlib;
bool TryResolveMscorlib(out PEFile mscorlib)
bool TryResolveMscorlib(out MetadataFile mscorlib)
{
mscorlib = null;
if (this.mscorlib != null)
@ -637,7 +637,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -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.Indent();
@ -1134,7 +1134,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1134,7 +1134,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine();
}
void WriteGenericParametersAndAttributes(PEFile module, MetadataGenericContext context, GenericParameterHandle handle)
void WriteGenericParametersAndAttributes(MetadataFile module, MetadataGenericContext context, GenericParameterHandle handle)
{
var metadata = module.Metadata;
var p = metadata.GetGenericParameter(handle);
@ -1161,7 +1161,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -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 p = metadata.GetParameter(handle);
@ -1247,7 +1247,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1247,7 +1247,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ FieldAttributes.NotSerialized, "notserialized" },
};
public void DisassembleField(PEFile module, FieldDefinitionHandle handle)
public void DisassembleField(MetadataFile module, FieldDefinitionHandle handle)
{
var metadata = module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(handle);
@ -1264,7 +1264,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1264,7 +1264,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{
// Field data as specified in II.16.3.1 of ECMA-335 6th edition
int rva = fieldDefinition.GetRelativeVirtualAddress();
int sectionIndex = module.Reader.PEHeaders.GetContainingSectionIndex(rva);
int sectionIndex = module.GetContainingSectionIndex(rva);
if (sectionIndex < 0)
{
output.WriteLine($"// RVA {rva:X8} invalid (not in any section)");
@ -1274,7 +1274,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1274,7 +1274,7 @@ namespace ICSharpCode.Decompiler.Disassembler
BlobReader initVal;
try
{
initVal = fieldDefinition.GetInitialValue(module.Reader, null);
initVal = fieldDefinition.GetInitialValue(module, null);
}
catch (BadImageFormatException ex)
{
@ -1283,7 +1283,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1283,7 +1283,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
if (initVal.Length > 0)
{
var sectionHeader = module.Reader.PEHeaders.SectionHeaders[sectionIndex];
var sectionHeader = module.SectionHeaders[sectionIndex];
output.Write(".data ");
if (sectionHeader.Name == ".text")
{
@ -1293,7 +1293,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1293,7 +1293,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{
output.Write("tls ");
}
else if (sectionHeader.Name != ".data")
else if (sectionHeader.Name is not (null or ".data"))
{
output.Write($"/* {sectionHeader.Name} */ ");
}
@ -1305,14 +1305,14 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -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 fieldDefinition = metadata.GetFieldDefinition(handle);
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);
WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),
@ -1342,7 +1342,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1342,7 +1342,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (fieldDefinition.HasFlag(FieldAttributes.HasFieldRVA))
{
int rva = fieldDefinition.GetRelativeVirtualAddress();
sectionPrefix = GetRVASectionPrefix(module.Reader.PEHeaders, rva);
sectionPrefix = GetRVASectionPrefix(module, rva);
output.Write(" at {1}_{0:X8}", rva, sectionPrefix);
}
@ -1356,12 +1356,14 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1356,12 +1356,14 @@ namespace ICSharpCode.Decompiler.Disassembler
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)
return 'D';
var sectionHeader = headers.SectionHeaders[sectionIndex];
var sectionHeader = peFile.Reader.PEHeaders.SectionHeaders[sectionIndex];
switch (sectionHeader.Name)
{
case ".tls":
@ -1381,7 +1383,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1381,7 +1383,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ PropertyAttributes.HasDefault, "hasdefault" },
};
public void DisassembleProperty(PEFile module, PropertyDefinitionHandle property)
public void DisassembleProperty(MetadataFile module, PropertyDefinitionHandle property)
{
var metadata = module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property);
@ -1398,14 +1400,14 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1398,14 +1400,14 @@ namespace ICSharpCode.Decompiler.Disassembler
CloseBlock();
}
public void DisassemblePropertyHeader(PEFile module, PropertyDefinitionHandle property)
public void DisassemblePropertyHeader(MetadataFile module, PropertyDefinitionHandle property)
{
var metadata = module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property);
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);
WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),
@ -1436,7 +1438,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1436,7 +1438,7 @@ namespace ICSharpCode.Decompiler.Disassembler
return accessors;
}
void WriteNestedMethod(string keyword, PEFile module, MethodDefinitionHandle method)
void WriteNestedMethod(string keyword, MetadataFile module, MethodDefinitionHandle method)
{
if (method.IsNil)
return;
@ -1454,7 +1456,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1454,7 +1456,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ EventAttributes.RTSpecialName, "rtspecialname" },
};
public void DisassembleEvent(PEFile module, EventDefinitionHandle handle)
public void DisassembleEvent(MetadataFile module, EventDefinitionHandle handle)
{
var eventDefinition = module.Metadata.GetEventDefinition(handle);
var accessors = eventDefinition.GetAccessors();
@ -1471,14 +1473,14 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1471,14 +1473,14 @@ namespace ICSharpCode.Decompiler.Disassembler
CloseBlock();
}
public void DisassembleEventHeader(PEFile module, EventDefinitionHandle handle)
public void DisassembleEventHeader(MetadataFile module, EventDefinitionHandle handle)
{
var eventDefinition = module.Metadata.GetEventDefinition(handle);
var accessors = eventDefinition.GetAccessors();
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;
if (!accessors.Adder.IsNil)
@ -1555,7 +1557,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1555,7 +1557,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ TypeAttributes.HasSecurity, null },
};
public void DisassembleType(PEFile module, TypeDefinitionHandle type)
public void DisassembleType(MetadataFile module, TypeDefinitionHandle type)
{
var typeDefinition = module.Metadata.GetTypeDefinition(type);
MetadataGenericContext genericContext = new MetadataGenericContext(type, module);
@ -1676,14 +1678,14 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1676,14 +1678,14 @@ namespace ICSharpCode.Decompiler.Disassembler
isInType = oldIsInType;
}
public void DisassembleTypeHeader(PEFile module, TypeDefinitionHandle type)
public void DisassembleTypeHeader(MetadataFile module, TypeDefinitionHandle type)
{
var typeDefinition = module.Metadata.GetTypeDefinition(type);
MetadataGenericContext genericContext = new MetadataGenericContext(type, module);
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);
WriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),
@ -1712,7 +1714,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -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)
{
@ -1765,37 +1767,37 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1765,37 +1767,37 @@ namespace ICSharpCode.Decompiler.Disassembler
#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;
}
private IReadOnlyCollection<TypeDefinitionHandle> Process(PEFile module, IReadOnlyCollection<TypeDefinitionHandle> items)
private IReadOnlyCollection<TypeDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<TypeDefinitionHandle> 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;
}
private IReadOnlyCollection<PropertyDefinitionHandle> Process(PEFile module, IReadOnlyCollection<PropertyDefinitionHandle> items)
private IReadOnlyCollection<PropertyDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<PropertyDefinitionHandle> 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;
}
private IReadOnlyCollection<FieldDefinitionHandle> Process(PEFile module, IReadOnlyCollection<FieldDefinitionHandle> items)
private IReadOnlyCollection<FieldDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<FieldDefinitionHandle> 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;
}
@ -1804,7 +1806,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1804,7 +1806,7 @@ namespace ICSharpCode.Decompiler.Disassembler
#region Helper methods
void WriteAttributes(PEFile module, CustomAttributeHandleCollection attributes)
void WriteAttributes(MetadataFile module, CustomAttributeHandleCollection attributes)
{
var metadata = module.Metadata;
foreach (CustomAttributeHandle a in Process(module, attributes))
@ -1931,7 +1933,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1931,7 +1933,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
#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))
{
@ -1953,7 +1955,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1953,7 +1955,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
public void WriteAssemblyHeader(PEFile module)
public void WriteAssemblyHeader(MetadataFile module)
{
var metadata = module.Metadata;
if (!metadata.IsAssembly)
@ -2016,7 +2018,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -2016,7 +2018,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
public void WriteModuleHeader(PEFile module, bool skipMVID = false)
public void WriteModuleHeader(MetadataFile module, bool skipMVID = false)
{
var metadata = module.Metadata;
@ -2083,17 +2085,20 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -2083,17 +2085,20 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine("// MVID: {0}", metadata.GetGuid(moduleDefinition.Mvid).ToString("B").ToUpperInvariant());
}
var headers = module.Reader.PEHeaders;
output.WriteLine(".imagebase 0x{0:x8}", headers.PEHeader.ImageBase);
output.WriteLine(".file alignment 0x{0:x8}", headers.PEHeader.FileAlignment);
output.WriteLine(".stackreserve 0x{0:x8}", headers.PEHeader.SizeOfStackReserve);
output.WriteLine(".subsystem 0x{0:x} // {1}", headers.PEHeader.Subsystem, headers.PEHeader.Subsystem.ToString());
output.WriteLine(".corflags 0x{0:x} // {1}", headers.CorHeader.Flags, headers.CorHeader.Flags.ToString());
if (module is PEFile peFile)
{
var headers = peFile.Reader.PEHeaders;
output.WriteLine(".imagebase 0x{0:x8}", headers.PEHeader.ImageBase);
output.WriteLine(".file alignment 0x{0:x8}", headers.PEHeader.FileAlignment);
output.WriteLine(".stackreserve 0x{0:x8}", headers.PEHeader.SizeOfStackReserve);
output.WriteLine(".subsystem 0x{0:x} // {1}", headers.PEHeader.Subsystem, headers.PEHeader.Subsystem.ToString());
output.WriteLine(".corflags 0x{0:x} // {1}", headers.CorHeader.Flags, headers.CorHeader.Flags.ToString());
}
WriteAttributes(module, metadata.GetCustomAttributes(EntityHandle.ModuleDefinition));
}
public void WriteModuleContents(PEFile module)
public void WriteModuleContents(MetadataFile module)
{
foreach (var handle in Process(module, module.Metadata.GetTopLevelTypeDefinitions().ToArray()))
{

2
ICSharpCode.Decompiler/Documentation/GetPotentiallyNestedClassTypeReference.cs

@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.Documentation @@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.Documentation
/// </summary>
/// <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>
public EntityHandle ResolveInPEFile(PEFile module)
public EntityHandle ResolveInPEFile(MetadataFile module)
{
string[] parts = typeName.Split('.');
for (int i = parts.Length - 1; i >= 0; i--)

4
ICSharpCode.Decompiler/Documentation/XmlDocLoader.cs

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

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -98,6 +98,7 @@ @@ -98,6 +98,7 @@
<Compile Include="Disassembler\IEntityProcessor.cs" />
<Compile Include="Disassembler\SortByNameProcessor.cs" />
<Compile Include="IL\ApplyPdbLocalTypeInfoTypeVisitor.cs" />
<Compile Include="Metadata\MetadataFile.cs" />
<Compile Include="Metadata\ModuleReferenceMetadata.cs" />
<Compile Include="NRTAttributes.cs" />
<Compile Include="PartialTypeInfo.cs" />
@ -146,6 +147,7 @@ @@ -146,6 +147,7 @@
<Compile Include="TypeSystem\ITypeDefinitionOrUnknown.cs" />
<Compile Include="Util\BitOperations.cs" />
<Compile Include="Util\Index.cs" />
<Compile Include="Metadata\WebCilFile.cs" />
<None Include="Properties\DecompilerVersionInfo.template.cs" />
<Compile Include="Semantics\OutVarResolveResult.cs" />
<Compile Include="SingleFileBundle.cs" />

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

@ -26,8 +26,8 @@ using System.Reflection.Metadata; @@ -26,8 +26,8 @@ using System.Reflection.Metadata;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL.ControlFlow
@ -53,11 +53,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -53,11 +53,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return false;
}
internal static bool IsCompilerGeneratedMainMethod(Metadata.PEFile module, MethodDefinitionHandle method)
internal static bool IsCompilerGeneratedMainMethod(MetadataFile module, MethodDefinitionHandle method)
{
var metadata = module.Metadata;
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);
}

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

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

2
ICSharpCode.Decompiler/IL/ILReader.cs

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

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

@ -189,7 +189,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -189,7 +189,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (genericContext == null)
return null;
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);
function.DelegateType = delegateType;
// 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 @@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
public DecompilerSettings Settings { get; }
public CancellationToken CancellationToken { 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 ResolvedUsingScope? UsingScope => DecompileRun?.UsingScope.Resolve(TypeSystem);

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

@ -80,7 +80,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -80,7 +80,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// 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.
if (IsLocalFunctionMethod(function.Method, context) || IsLocalFunctionDisplayClass(
function.Method.ParentModule.PEFile,
function.Method.ParentModule.MetadataFile,
(TypeDefinitionHandle)function.Method.DeclaringTypeDefinition.MetadataToken,
context)
)
@ -462,7 +462,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -462,7 +462,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
else
{
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,
genericContext.GetValueOrDefault(), ILFunctionKind.LocalFunction,
@ -755,10 +755,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -755,10 +755,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
if (method.MetadataToken.IsNil)
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)
return false;
@ -776,7 +776,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -776,7 +776,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
}
public static bool LocalFunctionNeedsAccessibilityChange(PEFile module, MethodDefinitionHandle methodHandle)
public static bool LocalFunctionNeedsAccessibilityChange(MetadataFile module, MethodDefinitionHandle methodHandle)
{
if (!IsLocalFunctionMethod(module, methodHandle))
return false;
@ -797,7 +797,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -797,7 +797,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
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)
return false;

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

@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var genericContext = new GenericContext(inst.Method);
// partially copied from CSharpDecompiler
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 transformContext = new ILTransformContext(context, proxyFunction);
proxyFunction.RunTransforms(CSharp.CSharpDecompiler.EarlyILTransforms(), transformContext);

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

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

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

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

10
ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs

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

4
ICSharpCode.Decompiler/Metadata/CodeMappingInfo.cs

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

16
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text.RegularExpressions;
using ICSharpCode.Decompiler.TypeSystem;
@ -40,7 +39,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -40,7 +39,7 @@ namespace ICSharpCode.Decompiler.Metadata
@"|(NuGetFallbackFolder[/\\](?<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);
}
@ -178,17 +177,16 @@ namespace ICSharpCode.Decompiler.Metadata @@ -178,17 +177,16 @@ namespace ICSharpCode.Decompiler.Metadata
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)
throw new ArgumentNullException(nameof(assembly));
if (metadata == null)
throw new ArgumentNullException(nameof(metadata));
var metadata = assembly.GetMetadataReader();
if (metadata.GetCustomAttributes(Handle.AssemblyDefinition).HasKnownAttribute(metadata, KnownAttribute.ReferenceAssembly))
return true;
@ -197,7 +195,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -197,7 +195,7 @@ namespace ICSharpCode.Decompiler.Metadata
return refPathMatch.Success;
}
public static string DetectRuntimePack(this PEFile assembly)
public static string DetectRuntimePack(this MetadataFile assembly)
{
if (assembly is null)
{

10
ICSharpCode.Decompiler/Metadata/EnumUnderlyingTypeResolveException.cs

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

8
ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.Metadata
{
public class FindTypeDecoder : ISignatureTypeProvider<bool, Unit>
{
readonly PEFile declaringModule;
readonly MetadataFile declaringModule;
readonly MetadataModule? currentModule;
readonly TypeDefinitionHandle handle;
readonly string? typeName;
@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -40,7 +40,7 @@ namespace ICSharpCode.Decompiler.Metadata
/// 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.
/// </summary>
internal FindTypeDecoder(TypeDefinitionHandle handle, PEFile declaringModule)
internal FindTypeDecoder(TypeDefinitionHandle handle, MetadataFile declaringModule)
{
this.handle = handle;
this.declaringModule = declaringModule;
@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.Metadata
public FindTypeDecoder(MetadataModule currentModule, ITypeDefinition type)
{
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.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode();
this.typeName = type.MetadataName;
@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -128,7 +128,7 @@ namespace ICSharpCode.Decompiler.Metadata
if (td == null)
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)

39
ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs

@ -1,6 +1,25 @@ @@ -1,6 +1,25 @@
using System;
// Copyright (c) 2018 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.
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
@ -426,5 +445,23 @@ namespace ICSharpCode.Decompiler.Metadata @@ -426,5 +445,23 @@ namespace ICSharpCode.Decompiler.Metadata
return new(metadataReader.MetadataPointer, metadataReader.MetadataLength);
}
}
public static uint ReadULEB128(this BinaryReader reader)
{
uint val = 0;
int shift = 0;
while (true)
{
byte b = reader.ReadByte();
val |= (b & 0b0111_1111u) << shift;
if ((b & 0b1000_0000) == 0)
break;
shift += 7;
if (shift >= 35)
throw new OverflowException();
}
return val;
}
}
}

332
ICSharpCode.Decompiler/Metadata/MetadataFile.cs

@ -0,0 +1,332 @@ @@ -0,0 +1,332 @@
// 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,
WebCIL,
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 @@ -43,7 +43,7 @@ namespace ICSharpCode.Decompiler.Metadata
this.declaringType = metadata.GetMethodDefinition(method).GetDeclaringType();
}
public MetadataGenericContext(TypeDefinitionHandle declaringType, PEFile module)
public MetadataGenericContext(TypeDefinitionHandle declaringType, MetadataFile module)
{
this.metadata = module.Metadata;
this.method = default;

260
ICSharpCode.Decompiler/Metadata/PEFile.cs

@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
@ -28,62 +27,11 @@ using System.Reflection.Metadata; @@ -28,62 +27,11 @@ using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
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}")]
public class PEFile : MetadataFile, IDisposable, TypeSystem.IModuleReference
public class PEFile : MetadataFile, IDisposable, IModuleReference
{
public PEReader Reader { get; }
@ -98,209 +46,59 @@ namespace ICSharpCode.Decompiler.Metadata @@ -98,209 +46,59 @@ namespace ICSharpCode.Decompiler.Metadata
}
public PEFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
: base(fileName, reader, metadataOptions)
: base(MetadataFileKind.PortableExecutable, fileName, reader, metadataOptions)
{
this.Reader = reader;
}
public bool IsAssembly => Metadata.IsAssembly;
public override bool IsEmbedded => false;
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()
{
Reader.Dispose();
}
Dictionary<TopLevelTypeName, TypeDefinitionHandle>? typeLookup;
/// <summary>
/// Finds the top-level-type with the specified name.
/// </summary>
public TypeDefinitionHandle GetTypeDefinition(TopLevelTypeName typeName)
IModule TypeSystem.IModuleReference.Resolve(ITypeResolveContext context)
{
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;
return new MetadataModule(context.Compilation, this, TypeSystemOptions.Default);
}
Dictionary<FullTypeName, ExportedTypeHandle>? typeForwarderLookup;
/// <summary>
/// Finds the type forwarder with the specified name.
/// </summary>
public ExportedTypeHandle GetTypeForwarder(FullTypeName typeName)
public override MethodBodyBlock GetMethodBody(int rva)
{
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;
return Reader.GetMethodBody(rva);
}
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 TypeSystem.IModuleReference WithOptions(TypeSystemOptions options)
public override SectionData GetSectionData(int rva)
{
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
{
readonly PEFile peFile;
readonly TypeSystemOptions options;
public PEFileWithOptions(PEFile peFile, TypeSystemOptions options)
{
this.peFile = peFile;
this.options = options;
}
IModule TypeSystem.IModuleReference.Resolve(ITypeResolveContext context)
{
return new MetadataModule(context.Compilation, peFile, options);
ImmutableArray<SectionHeader> sectionHeaders;
public override ImmutableArray<SectionHeader> SectionHeaders {
get {
var value = sectionHeaders;
if (value.IsDefault)
{
value = Reader.PEHeaders.SectionHeaders
.Select(h => new SectionHeader {
Name = h.Name,
RawDataPtr = unchecked((uint)h.PointerToRawData),
RawDataSize = unchecked((uint)h.SizeOfRawData),
VirtualAddress = unchecked((uint)h.VirtualAddress),
VirtualSize = unchecked((uint)h.VirtualSize)
}).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; @@ -23,7 +23,6 @@ using System.IO;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
namespace ICSharpCode.Decompiler.Metadata
{
@ -67,11 +66,11 @@ namespace ICSharpCode.Decompiler.Metadata @@ -67,11 +66,11 @@ namespace ICSharpCode.Decompiler.Metadata
sealed class MetadataResource : Resource
{
public PEFile Module { get; }
public MetadataFile Module { get; }
public ManifestResourceHandle Handle { get; }
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.Handle = handle;
@ -117,15 +116,13 @@ namespace ICSharpCode.Decompiler.Metadata @@ -117,15 +116,13 @@ namespace ICSharpCode.Decompiler.Metadata
// embedded resources cannot be read from this binary.
if (ResourceType != ResourceType.Embedded)
return false;
// get cor header
var headers = Module.Reader.PEHeaders;
if (headers.CorHeader == null)
if (Module.CorHeader == null)
return false;
var resources = headers.CorHeader.ResourcesDirectory;
var resources = Module.CorHeader.ResourcesDirectory;
// validate resources directory, GetSectionData throws on negative RVAs
if (resources.RelativeVirtualAddress <= 0)
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
// the actual length of the resource blob.
if (sectionData.Length < 4)
@ -144,7 +141,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -144,7 +141,7 @@ namespace ICSharpCode.Decompiler.Metadata
{
if (!TryReadResource(out var ptr, out var length))
return null;
return new ResourceMemoryStream(Module.Reader, ptr + sizeof(int), length);
return new ResourceMemoryStream(Module, ptr + sizeof(int), length);
}
public unsafe override long? TryGetLength()
@ -158,10 +155,10 @@ namespace ICSharpCode.Decompiler.Metadata @@ -158,10 +155,10 @@ namespace ICSharpCode.Decompiler.Metadata
sealed unsafe class ResourceMemoryStream : UnmanagedMemoryStream
{
#pragma warning disable IDE0052 // Remove unread private members
readonly PEReader peReader;
readonly MetadataFile peReader;
#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)
{
// Keep the PEReader alive while the stream in in use.

10
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -209,13 +209,13 @@ namespace ICSharpCode.Decompiler.Metadata @@ -209,13 +209,13 @@ namespace ICSharpCode.Decompiler.Metadata
}
#if !VSADDIN
public PEFile? Resolve(IAssemblyReference name)
public MetadataFile? Resolve(IAssemblyReference name)
{
var file = FindAssemblyFile(name);
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);
if (baseDirectory == null)
@ -224,7 +224,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -224,7 +224,7 @@ namespace ICSharpCode.Decompiler.Metadata
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)
{
@ -251,12 +251,12 @@ namespace ICSharpCode.Decompiler.Metadata @@ -251,12 +251,12 @@ namespace ICSharpCode.Decompiler.Metadata
return null;
}
public Task<PEFile?> ResolveAsync(IAssemblyReference name)
public Task<MetadataFile?> ResolveAsync(IAssemblyReference 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));
}

284
ICSharpCode.Decompiler/Metadata/WebCilFile.cs

@ -0,0 +1,284 @@ @@ -0,0 +1,284 @@
// 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.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Reflection.Metadata;
using System.Text;
using ICSharpCode.Decompiler.TypeSystem;
#nullable enable
namespace ICSharpCode.Decompiler.Metadata
{
public class WebCilFile : MetadataFile, IDisposable, IModuleReference
{
readonly MemoryMappedViewAccessor view;
readonly long webcilOffset;
private WebCilFile(string fileName, long webcilOffset, long metadataOffset, MemoryMappedViewAccessor view, ImmutableArray<SectionHeader> sectionHeaders, ImmutableArray<WasmSection> wasmSections, MetadataReaderProvider provider, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
: base(MetadataFileKind.WebCIL, fileName, provider, metadataOptions, 0)
{
this.webcilOffset = webcilOffset;
this.MetadataOffset = (int)metadataOffset;
this.view = view;
this.SectionHeaders = sectionHeaders;
this.WasmSections = wasmSections;
}
public static WebCilFile? FromStream(string fileName, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
{
using var memoryMappedFile = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open, null, 0, MemoryMappedFileAccess.Read);
var view = memoryMappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);
try
{
// read magic "\0asm"
if (view.ReadUInt32(0) != WASM_MAGIC)
return null;
// read version
if (view.ReadUInt32(4) != 1)
return null;
using var stream = view.AsStream();
using var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
stream.Position += 8;
long metadataOffset = -1;
List<WasmSection> sections = new List<WasmSection>();
while (stream.Position < stream.Length)
{
WasmSectionId id = (WasmSectionId)reader.ReadByte();
uint size = reader.ReadULEB128();
sections.Add(new WasmSection(id, stream.Position, size, view));
if (id == WasmSectionId.Custom && size == 0)
{
break;
}
stream.Seek(size, SeekOrigin.Current);
}
foreach (var section in sections)
{
if (section.Id != WasmSectionId.Data || metadataOffset > -1)
continue;
stream.Seek(section.Offset, SeekOrigin.Begin);
uint numSegments = reader.ReadULEB128();
if (numSegments != 2)
continue;
// skip the first segment
if (reader.ReadByte() != 1)
continue;
long segmentLength = reader.ReadULEB128();
long segmentStart = reader.BaseStream.Position;
reader.BaseStream.Seek(segmentLength, SeekOrigin.Current);
if (reader.ReadByte() != 1)
continue;
segmentLength = reader.ReadULEB128();
if (TryReadWebCilSegment(reader, out var header, out metadataOffset, out var webcilOffset, out var sectionHeaders))
{
stream.Seek(metadataOffset, SeekOrigin.Begin);
var metadata = MetadataReaderProvider.FromMetadataStream(stream, MetadataStreamOptions.LeaveOpen | MetadataStreamOptions.PrefetchMetadata);
var result = new WebCilFile(fileName, webcilOffset, metadataOffset, view, ImmutableArray.Create(sectionHeaders), sections.ToImmutableArray(), metadata, metadataOptions);
view = null; // don't dispose the view, we're still using it in the sections
return result;
}
}
return null;
}
finally
{
view?.Dispose();
}
}
static unsafe bool TryReadWebCilSegment(BinaryReader reader, out WebcilHeader webcilHeader, out long metadataOffset, out long webcilOffset, [NotNullWhen(true)] out SectionHeader[]? sectionHeaders)
{
webcilHeader = default;
metadataOffset = -1;
sectionHeaders = null;
webcilOffset = reader.BaseStream.Position;
if (reader.ReadUInt32() != WEBCIL_MAGIC)
return false;
webcilHeader.VersionMajor = reader.ReadUInt16();
webcilHeader.VersionMinor = reader.ReadUInt16();
webcilHeader.CoffSections = reader.ReadUInt16();
_ = reader.ReadUInt16(); // reserved0
webcilHeader.PECliHeaderRVA = reader.ReadUInt32();
webcilHeader.PECliHeaderSize = reader.ReadUInt32();
webcilHeader.PEDebugRVA = reader.ReadUInt32();
webcilHeader.PEDebugSize = reader.ReadUInt32();
sectionHeaders = new SectionHeader[webcilHeader.CoffSections];
for (int i = 0; i < webcilHeader.CoffSections; i++)
{
sectionHeaders[i].VirtualSize = reader.ReadUInt32();
sectionHeaders[i].VirtualAddress = reader.ReadUInt32();
sectionHeaders[i].RawDataSize = reader.ReadUInt32();
sectionHeaders[i].RawDataPtr = reader.ReadUInt32();
}
long corHeaderStart = TranslateRVA(sectionHeaders, webcilOffset, webcilHeader.PECliHeaderRVA);
if (reader.BaseStream.Seek(corHeaderStart, SeekOrigin.Begin) != corHeaderStart)
return false;
int byteCount = reader.ReadInt32();
int majorVersion = reader.ReadUInt16();
int minorVersion = reader.ReadUInt16();
metadataOffset = TranslateRVA(sectionHeaders, webcilOffset, (uint)reader.ReadInt32());
return reader.BaseStream.Seek(metadataOffset, SeekOrigin.Begin) == metadataOffset;
}
public override int MetadataOffset { get; }
private static int GetContainingSectionIndex(IEnumerable<SectionHeader> sections, int rva)
{
int i = 0;
foreach (var section in sections)
{
if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)
{
return i;
}
i++;
}
return -1;
}
private static long TranslateRVA(IEnumerable<SectionHeader> sections, long webcilOffset, uint rva)
{
foreach (var section in sections)
{
if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)
{
return section.RawDataPtr + (rva - section.VirtualAddress) + webcilOffset;
}
}
throw new BadImageFormatException("RVA not found in any section");
}
public override MethodBodyBlock GetMethodBody(int rva)
{
var reader = GetSectionData(rva).GetReader();
return MethodBodyBlock.Create(reader);
}
public override int GetContainingSectionIndex(int rva)
{
return GetContainingSectionIndex(SectionHeaders, rva);
}
public override unsafe SectionData GetSectionData(int rva)
{
foreach (var section in SectionHeaders)
{
if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)
{
byte* ptr = (byte*)0;
view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
return new SectionData(ptr + section.RawDataPtr + webcilOffset + (rva - section.VirtualAddress), (int)section.RawDataSize);
}
}
throw new BadImageFormatException("RVA not found in any section");
}
public override ImmutableArray<SectionHeader> SectionHeaders { get; }
public ImmutableArray<WasmSection> WasmSections { get; }
IModule? IModuleReference.Resolve(ITypeResolveContext context)
{
return new MetadataModule(context.Compilation, this, TypeSystemOptions.Default);
}
public void Dispose()
{
view.Dispose();
}
public struct WebcilHeader
{
public ushort VersionMajor;
public ushort VersionMinor;
public ushort CoffSections;
public uint PECliHeaderRVA;
public uint PECliHeaderSize;
public uint PEDebugRVA;
public uint PEDebugSize;
}
const uint WASM_MAGIC = 0x6d736100u; // "\0asm"
const uint WEBCIL_MAGIC = 0x4c496257u; // "WbIL"
[DebuggerDisplay("WasmSection {Id}: {Offset} {Size}")]
public class WasmSection
{
public WasmSectionId Id;
public long Offset;
public uint Size;
private MemoryMappedViewAccessor view;
public WasmSection(WasmSectionId id, long offset, uint size, MemoryMappedViewAccessor view)
{
this.Id = id;
this.Size = size;
this.Offset = offset;
this.view = view;
}
}
public enum WasmSectionId : byte
{
// order matters: enum values must match the WebAssembly spec
Custom = 0,
Type = 1,
Import = 2,
Function = 3,
Table = 4,
Memory = 5,
Global = 6,
Export = 7,
Start = 8,
Element = 9,
Code = 10,
Data = 11,
DataCount = 12,
}
}
}

2
ICSharpCode.Decompiler/NRExtensions.cs

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

17
ICSharpCode.Decompiler/SRMExtensions.cs

@ -1,10 +1,13 @@ @@ -1,10 +1,13 @@
using System;
using System.Collections.Immutable;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -624,7 +627,7 @@ namespace ICSharpCode.Decompiler @@ -624,7 +627,7 @@ namespace ICSharpCode.Decompiler
}
#endregion
public static unsafe BlobReader GetInitialValue(this FieldDefinition field, PEReader pefile,
public static unsafe BlobReader GetInitialValue(this FieldDefinition field, MetadataFile pefile,
ICompilation typeSystem)
{
if (!field.HasFlag(FieldAttributes.HasFieldRVA))
@ -650,10 +653,10 @@ namespace ICSharpCode.Decompiler @@ -650,10 +653,10 @@ namespace ICSharpCode.Decompiler
public FieldValueSizeDecoder(ICompilation typeSystem = null)
{
this.module = (MetadataModule)typeSystem?.MainModule;
if (module == null)
if (module?.MetadataFile is not PEFile pefile)
this.pointerSize = IntPtr.Size;
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) =>
@ -710,7 +713,7 @@ namespace ICSharpCode.Decompiler @@ -710,7 +713,7 @@ namespace ICSharpCode.Decompiler
var typeDef = module?.ResolveType(handle, new GenericContext()).GetDefinition();
if (typeDef == null || typeDef.MetadataToken.IsNil)
return 0;
reader = typeDef.ParentModule.PEFile.Metadata;
reader = typeDef.ParentModule.MetadataFile.Metadata;
var td = reader.GetTypeDefinition((TypeDefinitionHandle)typeDef.MetadataToken);
return td.GetLayout().Size;
}
@ -747,5 +750,11 @@ namespace ICSharpCode.Decompiler @@ -747,5 +750,11 @@ namespace ICSharpCode.Decompiler
_ => callConv.ToString().ToLowerInvariant()
};
}
public static UnmanagedMemoryStream AsStream(this MemoryMappedViewAccessor view)
{
long size = checked((long)view.SafeMemoryMappedViewHandle.ByteLength);
return new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, 0, size);
}
}
}

8
ICSharpCode.Decompiler/SingleFileBundle.cs

@ -104,18 +104,12 @@ namespace ICSharpCode.Decompiler @@ -104,18 +104,12 @@ namespace ICSharpCode.Decompiler
public string RelativePath; // Path of an embedded file, relative to the Bundle source-directory.
}
static UnmanagedMemoryStream AsStream(MemoryMappedViewAccessor view)
{
long size = checked((long)view.SafeMemoryMappedViewHandle.ByteLength);
return new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, 0, size);
}
/// <summary>
/// Reads the manifest header from the memory mapping.
/// </summary>
public static Header ReadManifest(MemoryMappedViewAccessor view, long bundleHeaderOffset)
{
using var stream = AsStream(view);
using var stream = view.AsStream();
stream.Seek(bundleHeaderOffset, SeekOrigin.Begin);
return ReadManifest(stream);
}

20
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -208,17 +208,17 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -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)
{
}
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))))
{
}
public DecompilerTypeSystem(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)
public DecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)
{
if (mainModule == null)
throw new ArgumentNullException(nameof(mainModule));
@ -232,16 +232,16 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -232,16 +232,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
"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.
// This is necessary to make .NET Core/PCL binaries work better.
var referencedAssemblies = new List<PEFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, PEFile MainModule, object Reference, Task<PEFile> ResolveTask)>();
var comparer = KeyComparer.Create(((bool IsAssembly, PEFile MainModule, object Reference) reference) =>
var referencedAssemblies = new List<MetadataFile>();
var assemblyReferenceQueue = new Queue<(bool IsAssembly, MetadataFile MainModule, object Reference, Task<MetadataFile> ResolveTask)>();
var comparer = KeyComparer.Create(((bool IsAssembly, MetadataFile MainModule, object Reference) reference) =>
reference.IsAssembly ? "A:" + ((IAssemblyReference)reference.Reference).FullName :
"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 tfm = mainModule.DetectTargetFrameworkId();
var (identifier, version) = UniversalAssemblyResolver.ParseTargetFramework(tfm);
@ -334,13 +334,13 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -334,13 +334,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
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)))
{
// Immediately start loading the referenced module as we add the entry to the queue.
// This allows loading multiple modules in parallel.
Task<PEFile> asm;
Task<MetadataFile> asm;
if (isAssembly)
{
asm = assemblyResolver.ResolveAsync((IAssemblyReference)reference);

2
ICSharpCode.Decompiler/TypeSystem/IAssembly.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary>
/// Gets the underlying metadata file. May return null, if the IAssembly was not created from a PE file.
/// </summary>
PEFile? PEFile { get; }
MetadataFile? MetadataFile { get; }
/// <summary>
/// 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 @@ -168,14 +168,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
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;
}
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)

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

@ -299,14 +299,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -299,14 +299,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
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;
}
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)

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

@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.attributes = def.Attributes;
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);
this.typeParameters = MetadataTypeParameter.Create(module, this, def.GetGenericParameters());
if (semanticsAttribute != 0 && !accessorOwner.IsNil
@ -606,14 +606,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -606,14 +606,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
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;
}
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)

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

@ -267,7 +267,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -267,7 +267,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
// "protected internal" (ProtectedOrInternal) accessibility is "reduced"
// to "protected" accessibility across assembly boundaries.
if (baseMember.Accessibility == Accessibility.ProtectedOrInternal
&& this.ParentModule?.PEFile != baseMember.ParentModule?.PEFile)
&& this.ParentModule?.MetadataFile != baseMember.ParentModule?.MetadataFile)
{
return Accessibility.Protected;
}
@ -302,14 +302,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -302,14 +302,14 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
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;
}
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)

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

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

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

@ -248,12 +248,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -248,12 +248,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override int GetHashCode()
{
return 0x51fc5b83 ^ module.PEFile.GetHashCode() ^ handle.GetHashCode();
return 0x51fc5b83 ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();
}
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()

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

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

12
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

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

4
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -699,14 +699,14 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -699,14 +699,14 @@ namespace ICSharpCode.Decompiler.TypeSystem
public static bool IsDirectImportOf(this ITypeDefinition type, IModule module)
{
var moduleReference = type.ParentModule;
foreach (var asmRef in module.PEFile.AssemblyReferences)
foreach (var asmRef in module.MetadataFile.AssemblyReferences)
{
if (asmRef.FullName == moduleReference.FullAssemblyName)
return true;
if (asmRef.Name == "netstandard" && asmRef.GetPublicKeyToken() != null)
{
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;
}
}

2
ICSharpCode.ILSpyX/Abstractions/ILanguage.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.ILSpyX.Abstractions @@ -24,7 +24,7 @@ namespace ICSharpCode.ILSpyX.Abstractions
public interface ILanguage
{
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 TypeToString(IType type, bool includeNamespace);

2
ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs

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

28
ICSharpCode.ILSpyX/AssemblyListSnapshot.cs

@ -33,9 +33,9 @@ namespace ICSharpCode.ILSpyX @@ -33,9 +33,9 @@ namespace ICSharpCode.ILSpyX
class AssemblyListSnapshot
{
readonly ImmutableArray<LoadedAssembly> assemblies;
Dictionary<string, PEFile>? asmLookupByFullName;
Dictionary<string, PEFile>? asmLookupByShortName;
Dictionary<string, List<(PEFile module, Version version)>>? asmLookupByShortNameGrouped;
Dictionary<string, MetadataFile>? asmLookupByFullName;
Dictionary<string, MetadataFile>? asmLookupByShortName;
Dictionary<string, List<(MetadataFile module, Version version)>>? asmLookupByShortNameGrouped;
public ImmutableArray<LoadedAssembly> Assemblies => assemblies;
public AssemblyListSnapshot(ImmutableArray<LoadedAssembly> assemblies)
@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpyX @@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpyX
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;
if (tfm.StartsWith(".NETFramework,Version=v4.", StringComparison.Ordinal))
@ -57,12 +57,12 @@ namespace ICSharpCode.ILSpyX @@ -57,12 +57,12 @@ namespace ICSharpCode.ILSpyX
lookup = await CreateLoadedAssemblyLookupAsync(shortNames: isWinRT).ConfigureAwait(false);
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 null;
}
public async Task<PEFile?> TryGetSimilarModuleAsync(IAssemblyReference reference)
public async Task<MetadataFile?> TryGetSimilarModuleAsync(IAssemblyReference reference)
{
var lookup = LazyInit.VolatileRead(ref asmLookupByShortNameGrouped);
if (lookup == null)
@ -76,14 +76,14 @@ namespace ICSharpCode.ILSpyX @@ -76,14 +76,14 @@ namespace ICSharpCode.ILSpyX
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)
{
try
{
var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false);
var module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);
if (module == null)
continue;
var reader = module.Metadata;
@ -109,15 +109,15 @@ namespace ICSharpCode.ILSpyX @@ -109,15 +109,15 @@ namespace ICSharpCode.ILSpyX
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)
{
try
{
var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false);
var module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);
var reader = module?.Metadata;
if (reader == null || !reader.IsAssembly)
continue;
@ -128,7 +128,7 @@ namespace ICSharpCode.ILSpyX @@ -128,7 +128,7 @@ namespace ICSharpCode.ILSpyX
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);
existing.Add(line);
continue;
@ -170,7 +170,7 @@ namespace ICSharpCode.ILSpyX @@ -170,7 +170,7 @@ namespace ICSharpCode.ILSpyX
{
AddDescendants(result.Package.RootFolder);
}
else if (result.PEFile != null)
else if (result.MetadataFile != null)
{
results.Add(asm);
}

74
ICSharpCode.ILSpyX/LoadedAssembly.cs

@ -35,6 +35,9 @@ using ICSharpCode.ILSpyX.PdbProvider; @@ -35,6 +35,9 @@ using ICSharpCode.ILSpyX.PdbProvider;
using K4os.Compression.LZ4;
using static ICSharpCode.Decompiler.Metadata.MetadataFile;
#nullable enable
namespace ICSharpCode.ILSpyX
@ -133,7 +136,7 @@ namespace ICSharpCode.ILSpyX @@ -133,7 +136,7 @@ namespace ICSharpCode.ILSpyX
var value = LazyInit.VolatileRead(ref targetFrameworkId);
if (value == null)
{
var assembly = await GetPEFileAsync().ConfigureAwait(false);
var assembly = await GetMetadataFileAsync().ConfigureAwait(false);
value = assembly.DetectTargetFrameworkId() ?? string.Empty;
value = LazyInit.GetOrSet(ref targetFrameworkId, value);
}
@ -148,7 +151,7 @@ namespace ICSharpCode.ILSpyX @@ -148,7 +151,7 @@ namespace ICSharpCode.ILSpyX
var value = LazyInit.VolatileRead(ref runtimePack);
if (value == null)
{
var assembly = await GetPEFileAsync().ConfigureAwait(false);
var assembly = await GetMetadataFileAsync().ConfigureAwait(false);
value = assembly.DetectRuntimePack() ?? string.Empty;
value = LazyInit.GetOrSet(ref runtimePack, value);
}
@ -169,13 +172,13 @@ namespace ICSharpCode.ILSpyX @@ -169,13 +172,13 @@ namespace ICSharpCode.ILSpyX
}
/// <summary>
/// Gets the <see cref="PEFile"/>.
/// Gets the <see cref="MetadataFile"/>.
/// </summary>
public async Task<PEFile> GetPEFileAsync()
public async Task<MetadataFile> GetMetadataFileAsync()
{
var loadResult = await loadingTask.ConfigureAwait(false);
if (loadResult.PEFile != null)
return loadResult.PEFile;
if (loadResult.MetadataFile != null)
return loadResult.MetadataFile;
else
throw loadResult.FileLoadException!;
}
@ -184,12 +187,12 @@ namespace ICSharpCode.ILSpyX @@ -184,12 +187,12 @@ namespace ICSharpCode.ILSpyX
/// Gets the <see cref="PEFile"/>.
/// Returns null in case of load errors.
/// </summary>
public PEFile? GetPEFileOrNull()
public MetadataFile? GetMetadataFileOrNull()
{
try
{
var loadResult = loadingTask.GetAwaiter().GetResult();
return loadResult.PEFile;
return loadResult.MetadataFile;
}
catch (Exception ex)
{
@ -199,15 +202,15 @@ namespace ICSharpCode.ILSpyX @@ -199,15 +202,15 @@ namespace ICSharpCode.ILSpyX
}
/// <summary>
/// Gets the <see cref="PEFile"/>.
/// Gets the <see cref="MetadataFile"/>.
/// Returns null in case of load errors.
/// </summary>
public async Task<PEFile?> GetPEFileOrNullAsync()
public async Task<MetadataFile?> GetMetadataFileOrNullAsync()
{
try
{
var loadResult = await loadingTask.ConfigureAwait(false);
return loadResult.PEFile;
return loadResult.MetadataFile;
}
catch (Exception ex)
{
@ -228,7 +231,7 @@ namespace ICSharpCode.ILSpyX @@ -228,7 +231,7 @@ namespace ICSharpCode.ILSpyX
public ICompilation? GetTypeSystemOrNull()
{
return LazyInitializer.EnsureInitialized(ref this.typeSystem, () => {
var module = GetPEFileOrNull();
var module = GetMetadataFileOrNull();
if (module == null)
return null!;
return new SimpleCompilation(
@ -247,7 +250,7 @@ namespace ICSharpCode.ILSpyX @@ -247,7 +250,7 @@ namespace ICSharpCode.ILSpyX
{
if (typeSystemWithOptions != null && options == currentTypeSystemOptions)
return typeSystemWithOptions;
var module = GetPEFileOrNull();
var module = GetMetadataFileOrNull();
if (module == null)
return null;
currentTypeSystemOptions = options;
@ -312,7 +315,7 @@ namespace ICSharpCode.ILSpyX @@ -312,7 +315,7 @@ namespace ICSharpCode.ILSpyX
/// </summary>
public bool IsLoadedAsValidAssembly {
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 @@ -356,7 +359,7 @@ namespace ICSharpCode.ILSpyX
return LoadAssembly(fileStream, PEStreamOptions.PrefetchEntireImage, applyWinRTProjections);
}
}
catch (PEFileNotSupportedException ex)
catch (MetadataFileNotSupportedException ex)
{
loadAssemblyException = ex;
}
@ -380,6 +383,16 @@ namespace ICSharpCode.ILSpyX @@ -380,6 +383,16 @@ namespace ICSharpCode.ILSpyX
bundle.LoadedAssembly = this;
return new LoadResult(loadAssemblyException, bundle);
}
// If it's not a .NET module, maybe it's a WASM module
var wasm = WebCilFile.FromStream(fileName);
if (wasm != null)
{
lock (loadedAssemblies)
{
loadedAssemblies.Add(wasm, this);
}
return new LoadResult(loadAssemblyException, wasm);
}
// If it's not a .NET module, maybe it's a zip archive (e.g. .nupkg)
try
{
@ -396,8 +409,9 @@ namespace ICSharpCode.ILSpyX @@ -396,8 +409,9 @@ namespace ICSharpCode.ILSpyX
{
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 metadataFile = new MetadataFile(fileName, metadata);
var metadataFile = new MetadataFile(kind, fileName, metadata);
lock (loadedAssemblies)
{
loadedAssemblies.Add(metadataFile, this);
@ -463,8 +477,12 @@ namespace ICSharpCode.ILSpyX @@ -463,8 +477,12 @@ namespace ICSharpCode.ILSpyX
}
}
IDebugInfoProvider? LoadDebugInfo(PEFile module)
IDebugInfoProvider? LoadDebugInfo(PEFile? module)
{
if (module == null)
{
return null;
}
if (useDebugSymbols)
{
try
@ -489,8 +507,8 @@ namespace ICSharpCode.ILSpyX @@ -489,8 +507,8 @@ namespace ICSharpCode.ILSpyX
public async Task<IDebugInfoProvider?> LoadDebugInfo(string fileName)
{
this.PdbFileName = fileName;
var assembly = await GetPEFileAsync().ConfigureAwait(false);
debugInfoProvider = await Task.Run(() => LoadDebugInfo(assembly));
var assembly = await GetMetadataFileAsync().ConfigureAwait(false);
debugInfoProvider = await Task.Run(() => LoadDebugInfo(assembly as PEFile));
return debugInfoProvider;
}
@ -525,7 +543,7 @@ namespace ICSharpCode.ILSpyX @@ -525,7 +543,7 @@ namespace ICSharpCode.ILSpyX
this.referenceLoadInfo = parent.LoadedAssemblyReferencesInfo;
}
public PEFile? Resolve(IAssemblyReference reference)
public MetadataFile? Resolve(IAssemblyReference reference)
{
return ResolveAsync(reference).GetAwaiter().GetResult();
}
@ -542,9 +560,9 @@ namespace ICSharpCode.ILSpyX @@ -542,9 +560,9 @@ namespace ICSharpCode.ILSpyX
/// 8) search C:\Windows\Microsoft.NET\Framework64\v4.0.30319
/// 9) try to find match by asm name (no tfm/version) in loaded assemblies
/// </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
if (providedAssemblyResolver != null)
{
@ -580,7 +598,7 @@ namespace ICSharpCode.ILSpyX @@ -580,7 +598,7 @@ namespace ICSharpCode.ILSpyX
if (asm != null)
{
referenceLoadInfo.AddMessage(reference.FullName, MessageKind.Info, "Success - Loading from: " + file);
return await asm.GetPEFileOrNullAsync().ConfigureAwait(false);
return await asm.GetMetadataFileOrNullAsync().ConfigureAwait(false);
}
return null;
}
@ -600,12 +618,12 @@ namespace ICSharpCode.ILSpyX @@ -600,12 +618,12 @@ namespace ICSharpCode.ILSpyX
}
}
public PEFile? ResolveModule(PEFile mainModule, string moduleName)
public MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName)
{
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)
{
@ -632,7 +650,7 @@ namespace ICSharpCode.ILSpyX @@ -632,7 +650,7 @@ namespace ICSharpCode.ILSpyX
}
if (asm != null)
{
return await asm.GetPEFileOrNullAsync().ConfigureAwait(false);
return await asm.GetMetadataFileOrNullAsync().ConfigureAwait(false);
}
}
}
@ -640,7 +658,7 @@ namespace ICSharpCode.ILSpyX @@ -640,7 +658,7 @@ namespace ICSharpCode.ILSpyX
// Module does not exist on disk, look for one with a matching name in the assemblylist:
foreach (LoadedAssembly loaded in alreadyLoadedAssemblies.Assemblies)
{
var module = await loaded.GetPEFileOrNullAsync().ConfigureAwait(false);
var module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);
var reader = module?.Metadata;
if (reader == null || reader.IsAssembly)
continue;
@ -694,7 +712,7 @@ namespace ICSharpCode.ILSpyX @@ -694,7 +712,7 @@ namespace ICSharpCode.ILSpyX
/// </summary>
public IDebugInfoProvider? GetDebugInfoOrNull()
{
if (GetPEFileOrNull() == null)
if (GetMetadataFileOrNull() == null)
return null;
return debugInfoProvider;
}

10
ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs

@ -27,27 +27,27 @@ namespace ICSharpCode.ILSpyX @@ -27,27 +27,27 @@ namespace ICSharpCode.ILSpyX
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);
}
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);
}
public static IDebugInfoProvider? GetDebugInfoOrNull(this PEFile file)
public static IDebugInfoProvider? GetDebugInfoOrNull(this MetadataFile file)
{
return GetLoadedAssembly(file).GetDebugInfoOrNull();
}
public static ICompilation? GetTypeSystemOrNull(this PEFile file)
public static ICompilation? GetTypeSystemOrNull(this MetadataFile file)
{
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));
}

20
ICSharpCode.ILSpyX/LoadedPackage.cs

@ -273,52 +273,52 @@ namespace ICSharpCode.ILSpyX @@ -273,52 +273,52 @@ namespace ICSharpCode.ILSpyX
public List<PackageFolder> Folders { get; } = new List<PackageFolder>();
public List<PackageEntry> Entries { get; } = new List<PackageEntry>();
public PEFile? Resolve(IAssemblyReference reference)
public MetadataFile? Resolve(IAssemblyReference reference)
{
var asm = ResolveFileName(reference.Name + ".dll");
if (asm != null)
{
return asm.GetPEFileOrNull();
return asm.GetMetadataFileOrNull();
}
return parent?.Resolve(reference);
}
public Task<PEFile?> ResolveAsync(IAssemblyReference reference)
public Task<MetadataFile?> ResolveAsync(IAssemblyReference reference)
{
var asm = ResolveFileName(reference.Name + ".dll");
if (asm != null)
{
return asm.GetPEFileOrNullAsync();
return asm.GetMetadataFileOrNullAsync();
}
if (parent != null)
{
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");
if (asm != null)
{
return asm.GetPEFileOrNull();
return asm.GetMetadataFileOrNull();
}
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");
if (asm != null)
{
return asm.GetPEFileOrNullAsync();
return asm.GetMetadataFileOrNullAsync();
}
if (parent != null)
{
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);

5
ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs

@ -26,6 +26,8 @@ using ICSharpCode.Decompiler.DebugInfo; @@ -26,6 +26,8 @@ using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
using static ICSharpCode.Decompiler.Metadata.MetadataFile;
#nullable enable
namespace ICSharpCode.ILSpyX.PdbProvider
@ -240,7 +242,8 @@ namespace ICSharpCode.ILSpyX.PdbProvider @@ -240,7 +242,8 @@ namespace ICSharpCode.ILSpyX.PdbProvider
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 @@ -67,8 +67,8 @@ namespace ICSharpCode.ILSpyX.Search
{
if (searchRequest.InAssembly != null)
{
if (entity.ParentModule?.PEFile == null ||
!(Path.GetFileName(entity.ParentModule.PEFile.FileName).Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)
if (entity.ParentModule?.MetadataFile == null ||
!(Path.GetFileName(entity.ParentModule.MetadataFile.FileName).Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)
|| entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)))
{
return false;

2
ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs

@ -78,7 +78,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -78,7 +78,7 @@ namespace ICSharpCode.ILSpyX.Search
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)
{

7
ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs

@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
// 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.
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading;
@ -35,7 +34,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -35,7 +34,7 @@ namespace ICSharpCode.ILSpyX.Search
this.searchKind = searchKind;
}
public override void Search(PEFile module, CancellationToken cancellationToken)
public override void Search(MetadataFile module, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@ -61,7 +60,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -61,7 +60,7 @@ namespace ICSharpCode.ILSpyX.Search
OnFoundResult(module);
}
string? GetNameToMatch(PEFile module, AssemblySearchKind kind)
string? GetNameToMatch(MetadataFile module, AssemblySearchKind kind)
{
switch (kind)
{
@ -98,7 +97,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -98,7 +97,7 @@ namespace ICSharpCode.ILSpyX.Search
return null;
}
void OnFoundResult(PEFile module)
void OnFoundResult(MetadataFile module)
{
OnFoundResult(searchRequest.SearchResultFactory.Create(module));
}

8
ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs

@ -28,8 +28,6 @@ using ICSharpCode.Decompiler.TypeSystem; @@ -28,8 +28,6 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpyX.Abstractions;
using static System.Reflection.Metadata.PEReaderExtensions;
using ILOpCode = System.Reflection.Metadata.ILOpCode;
namespace ICSharpCode.ILSpyX.Search
@ -78,7 +76,7 @@ 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
}
public override void Search(PEFile module, CancellationToken cancellationToken)
public override void Search(MetadataFile module, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var metadata = module.Metadata;
@ -143,9 +141,9 @@ namespace ICSharpCode.ILSpyX.Search @@ -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)
{
Debug.Assert(searchTermLiteralValue != null);

3
ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs

@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
// 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.
using System;
using System.Collections.Concurrent;
using System.Threading;
@ -36,7 +35,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -36,7 +35,7 @@ namespace ICSharpCode.ILSpyX.Search
this.searchKind = searchKind;
}
public override void Search(PEFile module, CancellationToken cancellationToken)
public override void Search(MetadataFile module, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var metadata = module.Metadata;

3
ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs

@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
// 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.
using System;
using System.Collections.Concurrent;
using System.Globalization;
using System.Reflection.Metadata;
@ -44,7 +43,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -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();
if (searchTermToken.IsNil)

6
ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -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();
var typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings);
@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpyX.Search
Search(module, root);
}
private void Search(PEFile module, INamespace ns)
private void Search(MetadataFile module, INamespace ns)
{
if (ns.Types.Any())
{
@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpyX.Search
Search(module, child);
}
void OnFoundResult(PEFile module, INamespace ns)
void OnFoundResult(MetadataFile module, INamespace ns)
{
OnFoundResult(searchRequest.SearchResultFactory.Create(module, ns));
}

7
ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs

@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
// 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.
using System;
using System.Collections.Concurrent;
using System.Reflection;
using System.Threading;
@ -50,7 +49,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -50,7 +49,7 @@ namespace ICSharpCode.ILSpyX.Search
return true;
}
public override void Search(PEFile module, CancellationToken cancellationToken)
public override void Search(MetadataFile module, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var resourcesNode = treeNodeFactory.CreateResourcesList(module);
@ -59,7 +58,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -59,7 +58,7 @@ namespace ICSharpCode.ILSpyX.Search
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();
@ -81,7 +80,7 @@ namespace ICSharpCode.ILSpyX.Search @@ -81,7 +80,7 @@ namespace ICSharpCode.ILSpyX.Search
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));
}

8
ICSharpCode.ILSpyX/Search/SearchResult.cs

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

2
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -66,7 +66,7 @@ namespace ILSpy.BamlDecompiler @@ -66,7 +66,7 @@ namespace ILSpy.BamlDecompiler
{
var asm = this.Ancestors().OfType<AssemblyTreeNode>().First().LoadedAssembly;
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());
decompiler.CancellationToken = cancellationToken;
var result = decompiler.Decompile(data);

2
ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs

@ -51,7 +51,7 @@ namespace ILSpy.BamlDecompiler @@ -51,7 +51,7 @@ namespace ILSpy.BamlDecompiler
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() {
ThrowOnAssemblyResolveErrors = context.DecompilationOptions.DecompilerSettings.ThrowOnAssemblyResolveErrors
});

43
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -30,7 +30,6 @@ using System.Runtime.CompilerServices; @@ -30,7 +30,6 @@ using System.Runtime.CompilerServices;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem;
@ -98,7 +97,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -98,7 +97,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
[Export(typeof(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";
@ -113,7 +112,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -113,7 +112,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
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);
if (cacheEntry.readyToRunReader == null)
{
@ -136,7 +135,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -136,7 +135,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
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);
if (cacheEntry.readyToRunReader == null)
{
@ -196,7 +195,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -196,7 +195,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
if (cacheEntry.compositeReadyToRunReader == null)
{
disassemblingReader = reader;
file = method.ParentModule.PEFile;
file = method.ParentModule.MetadataFile as PEFile;
}
else
{
@ -220,33 +219,41 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -220,33 +219,41 @@ namespace ICSharpCode.ILSpy.ReadyToRun
return Languages.ILLanguage.GetRichTextTooltip(entity);
}
private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, PEFile module)
private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, MetadataFile file)
{
ReadyToRunReaderCacheEntry result;
lock (readyToRunReaders)
{
if (!readyToRunReaders.TryGetValue(module, out result))
if (!readyToRunReaders.TryGetValue(file, out result))
{
result = new ReadyToRunReaderCacheEntry();
try
{
result.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), new StandaloneAssemblyMetadata(module.Reader), module.Reader, module.FileName);
if (result.readyToRunReader.Machine != Machine.Amd64 && result.readyToRunReader.Machine != Machine.I386)
if (file is not PEFile module)
{
result.failureReason = $"Architecture {result.readyToRunReader.Machine} is not currently supported.";
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.compositeReadyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), compositePath);
result.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), new StandaloneAssemblyMetadata(module.Reader), module.Reader, module.FileName);
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)
{
result.failureReason = e.Message;
}
readyToRunReaders.Add(module, result);
readyToRunReaders.Add(file, result);
}
}
return result;
@ -270,18 +277,18 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -270,18 +277,18 @@ namespace ICSharpCode.ILSpy.ReadyToRun
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;
}
else
{
return new IlSpyAssemblyMetadata(module);
return new IlSpyAssemblyMetadata(peFile);
}
}
}

9
ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs

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

8
ILSpy/Analyzers/AnalyzerContext.cs

@ -55,11 +55,11 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -55,11 +55,11 @@ namespace ICSharpCode.ILSpy.Analyzers
{
if (!method.HasBody || method.MetadataToken.IsNil)
return null;
var module = method.ParentModule.PEFile;
var module = method.ParentModule.MetadataFile;
var md = module.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
try
{
return module.Reader.GetMethodBody(md.RelativeVirtualAddress);
return module.GetMethodBody(md.RelativeVirtualAddress);
}
catch (BadImageFormatException)
{
@ -72,9 +72,9 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -72,9 +72,9 @@ namespace ICSharpCode.ILSpy.Analyzers
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()));
}

4
ILSpy/Analyzers/AnalyzerEntityTreeNode.cs

@ -41,14 +41,14 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -41,14 +41,14 @@ namespace ICSharpCode.ILSpy.Analyzers
MessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, "ILSpy");
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)
{
foreach (LoadedAssembly asm in removedAssemblies)
{
if (this.Member.ParentModule.PEFile == asm.GetPEFileOrNull())
if (this.Member.ParentModule.MetadataFile == asm.GetMetadataFileOrNull())
return false; // remove this node
}
this.Children.RemoveAll(

6
ILSpy/Analyzers/AnalyzerHelpers.cs

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

28
ILSpy/Analyzers/AnalyzerScope.cs

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

6
ILSpy/Analyzers/Builtin/EventImplementedByAnalyzer.cs

@ -46,15 +46,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -46,15 +46,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
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;
foreach (var @event in type.Events)
{
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;
}
}

6
ILSpy/Analyzers/Builtin/EventOverriddenByAnalyzer.cs

@ -46,9 +46,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -46,9 +46,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
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;
foreach (var @event in type.Events)
@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (!@event.IsOverride)
continue;
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;
}

13
ILSpy/Analyzers/Builtin/FieldAccessAnalyzer.cs

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

6
ILSpy/Analyzers/Builtin/FindTypeInAttributeDecoder.cs

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

6
ILSpy/Analyzers/Builtin/MethodImplementedByAnalyzer.cs

@ -49,15 +49,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -49,15 +49,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
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;
foreach (var method in type.Methods)
{
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;
}
}

6
ILSpy/Analyzers/Builtin/MethodOverriddenByAnalyzer.cs

@ -48,9 +48,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -48,9 +48,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
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;
foreach (var method in type.Methods)
@ -58,7 +58,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -58,7 +58,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (!method.IsOverride)
continue;
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;
}

10
ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
var analyzedMethod = (IMethod)analyzedSymbol;
var analyzedBaseMethod = (IMethod)InheritanceHelper.GetBaseMember(analyzedMethod);
var mapping = context.Language
.GetCodeMappingInfo(analyzedMethod.ParentModule.PEFile,
.GetCodeMappingInfo(analyzedMethod.ParentModule.MetadataFile,
analyzedMethod.DeclaringTypeDefinition.MetadataToken);
var parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken);
@ -64,7 +64,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -64,7 +64,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
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);
yield return parentModule.GetDefinition(parent);
}
@ -137,9 +137,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -137,9 +137,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
return false; // unexpected end of blob
}
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;
}
@ -192,7 +192,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -192,7 +192,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
static bool IsSameMember(IMember analyzedMethod, IMember m)
{
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 @@ -38,10 +38,10 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
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);
return context.Language.GetCodeMappingInfo(method.ParentModule.PEFile, method.MetadataToken)
var typeSystem = context.GetOrCreateTypeSystem(corFile);
return context.Language.GetCodeMappingInfo(corFile, method.MetadataToken)
.GetMethodParts((MethodDefinitionHandle)method.MetadataToken)
.SelectMany(h => ScanMethod(h, typeSystem)).Distinct();
}
@ -51,14 +51,14 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -51,14 +51,14 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
IEnumerable<IEntity> ScanMethod(MethodDefinitionHandle handle, DecompilerTypeSystem typeSystem)
{
var module = typeSystem.MainModule;
var md = module.PEFile.Metadata.GetMethodDefinition(handle);
var md = module.MetadataFile.Metadata.GetMethodDefinition(handle);
if (!md.HasBody())
yield break;
BlobReader blob;
try
{
blob = module.PEFile.Reader.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
blob = module.MetadataFile.GetMethodBody(md.RelativeVirtualAddress).GetILReader();
}
catch (BadImageFormatException)
{

6
ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
Debug.Assert(analyzedSymbol is IMethod);
var analyzedMethod = (IMethod)analyzedSymbol;
var mapping = context.Language
.GetCodeMappingInfo(analyzedMethod.ParentModule.PEFile,
.GetCodeMappingInfo(analyzedMethod.ParentModule.MetadataFile,
analyzedMethod.DeclaringTypeDefinition.MetadataToken);
var parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken);
@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
foreach (var type in scope.GetTypesInScope(context.CancellationToken))
{
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>();
foreach (var method in methods)
{
@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
case HandleKind.MethodSpecification:
case HandleKind.MemberReference:
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;
}

6
ILSpy/Analyzers/Builtin/PropertyImplementedByAnalyzer.cs

@ -46,15 +46,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -46,15 +46,15 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
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;
foreach (var property in type.Properties)
{
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;
}
}

6
ILSpy/Analyzers/Builtin/PropertyOverriddenByAnalyzer.cs

@ -49,9 +49,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -49,9 +49,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
var token = analyzedEntity.MetadataToken;
var declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.PEFile;
var module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;
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;
foreach (var property in type.Properties)
@ -59,7 +59,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -59,7 +59,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (!property.IsOverride)
continue;
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;
}

2
ILSpy/Analyzers/Builtin/TypeExposedByAnalyzer.cs

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

2
ILSpy/Analyzers/Builtin/TypeExtensionMethodsAnalyzer.cs

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

4
ILSpy/Analyzers/Builtin/TypeInstantiatedByAnalyzer.cs

@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
var scope = context.GetScopeOf((ITypeDefinition)analyzedSymbol);
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>();
foreach (var method in methods)
{
@ -134,7 +134,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -134,7 +134,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
continue;
if (ctor.DeclaringTypeDefinition?.MetadataToken == analyzedEntity.MetadataToken
&& ctor.ParentModule.PEFile == analyzedEntity.ParentModule.PEFile)
&& ctor.ParentModule.MetadataFile == analyzedEntity.ParentModule.MetadataFile)
return true;
}

10
ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs

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

4
ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs

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

3
ILSpy/Commands/GeneratePdbContextMenuEntry.cs

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

26
ILSpy/Commands/IProtocolHandler.cs

@ -1,18 +1,30 @@ @@ -1,18 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
// Copyright (c) 2018 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.
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy
{
public interface IProtocolHandler
{
ILSpyTreeNode Resolve(string protocol, PEFile module, Handle handle, out bool newTabPage);
ILSpyTreeNode Resolve(string protocol, MetadataFile module, Handle handle, out bool newTabPage);
}
}

2
ILSpy/EntityReference.cs

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

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

Loading…
Cancel
Save