Browse Source

Merge pull request #3149 from icsharpcode/pdb+dmeta

Support reading raw metadata blobs and Portable PDBs
natural-type-lambdas-methods
Siegfried Pammer 2 years ago committed by GitHub
parent
commit
47ac132f77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  2. 4
      ICSharpCode.Decompiler/Disassembler/DisassemblerSignatureTypeProvider.cs
  3. 14
      ICSharpCode.Decompiler/Disassembler/IEntityProcessor.cs
  4. 28
      ICSharpCode.Decompiler/Disassembler/SortByNameProcessor.cs
  5. 26
      ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs
  6. 2
      ICSharpCode.Decompiler/Metadata/MetadataGenericContext.cs
  7. 51
      ICSharpCode.Decompiler/Metadata/PEFile.cs
  8. 2
      ICSharpCode.Decompiler/Output/ITextOutput.cs
  9. 4
      ICSharpCode.Decompiler/Output/PlainTextOutput.cs
  10. 88
      ICSharpCode.ILSpyX/LoadedAssembly.cs
  11. 2
      ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs
  12. 4
      ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs
  13. 9
      ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs
  14. 6
      ILSpy/EntityReference.cs
  15. 6
      ILSpy/ExtensionMethods.cs
  16. 1
      ILSpy/Images/Header.svg
  17. 11
      ILSpy/Images/Header.xaml
  18. 1
      ILSpy/Images/Heap.svg
  19. 10
      ILSpy/Images/Heap.xaml
  20. 10
      ILSpy/Images/Images.cs
  21. 1
      ILSpy/Images/ListFolder.Open.svg
  22. 12
      ILSpy/Images/ListFolder.Open.xaml
  23. 1
      ILSpy/Images/ListFolder.svg
  24. 11
      ILSpy/Images/ListFolder.xaml
  25. 1
      ILSpy/Images/Metadata.svg
  26. 15
      ILSpy/Images/Metadata.xaml
  27. 73
      ILSpy/Images/MetadataFile.svg
  28. 29
      ILSpy/Images/MetadataFile.xaml
  29. 1
      ILSpy/Images/MetadataTable.svg
  30. 10
      ILSpy/Images/MetadataTable.xaml
  31. 1
      ILSpy/Images/MetadataTableGroup.svg
  32. 10
      ILSpy/Images/MetadataTableGroup.xaml
  33. 1
      ILSpy/Images/ProgramDebugDatabase.svg
  34. 14
      ILSpy/Images/ProgramDebugDatabase.xaml
  35. 9
      ILSpy/Images/README.md
  36. 4
      ILSpy/MainWindow.xaml.cs
  37. 2
      ILSpy/Metadata/CoffHeaderTreeNode.cs
  38. 37
      ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs
  39. 23
      ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs
  40. 33
      ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs
  41. 36
      ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs
  42. 40
      ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs
  43. 36
      ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs
  44. 41
      ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs
  45. 44
      ILSpy/Metadata/CorTables/EventTableTreeNode.cs
  46. 37
      ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs
  47. 35
      ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs
  48. 37
      ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs
  49. 34
      ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs
  50. 41
      ILSpy/Metadata/CorTables/FieldTableTreeNode.cs
  51. 34
      ILSpy/Metadata/CorTables/FileTableTreeNode.cs
  52. 43
      ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs
  53. 38
      ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs
  54. 45
      ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs
  55. 40
      ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs
  56. 38
      ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs
  57. 40
      ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs
  58. 44
      ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs
  59. 39
      ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs
  60. 37
      ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs
  61. 45
      ILSpy/Metadata/CorTables/MethodTableTreeNode.cs
  62. 32
      ILSpy/Metadata/CorTables/ModuleRefTableTreeNode.cs
  63. 36
      ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs
  64. 39
      ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs
  65. 32
      ILSpy/Metadata/CorTables/ParamTableTreeNode.cs
  66. 41
      ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs
  67. 38
      ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs
  68. 34
      ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs
  69. 55
      ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs
  70. 39
      ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs
  71. 22
      ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs
  72. 6
      ILSpy/Metadata/DataDirectoriesTreeNode.cs
  73. 3
      ILSpy/Metadata/DebugDirectory/CodeViewTreeNode.cs
  74. 5
      ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs
  75. 2
      ILSpy/Metadata/DebugDirectory/PdbChecksumTreeNode.cs
  76. 13
      ILSpy/Metadata/DebugDirectoryTreeNode.cs
  77. 33
      ILSpy/Metadata/DebugMetadataTablesTreeNode.cs
  78. 77
      ILSpy/Metadata/DebugMetadataTreeNode.cs
  79. 46
      ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs
  80. 40
      ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs
  81. 41
      ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs
  82. 35
      ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs
  83. 44
      ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs
  84. 31
      ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs
  85. 45
      ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs
  86. 48
      ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs
  87. 4
      ILSpy/Metadata/DosHeaderTreeNode.cs
  88. 17
      ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs
  89. 8
      ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs
  90. 17
      ILSpy/Metadata/Heaps/StringHeapTreeNode.cs
  91. 18
      ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs
  92. 22
      ILSpy/Metadata/MetadataHeapTreeNode.cs
  93. 25
      ILSpy/Metadata/MetadataTableTreeNode.cs
  94. 179
      ILSpy/Metadata/MetadataTablesTreeNode.cs
  95. 69
      ILSpy/Metadata/MetadataTreeNode.cs
  96. 2
      ILSpy/Metadata/OptionalHeaderTreeNode.cs
  97. 6
      ILSpy/TextView/AvalonEditTextOutput.cs
  98. 3
      ILSpy/TextView/DecompilerTextView.cs
  99. 32
      ILSpy/TreeNodes/AssemblyTreeNode.cs

5
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -17,7 +17,6 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Text; using System.Text;
@ -26,8 +25,6 @@ using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Disassembler namespace ICSharpCode.Decompiler.Disassembler
{ {
public enum ILNameSyntax public enum ILNameSyntax
@ -72,7 +69,7 @@ namespace ICSharpCode.Decompiler.Disassembler
writer.WriteLocalReference(OffsetToString(offset.Value), offset); writer.WriteLocalReference(OffsetToString(offset.Value), offset);
} }
public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Metadata.PEFile module, MetadataGenericContext context, ITextOutput writer) public static void WriteTo(this ExceptionRegion exceptionHandler, MetadataFile module, MetadataGenericContext context, ITextOutput writer)
{ {
writer.Write(".try "); writer.Write(".try ");
WriteOffsetReference(writer, exceptionHandler.TryOffset); WriteOffsetReference(writer, exceptionHandler.TryOffset);

4
ICSharpCode.Decompiler/Disassembler/DisassemblerSignatureTypeProvider.cs

@ -27,11 +27,11 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
public class DisassemblerSignatureTypeProvider : ISignatureTypeProvider<Action<ILNameSyntax>, MetadataGenericContext> public class DisassemblerSignatureTypeProvider : ISignatureTypeProvider<Action<ILNameSyntax>, MetadataGenericContext>
{ {
readonly PEFile module; readonly MetadataFile module;
readonly MetadataReader metadata; readonly MetadataReader metadata;
readonly ITextOutput output; readonly ITextOutput output;
public DisassemblerSignatureTypeProvider(PEFile module, ITextOutput output) public DisassemblerSignatureTypeProvider(MetadataFile module, ITextOutput output)
{ {
this.module = module ?? throw new ArgumentNullException(nameof(module)); this.module = module ?? throw new ArgumentNullException(nameof(module));
this.output = output ?? throw new ArgumentNullException(nameof(output)); this.output = output ?? throw new ArgumentNullException(nameof(output));

14
ICSharpCode.Decompiler/Disassembler/IEntityProcessor.cs

@ -27,18 +27,18 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
public interface IEntityProcessor public interface IEntityProcessor
{ {
IReadOnlyCollection<InterfaceImplementationHandle> Process(PEFile module, IReadOnlyCollection<InterfaceImplementationHandle> items); IReadOnlyCollection<InterfaceImplementationHandle> Process(MetadataFile module, IReadOnlyCollection<InterfaceImplementationHandle> items);
IReadOnlyCollection<TypeDefinitionHandle> Process(PEFile module, IReadOnlyCollection<TypeDefinitionHandle> items); IReadOnlyCollection<TypeDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<TypeDefinitionHandle> items);
IReadOnlyCollection<MethodDefinitionHandle> Process(PEFile module, IReadOnlyCollection<MethodDefinitionHandle> items); IReadOnlyCollection<MethodDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<MethodDefinitionHandle> items);
IReadOnlyCollection<PropertyDefinitionHandle> Process(PEFile module, IReadOnlyCollection<PropertyDefinitionHandle> items); IReadOnlyCollection<PropertyDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<PropertyDefinitionHandle> items);
IReadOnlyCollection<EventDefinitionHandle> Process(PEFile module, IReadOnlyCollection<EventDefinitionHandle> items); IReadOnlyCollection<EventDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<EventDefinitionHandle> items);
IReadOnlyCollection<FieldDefinitionHandle> Process(PEFile module, IReadOnlyCollection<FieldDefinitionHandle> items); IReadOnlyCollection<FieldDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<FieldDefinitionHandle> items);
IReadOnlyCollection<CustomAttributeHandle> Process(PEFile module, IReadOnlyCollection<CustomAttributeHandle> items); IReadOnlyCollection<CustomAttributeHandle> Process(MetadataFile module, IReadOnlyCollection<CustomAttributeHandle> items);
} }
} }

28
ICSharpCode.Decompiler/Disassembler/SortByNameProcessor.cs

@ -30,52 +30,52 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
public class SortByNameProcessor : IEntityProcessor public class SortByNameProcessor : IEntityProcessor
{ {
public IReadOnlyCollection<InterfaceImplementationHandle> Process(PEFile module, public IReadOnlyCollection<InterfaceImplementationHandle> Process(MetadataFile module,
IReadOnlyCollection<InterfaceImplementationHandle> items) IReadOnlyCollection<InterfaceImplementationHandle> items)
{ {
return items.OrderBy(item => GetSortKey(item, module)).ToArray(); return items.OrderBy(item => GetSortKey(item, module)).ToArray();
} }
public IReadOnlyCollection<TypeDefinitionHandle> Process(PEFile module, public IReadOnlyCollection<TypeDefinitionHandle> Process(MetadataFile module,
IReadOnlyCollection<TypeDefinitionHandle> items) IReadOnlyCollection<TypeDefinitionHandle> items)
{ {
return items.OrderBy(item => GetSortKey(item, module)).ToArray(); return items.OrderBy(item => GetSortKey(item, module)).ToArray();
} }
public IReadOnlyCollection<MethodDefinitionHandle> Process(PEFile module, public IReadOnlyCollection<MethodDefinitionHandle> Process(MetadataFile module,
IReadOnlyCollection<MethodDefinitionHandle> items) IReadOnlyCollection<MethodDefinitionHandle> items)
{ {
return items.OrderBy(item => GetSortKey(item, module)).ToArray(); return items.OrderBy(item => GetSortKey(item, module)).ToArray();
} }
public IReadOnlyCollection<PropertyDefinitionHandle> Process(PEFile module, public IReadOnlyCollection<PropertyDefinitionHandle> Process(MetadataFile module,
IReadOnlyCollection<PropertyDefinitionHandle> items) IReadOnlyCollection<PropertyDefinitionHandle> items)
{ {
return items.OrderBy(item => GetSortKey(item, module)).ToArray(); return items.OrderBy(item => GetSortKey(item, module)).ToArray();
} }
public IReadOnlyCollection<EventDefinitionHandle> Process(PEFile module, public IReadOnlyCollection<EventDefinitionHandle> Process(MetadataFile module,
IReadOnlyCollection<EventDefinitionHandle> items) IReadOnlyCollection<EventDefinitionHandle> items)
{ {
return items.OrderBy(item => GetSortKey(item, module)).ToArray(); return items.OrderBy(item => GetSortKey(item, module)).ToArray();
} }
public IReadOnlyCollection<FieldDefinitionHandle> Process(PEFile module, public IReadOnlyCollection<FieldDefinitionHandle> Process(MetadataFile module,
IReadOnlyCollection<FieldDefinitionHandle> items) IReadOnlyCollection<FieldDefinitionHandle> items)
{ {
return items.OrderBy(item => GetSortKey(item, module)).ToArray(); return items.OrderBy(item => GetSortKey(item, module)).ToArray();
} }
public IReadOnlyCollection<CustomAttributeHandle> Process(PEFile module, public IReadOnlyCollection<CustomAttributeHandle> Process(MetadataFile module,
IReadOnlyCollection<CustomAttributeHandle> items) IReadOnlyCollection<CustomAttributeHandle> items)
{ {
return items.OrderBy(item => GetSortKey(item, module)).ToArray(); return items.OrderBy(item => GetSortKey(item, module)).ToArray();
} }
private static string GetSortKey(TypeDefinitionHandle handle, PEFile module) => private static string GetSortKey(TypeDefinitionHandle handle, MetadataFile module) =>
handle.GetFullTypeName(module.Metadata).ToILNameString(); handle.GetFullTypeName(module.Metadata).ToILNameString();
private static string GetSortKey(MethodDefinitionHandle handle, PEFile module) private static string GetSortKey(MethodDefinitionHandle handle, MetadataFile module)
{ {
PlainTextOutput output = new PlainTextOutput(); PlainTextOutput output = new PlainTextOutput();
MethodDefinition definition = module.Metadata.GetMethodDefinition(handle); MethodDefinition definition = module.Metadata.GetMethodDefinition(handle);
@ -97,22 +97,22 @@ namespace ICSharpCode.Decompiler.Disassembler
return output.ToString(); return output.ToString();
} }
private static string GetSortKey(InterfaceImplementationHandle handle, PEFile module) => private static string GetSortKey(InterfaceImplementationHandle handle, MetadataFile module) =>
module.Metadata.GetInterfaceImplementation(handle) module.Metadata.GetInterfaceImplementation(handle)
.Interface .Interface
.GetFullTypeName(module.Metadata) .GetFullTypeName(module.Metadata)
.ToILNameString(); .ToILNameString();
private static string GetSortKey(FieldDefinitionHandle handle, PEFile module) => private static string GetSortKey(FieldDefinitionHandle handle, MetadataFile module) =>
module.Metadata.GetString(module.Metadata.GetFieldDefinition(handle).Name); module.Metadata.GetString(module.Metadata.GetFieldDefinition(handle).Name);
private static string GetSortKey(PropertyDefinitionHandle handle, PEFile module) => private static string GetSortKey(PropertyDefinitionHandle handle, MetadataFile module) =>
module.Metadata.GetString(module.Metadata.GetPropertyDefinition(handle).Name); module.Metadata.GetString(module.Metadata.GetPropertyDefinition(handle).Name);
private static string GetSortKey(EventDefinitionHandle handle, PEFile module) => private static string GetSortKey(EventDefinitionHandle handle, MetadataFile module) =>
module.Metadata.GetString(module.Metadata.GetEventDefinition(handle).Name); module.Metadata.GetString(module.Metadata.GetEventDefinition(handle).Name);
private static string GetSortKey(CustomAttributeHandle handle, PEFile module) => private static string GetSortKey(CustomAttributeHandle handle, MetadataFile module) =>
module.Metadata.GetCustomAttribute(handle) module.Metadata.GetCustomAttribute(handle)
.Constructor .Constructor
.GetDeclaringType(module.Metadata) .GetDeclaringType(module.Metadata)

26
ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.IL
output.Write($"[{interval.Start:x4}..{interval.InclusiveEnd:x4}] "); output.Write($"[{interval.Start:x4}..{interval.InclusiveEnd:x4}] ");
} }
public static void WriteTo(this EntityHandle entity, PEFile module, ITextOutput output, Metadata.MetadataGenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature) public static void WriteTo(this EntityHandle entity, MetadataFile module, ITextOutput output, Metadata.MetadataGenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{ {
if (entity.IsNil) if (entity.IsNil)
{ {
@ -138,7 +138,7 @@ namespace ICSharpCode.Decompiler.IL
case HandleKind.FieldDefinition: case HandleKind.FieldDefinition:
{ {
var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)entity); var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)entity);
signature = fd.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new Metadata.MetadataGenericContext(fd.GetDeclaringType(), module)); signature = fd.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new Metadata.MetadataGenericContext(fd.GetDeclaringType(), metadata));
signature(ILNameSyntax.SignatureNoNamedTypeParameters); signature(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
((EntityHandle)fd.GetDeclaringType()).WriteTo(module, output, default, ILNameSyntax.TypeName); ((EntityHandle)fd.GetDeclaringType()).WriteTo(module, output, default, ILNameSyntax.TypeName);
@ -149,7 +149,7 @@ namespace ICSharpCode.Decompiler.IL
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
{ {
var md = metadata.GetMethodDefinition((MethodDefinitionHandle)entity); var md = metadata.GetMethodDefinition((MethodDefinitionHandle)entity);
methodSignature = md.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new Metadata.MetadataGenericContext((MethodDefinitionHandle)entity, module)); methodSignature = md.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new Metadata.MetadataGenericContext((MethodDefinitionHandle)entity, metadata));
methodSignature.Header.WriteTo(output); methodSignature.Header.WriteTo(output);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
@ -198,7 +198,7 @@ namespace ICSharpCode.Decompiler.IL
if (j > 0) if (j > 0)
output.Write(", "); output.Write(", ");
var constraint = metadata.GetGenericParameterConstraint(constraints[j]); var constraint = metadata.GetGenericParameterConstraint(constraints[j]);
constraint.Type.WriteTo(module, output, new Metadata.MetadataGenericContext((MethodDefinitionHandle)entity, module), ILNameSyntax.TypeName); constraint.Type.WriteTo(module, output, new Metadata.MetadataGenericContext((MethodDefinitionHandle)entity, metadata), ILNameSyntax.TypeName);
} }
output.Write(") "); output.Write(") ");
} }
@ -227,7 +227,7 @@ namespace ICSharpCode.Decompiler.IL
methodSignature.Header.WriteTo(output); methodSignature.Header.WriteTo(output);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
WriteParent(output, module, metadata, mr.Parent, genericContext, syntax); WriteParent(output, module, mr.Parent, genericContext, syntax);
output.Write("::"); output.Write("::");
output.WriteReference(module, entity, DisassemblerHelpers.Escape(memberName)); output.WriteReference(module, entity, DisassemblerHelpers.Escape(memberName));
WriteParameterList(output, methodSignature); WriteParameterList(output, methodSignature);
@ -236,7 +236,7 @@ namespace ICSharpCode.Decompiler.IL
var fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext); var fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);
fieldSignature(ILNameSyntax.SignatureNoNamedTypeParameters); fieldSignature(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
WriteParent(output, module, metadata, mr.Parent, genericContext, syntax); WriteParent(output, module, mr.Parent, genericContext, syntax);
output.Write("::"); output.Write("::");
output.WriteReference(module, entity, DisassemblerHelpers.Escape(memberName)); output.WriteReference(module, entity, DisassemblerHelpers.Escape(memberName));
break; break;
@ -279,7 +279,7 @@ namespace ICSharpCode.Decompiler.IL
methodSignature.Header.WriteTo(output); methodSignature.Header.WriteTo(output);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
WriteParent(output, module, metadata, memberReference.Parent, genericContext, syntax); WriteParent(output, module, memberReference.Parent, genericContext, syntax);
output.Write("::"); output.Write("::");
output.Write(DisassemblerHelpers.Escape(memberName)); output.Write(DisassemblerHelpers.Escape(memberName));
WriteTypeParameterList(output, syntax, substitution); WriteTypeParameterList(output, syntax, substitution);
@ -352,24 +352,24 @@ namespace ICSharpCode.Decompiler.IL
} }
} }
static void WriteParent(ITextOutput output, PEFile module, MetadataReader metadata, EntityHandle parentHandle, Metadata.MetadataGenericContext genericContext, ILNameSyntax syntax) static void WriteParent(ITextOutput output, MetadataFile metadataFile, EntityHandle parentHandle, Metadata.MetadataGenericContext genericContext, ILNameSyntax syntax)
{ {
switch (parentHandle.Kind) switch (parentHandle.Kind)
{ {
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
var methodDef = metadata.GetMethodDefinition((MethodDefinitionHandle)parentHandle); var methodDef = metadataFile.Metadata.GetMethodDefinition((MethodDefinitionHandle)parentHandle);
((EntityHandle)methodDef.GetDeclaringType()).WriteTo(module, output, genericContext, syntax); ((EntityHandle)methodDef.GetDeclaringType()).WriteTo(metadataFile, output, genericContext, syntax);
break; break;
case HandleKind.ModuleReference: case HandleKind.ModuleReference:
output.Write('['); output.Write('[');
var moduleRef = metadata.GetModuleReference((ModuleReferenceHandle)parentHandle); var moduleRef = metadataFile.Metadata.GetModuleReference((ModuleReferenceHandle)parentHandle);
output.Write(metadata.GetString(moduleRef.Name)); output.Write(metadataFile.Metadata.GetString(moduleRef.Name));
output.Write(']'); output.Write(']');
break; break;
case HandleKind.TypeDefinition: case HandleKind.TypeDefinition:
case HandleKind.TypeReference: case HandleKind.TypeReference:
case HandleKind.TypeSpecification: case HandleKind.TypeSpecification:
parentHandle.WriteTo(module, output, genericContext, syntax); parentHandle.WriteTo(metadataFile, output, genericContext, syntax);
break; break;
} }
} }

2
ICSharpCode.Decompiler/Metadata/MetadataGenericContext.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.Metadata
readonly TypeDefinitionHandle declaringType; readonly TypeDefinitionHandle declaringType;
readonly MethodDefinitionHandle method; readonly MethodDefinitionHandle method;
public MetadataGenericContext(MethodDefinitionHandle method, PEFile module) public MetadataGenericContext(MethodDefinitionHandle method, MetadataFile module)
{ {
this.metadata = module.Metadata; this.metadata = module.Metadata;
this.method = method; this.method = method;

51
ICSharpCode.Decompiler/Metadata/PEFile.cs

@ -32,6 +32,43 @@ using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Metadata namespace ICSharpCode.Decompiler.Metadata
{ {
public class MetadataFile
{
public enum MetadataFileKind
{
PortableExecutable,
ProgramDebugDatabase,
Metadata
}
public string FileName { get; }
public MetadataFileKind Kind { get; }
public MetadataReader Metadata { get; }
public virtual int MetadataOffset { get; }
public virtual bool IsEmbedded { get; }
public MetadataFile(string fileName, MetadataReaderProvider metadata, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, int metadataOffset = 0, bool isEmbedded = false)
{
this.FileName = fileName;
this.Metadata = metadata.GetMetadataReader(metadataOptions);
this.MetadataOffset = metadataOffset;
this.IsEmbedded = isEmbedded;
this.Kind = isEmbedded || Path.GetExtension(fileName).Equals(".pdb", StringComparison.OrdinalIgnoreCase) ? MetadataFileKind.ProgramDebugDatabase : MetadataFileKind.Metadata;
}
private protected MetadataFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
{
this.FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
_ = reader ?? throw new ArgumentNullException(nameof(reader));
if (!reader.HasMetadata)
throw new PEFileNotSupportedException("PE file does not contain any managed metadata.");
this.Metadata = reader.GetMetadataReader(metadataOptions);
this.Kind = MetadataFileKind.PortableExecutable;
}
}
/// <summary> /// <summary>
/// PEFile is the main class the decompiler uses to represent a metadata assembly/module. /// 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. /// Every file on disk can be loaded into a standalone PEFile instance.
@ -46,11 +83,9 @@ namespace ICSharpCode.Decompiler.Metadata
/// decompiled type systems. /// decompiled type systems.
/// </remarks> /// </remarks>
[DebuggerDisplay("{FileName}")] [DebuggerDisplay("{FileName}")]
public class PEFile : IDisposable, TypeSystem.IModuleReference public class PEFile : MetadataFile, IDisposable, TypeSystem.IModuleReference
{ {
public string FileName { get; }
public PEReader Reader { get; } public PEReader Reader { get; }
public MetadataReader Metadata { get; }
public PEFile(string fileName, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default) public PEFile(string fileName, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
: this(fileName, new PEReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), streamOptions), metadataOptions) : this(fileName, new PEReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), streamOptions), metadataOptions)
@ -63,16 +98,16 @@ namespace ICSharpCode.Decompiler.Metadata
} }
public PEFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default) public PEFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
: base(fileName, reader, metadataOptions)
{ {
this.FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); this.Reader = reader;
this.Reader = 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);
} }
public bool IsAssembly => Metadata.IsAssembly; public bool IsAssembly => Metadata.IsAssembly;
public override bool IsEmbedded => false;
public override int MetadataOffset => Reader.PEHeaders.MetadataStartOffset;
string? name; string? name;
public string Name { public string Name {

2
ICSharpCode.Decompiler/Output/ITextOutput.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.Decompiler
void Write(string text); void Write(string text);
void WriteLine(); void WriteLine();
void WriteReference(OpCodeInfo opCode, bool omitSuffix = false); void WriteReference(OpCodeInfo opCode, bool omitSuffix = false);
void WriteReference(PEFile module, Handle handle, string text, string protocol = "decompile", bool isDefinition = false); void WriteReference(MetadataFile metadata, Handle handle, string text, string protocol = "decompile", bool isDefinition = false);
void WriteReference(IType type, string text, bool isDefinition = false); void WriteReference(IType type, string text, bool isDefinition = false);
void WriteReference(IMember member, string text, bool isDefinition = false); void WriteReference(IMember member, string text, bool isDefinition = false);
void WriteLocalReference(string text, object reference, bool isDefinition = false); void WriteLocalReference(string text, object reference, bool isDefinition = false);

4
ICSharpCode.Decompiler/Output/PlainTextOutput.cs

@ -123,7 +123,7 @@ namespace ICSharpCode.Decompiler
} }
} }
public void WriteReference(PEFile module, Handle handle, string text, string protocol = "decompile", bool isDefinition = false) public void WriteReference(MetadataFile module, Handle handle, string text, string protocol = "decompile", bool isDefinition = false)
{ {
Write(text); Write(text);
} }
@ -225,7 +225,7 @@ namespace ICSharpCode.Decompiler
actions.Add(target => target.WriteReference(opCode)); actions.Add(target => target.WriteReference(opCode));
} }
public void WriteReference(PEFile module, Handle handle, string text, string protocol = "decompile", bool isDefinition = false) public void WriteReference(MetadataFile module, Handle handle, string text, string protocol = "decompile", bool isDefinition = false)
{ {
actions.Add(target => target.WriteReference(module, handle, text, protocol, isDefinition)); actions.Add(target => target.WriteReference(module, handle, text, protocol, isDefinition));
} }

88
ICSharpCode.ILSpyX/LoadedAssembly.cs

@ -50,32 +50,39 @@ namespace ICSharpCode.ILSpyX
/// * a non-existant file /// * a non-existant file
/// * a file of unknown format that could not be loaded /// * a file of unknown format that could not be loaded
/// * a .nupkg file or .NET core bundle /// * a .nupkg file or .NET core bundle
/// * a standalone portable pdb file or metadata stream
/// * a file that is still being loaded in the background /// * a file that is still being loaded in the background
/// </summary> /// </summary>
[DebuggerDisplay("[LoadedAssembly {shortName}]")] [DebuggerDisplay("[LoadedAssembly {shortName}]")]
public sealed class LoadedAssembly public sealed class LoadedAssembly
{ {
/// <summary> /// <summary>
/// Maps from PEFile (successfully loaded .NET module) back to the LoadedAssembly instance /// Maps from MetadataFile (successfully loaded .NET module) back to the LoadedAssembly instance
/// that was used to load the module. /// that was used to load the module.
/// </summary> /// </summary>
internal static readonly ConditionalWeakTable<PEFile, LoadedAssembly> loadedAssemblies = new ConditionalWeakTable<PEFile, LoadedAssembly>(); internal static readonly ConditionalWeakTable<MetadataFile, LoadedAssembly> loadedAssemblies = new ConditionalWeakTable<MetadataFile, LoadedAssembly>();
public sealed class LoadResult public sealed class LoadResult
{ {
public PEFile? PEFile { get; } public MetadataFile? MetadataFile { get; }
public Exception? PEFileLoadException { get; } public PEFile? PEFile => MetadataFile as PEFile;
public Exception? FileLoadException { get; }
public LoadedPackage? Package { get; } public LoadedPackage? Package { get; }
public LoadResult(PEFile peFile) public LoadResult(PEFile peFile)
{ {
this.PEFile = peFile ?? throw new ArgumentNullException(nameof(peFile)); this.MetadataFile = peFile ?? throw new ArgumentNullException(nameof(peFile));
} }
public LoadResult(Exception peFileLoadException, LoadedPackage package) public LoadResult(Exception fileLoadException, LoadedPackage package)
{ {
this.PEFileLoadException = peFileLoadException ?? throw new ArgumentNullException(nameof(peFileLoadException)); this.FileLoadException = fileLoadException ?? throw new ArgumentNullException(nameof(fileLoadException));
this.Package = package ?? throw new ArgumentNullException(nameof(package)); this.Package = package ?? throw new ArgumentNullException(nameof(package));
} }
public LoadResult(Exception fileLoadException, MetadataFile metadataFile)
{
this.FileLoadException = fileLoadException ?? throw new ArgumentNullException(nameof(fileLoadException));
this.MetadataFile = metadataFile ?? throw new ArgumentNullException(nameof(metadataFile));
}
} }
readonly Task<LoadResult> loadingTask; readonly Task<LoadResult> loadingTask;
@ -170,7 +177,7 @@ namespace ICSharpCode.ILSpyX
if (loadResult.PEFile != null) if (loadResult.PEFile != null)
return loadResult.PEFile; return loadResult.PEFile;
else else
throw loadResult.PEFileLoadException!; throw loadResult.FileLoadException!;
} }
/// <summary> /// <summary>
@ -260,31 +267,38 @@ namespace ICSharpCode.ILSpyX
get { get {
if (IsLoaded && !HasLoadError) if (IsLoaded && !HasLoadError)
{ {
PEFile? module = GetPEFileOrNull(); var result = GetLoadResultAsync().GetAwaiter().GetResult();
var metadata = module?.Metadata; if (result.MetadataFile != null)
string? versionOrInfo = null;
if (metadata != null)
{ {
if (metadata.IsAssembly) switch (result.MetadataFile.Kind)
{
versionOrInfo = metadata.GetAssemblyDefinition().Version?.ToString();
string tfId = GetTargetFrameworkIdAsync().GetAwaiter().GetResult();
if (!string.IsNullOrEmpty(tfId))
versionOrInfo += ", " + tfId.Replace("Version=", " ");
}
else
{ {
versionOrInfo = ".netmodule"; case MetadataFile.MetadataFileKind.PortableExecutable:
var metadata = result.MetadataFile.Metadata;
string? versionOrInfo;
if (metadata.IsAssembly)
{
versionOrInfo = metadata.GetAssemblyDefinition().Version?.ToString();
string tfId = GetTargetFrameworkIdAsync().GetAwaiter().GetResult();
if (!string.IsNullOrEmpty(tfId))
versionOrInfo += ", " + tfId.Replace("Version=", " ");
}
else
{
versionOrInfo = ".netmodule";
}
if (versionOrInfo == null)
return ShortName;
return string.Format("{0} ({1})", ShortName, versionOrInfo);
case MetadataFile.MetadataFileKind.ProgramDebugDatabase:
return ShortName + " (Debug Metadata)";
case MetadataFile.MetadataFileKind.Metadata:
return ShortName + " (Metadata)";
default:
return ShortName;
} }
} }
if (versionOrInfo == null)
return ShortName;
return string.Format("{0} ({1})", ShortName, versionOrInfo);
}
else
{
return ShortName;
} }
return ShortName;
} }
} }
@ -374,6 +388,24 @@ namespace ICSharpCode.ILSpyX
return new LoadResult(loadAssemblyException, zip); return new LoadResult(loadAssemblyException, zip);
} }
catch (InvalidDataException) catch (InvalidDataException)
{
// Not a compressed module, try other options below
}
// or it could be a standalone portable PDB
try
{
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
var metadata = MetadataReaderProvider.FromMetadataStream(fileStream, MetadataStreamOptions.PrefetchMetadata);
var metadataFile = new MetadataFile(fileName, metadata);
lock (loadedAssemblies)
{
loadedAssemblies.Add(metadataFile, this);
}
return new LoadResult(loadAssemblyException, metadataFile);
}
}
catch (Exception)
{ {
throw loadAssemblyException; throw loadAssemblyException;
} }

2
ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpyX
return GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settings)); return GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settings));
} }
public static LoadedAssembly GetLoadedAssembly(this PEFile file) public static LoadedAssembly GetLoadedAssembly(this MetadataFile file)
{ {
if (file == null) if (file == null)
throw new ArgumentNullException(nameof(file)); throw new ArgumentNullException(nameof(file));

4
ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs

@ -39,7 +39,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider
// try to open portable pdb file/embedded pdb info: // try to open portable pdb file/embedded pdb info:
if (TryOpenPortablePdb(module, out var provider, out var pdbFileName)) if (TryOpenPortablePdb(module, out var provider, out var pdbFileName))
{ {
return new PortableDebugInfoProvider(module.FileName, provider, pdbFileName); return new PortableDebugInfoProvider(module.FileName, provider, MetadataReaderOptions.Default, pdbFileName);
} }
else else
{ {
@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider
{ {
stream.Position = 0; stream.Position = 0;
var provider = MetadataReaderProvider.FromPortablePdbStream(stream); var provider = MetadataReaderProvider.FromPortablePdbStream(stream);
return new PortableDebugInfoProvider(module.FileName, provider, pdbFileName); return new PortableDebugInfoProvider(module.FileName, provider, MetadataReaderOptions.Default, pdbFileName);
} }
} }

9
ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs

@ -23,6 +23,7 @@ using System.IO;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using ICSharpCode.Decompiler.DebugInfo; using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
#nullable enable #nullable enable
@ -34,15 +35,18 @@ namespace ICSharpCode.ILSpyX.PdbProvider
string? pdbFileName; string? pdbFileName;
string moduleFileName; string moduleFileName;
readonly MetadataReaderProvider provider; readonly MetadataReaderProvider provider;
MetadataReaderOptions options;
bool hasError; bool hasError;
internal bool IsEmbedded => pdbFileName == null; internal bool IsEmbedded => pdbFileName == null;
public PortableDebugInfoProvider(string moduleFileName, MetadataReaderProvider provider, public PortableDebugInfoProvider(string moduleFileName, MetadataReaderProvider provider,
MetadataReaderOptions options = MetadataReaderOptions.Default,
string? pdbFileName = null) string? pdbFileName = null)
{ {
this.moduleFileName = moduleFileName ?? throw new ArgumentNullException(nameof(moduleFileName)); this.moduleFileName = moduleFileName ?? throw new ArgumentNullException(nameof(moduleFileName));
this.provider = provider ?? throw new ArgumentNullException(nameof(provider)); this.provider = provider ?? throw new ArgumentNullException(nameof(provider));
this.options = options;
this.pdbFileName = pdbFileName; this.pdbFileName = pdbFileName;
} }
@ -233,5 +237,10 @@ namespace ICSharpCode.ILSpyX.PdbProvider
return extraTypeInfo.TupleElementNames != null || extraTypeInfo.DynamicFlags != null; return extraTypeInfo.TupleElementNames != null || extraTypeInfo.DynamicFlags != null;
} }
public MetadataFile ToMetadataFile()
{
return new MetadataFile(SourceFileName, provider, options, 0, IsEmbedded);
}
} }
} }

6
ILSpy/EntityReference.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.ILSpy
[DebuggerDisplay("EntityReference Module={Module}, Handle={Handle}, Protocol={Protocol}")] [DebuggerDisplay("EntityReference Module={Module}, Handle={Handle}, Protocol={Protocol}")]
public class EntityReference public class EntityReference
{ {
readonly PEFile? peFile; readonly MetadataFile? peFile;
public string Module { get; } public string Module { get; }
public Handle Handle { get; } public Handle Handle { get; }
public string Protocol { get; } public string Protocol { get; }
@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy
this.Protocol = protocol ?? "decompile"; this.Protocol = protocol ?? "decompile";
} }
public EntityReference(PEFile module, Handle handle, string protocol = "decompile") public EntityReference(MetadataFile module, Handle handle, string protocol = "decompile")
{ {
this.peFile = module; this.peFile = module;
this.Module = module.FileName; this.Module = module.FileName;
@ -54,7 +54,7 @@ namespace ICSharpCode.ILSpy
this.Protocol = protocol; this.Protocol = protocol;
} }
public PEFile? ResolveAssembly(AssemblyList context) public MetadataFile? ResolveAssembly(AssemblyList context)
{ {
return peFile ?? context.FindAssembly(Module)?.GetPEFileOrNull(); return peFile ?? context.FindAssembly(Module)?.GetPEFileOrNull();
} }

6
ILSpy/ExtensionMethods.cs

@ -19,17 +19,13 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
@ -76,7 +72,7 @@ namespace ICSharpCode.ILSpy
return result; return result;
} }
public static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this PEFile file) public static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this MetadataFile file)
{ {
return LoadedAssemblyExtensions.GetLoadedAssembly(file) return LoadedAssemblyExtensions.GetLoadedAssembly(file)
.GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(MainWindow.Instance.CurrentDecompilerSettings)); .GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(MainWindow.Instance.CurrentDecompilerSettings));

1
ILSpy/Images/Header.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.icon-canvas-transparent{opacity:0;fill:#f6f6f6}.icon-vs-out{fill:#f6f6f6}.icon-vs-bg{fill:#424242}.icon-vs-fg{fill:#f0eff1}.icon-vs-blue{fill:#1ba1e2}</style><path class="icon-canvas-transparent" d="M16 16H0V0h16v16z" id="canvas"/><path class="icon-vs-out" d="M15 0v16H1V0h14z" id="outline"/><path class="icon-vs-bg" d="M2 1v14h12V1H2zm11 13H3V2h10v12zm-1-1H4v-1h8v1zm0-2H4v-1h8v1zm0-2H4V8h8v1z" id="iconBg"/><path class="icon-vs-fg" d="M11 5H5V4h6v1zm2-3v12H3V2h10zm-1 10H4v1h8v-1zm0-2H4v1h8v-1zm0-2H4v1h8V8zm0-5H4v3h8V3z" id="iconFg"/><path class="icon-vs-blue" d="M12 3H4v3h8V3zm-1 2H5V4h6v1z" id="colorImportance"/></svg>

After

Width:  |  Height:  |  Size: 693 B

11
ILSpy/Images/Header.xaml

@ -0,0 +1,11 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M1,16L15,16 15,0 1,0z" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M12,9L4,9 4,8 12,8z M12,11L4,11 4,10 12,10z M12,13L4,13 4,12 12,12z M13,14L3,14 3,2 13,2z M2,15L14,15 14,1 2,1z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M12,3L4,3 4,6 12,6z M12,8L4,8 4,9 12,9z M12,10L4,10 4,11 12,11z M12,12L4,12 4,13 12,13z M13,14L3,14 3,2 13,2z M11,5L5,5 5,4 11,4z" />
<GeometryDrawing Brush="#FF1BA1E2" Geometry="F1M11,5L5,5 5,4 11,4z M12,3L4,3 4,6 12,6z" />
</DrawingGroup.Children>
</DrawingGroup>

1
ILSpy/Images/Heap.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.icon-canvas-transparent{opacity:0;fill:#f6f6f6}.icon-vs-out{fill:#f6f6f6}.icon-vs-bg{fill:#424242}.icon-vs-fg{fill:#f0eff1}</style><path class="icon-canvas-transparent" d="M15.993 16h-16V0h16v16z" id="canvas"/><path class="icon-vs-out" d="M16 15H1V1h15v14z" id="outline"/><path class="icon-vs-fg" d="M14 13H3v-2h11v2zm0-3H3V8h11v2zm0-3H3V5h11v2z" id="iconFg"/><g id="iconBg"><path class="icon-vs-bg" d="M2 2v12h13V2H2zm12 11H3v-2h11v2zm0-3H3V8h11v2zm0-3H3V5h11v2z"/></g></svg>

After

Width:  |  Height:  |  Size: 544 B

10
ILSpy/Images/Heap.xaml

@ -0,0 +1,10 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M15.993,16L-0.00699999999999967,16 -0.00699999999999967,0 15.993,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M1,15L16,15 16,1 1,1z" />
<GeometryDrawing Brush="#FFEFEFF0" Geometry="F1M14,7L3,7 3,5 14,5z M14,10L3,10 3,8 14,8z M14,13L3,13 3,11 14,11z" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M14,7L3,7 3,5 14,5z M14,10L3,10 3,8 14,8z M14,13L3,13 3,11 14,11z M2,14L15,14 15,2 2,2z" />
</DrawingGroup.Children>
</DrawingGroup>

10
ILSpy/Images/Images.cs

@ -56,6 +56,16 @@ namespace ICSharpCode.ILSpy
public static readonly ImageSource ReferenceFolder = Load("ReferenceFolder"); public static readonly ImageSource ReferenceFolder = Load("ReferenceFolder");
public static readonly ImageSource NuGet = Load(null, "Images/NuGet.png"); public static readonly ImageSource NuGet = Load(null, "Images/NuGet.png");
public static readonly ImageSource MetadataFile = Load("MetadataFile");
public static readonly ImageSource ProgramDebugDatabase = Load("ProgramDebugDatabase");
public static readonly ImageSource Metadata = Load("Metadata");
public static readonly ImageSource Heap = Load("Heap");
public static readonly ImageSource Header = Load("Header");
public static readonly ImageSource MetadataTable = Load("MetadataTable");
public static readonly ImageSource MetadataTableGroup = Load("MetadataTableGroup");
public static readonly ImageSource ListFolder = Load("ListFolder");
public static readonly ImageSource ListFolderOpen = Load("ListFolder.Open");
public static readonly ImageSource SubTypes = Load("SubTypes"); public static readonly ImageSource SubTypes = Load("SubTypes");
public static readonly ImageSource SuperTypes = Load("SuperTypes"); public static readonly ImageSource SuperTypes = Load("SuperTypes");

1
ILSpy/Images/ListFolder.Open.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.icon-canvas-transparent{opacity:0;fill:#f6f6f6}.icon-vs-out{fill:#f6f6f6}.icon-vs-fg{fill:#f0eff1}.icon-folder{fill:#dcb67a}.icon-vs-bg{fill:#424242}</style><path class="icon-canvas-transparent" d="M0 0h16v16H0V0z" id="canvas"/><path class="icon-vs-out" d="M16 6.969V16H5v-2.031H2s-.86-.022-1.43-.566c-.343-.332-.57-.817-.57-1.434v-9c0-1.303 1.005-2 2-2h7.116l1 2H13c.97 0 2 .701 2 2v2h1z" id="outline"/><path class="icon-vs-fg" d="M7 9h1v1H7V9zm0 3h1v-1H7v1zm0 2h1v-1H7v1zm2 0h5v-1H9v1zm0-2h5v-1H9v1zm0-3v1h5V9H9z" id="iconFg"/><g id="iconBg"><path class="icon-folder" d="M2 3h6l1 2h4v2h1V5c0-1-1.236-1-1-1H9.5l-1-2H2S1 2 1 3v9c0 .97.94.984.997.984H2V3z"/><path class="icon-folder" d="M5 8H4l-2 5h3z"/><path class="icon-vs-bg" d="M6 8v7h9V8H6zm1 1h1v1H7V9zm0 2h1v1H7v-1zm0 3v-1h1v1H7zm7 0H9v-1h5v1zm0-2H9v-1h5v1zm0-2H9V9h5v1z"/></g></svg>

After

Width:  |  Height:  |  Size: 907 B

12
ILSpy/Images/ListFolder.Open.xaml

@ -0,0 +1,12 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M0,0L16,0 16,16 0,16z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M16,6.9688L16,6.9998 16,8.1648 16,15.9998 5,15.9998 5,13.9688 2,13.9688C2,13.9688 1.14,13.9478 0.57,13.4038 0.227,13.0718 0,12.5858 0,11.9688L0,2.9688C0,1.6658,1.005,0.9688,2,0.9688L9.116,0.9688 10.116,2.9688 13,2.9688C13.97,2.9688,15,3.6698,15,4.9688L15,6.9688z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M9,10L14,10 14,9 9,9z M9,12L14,12 14,11 9,11z M9,14L14,14 14,13 9,13z M7,14L8,14 8,13 7,13z M7,12L8,12 8,11 7,11z M7,9L8,9 8,10 7,10z" />
<GeometryDrawing Brush="#FFDCB67A" Geometry="F1M2,3L8,3 9,5 13,5 13,7 14,7 14,5C14,4,12.764,4,13,4L9.5,4 8.5,2 2,2C2,2,1,2,1,3L1,12C1,12.97,1.94,12.984,1.997,12.984L2,12.984z" />
<GeometryDrawing Brush="#FFDCB67A" Geometry="F1M5,8L4,8 2,13 5,13z" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M14,10L9,10 9,9 14,9z M14,12L9,12 9,11 14,11z M14,14L9,14 9,13 14,13z M7,13L8,13 8,14 7,14z M7,11L8,11 8,12 7,12z M7,9L8,9 8,10 7,10z M6,15L15,15 15,8 6,8z" />
</DrawingGroup.Children>
</DrawingGroup>

1
ILSpy/Images/ListFolder.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{fill:#F6F6F6;} .icon-folder{fill:#DCB67A;} .icon-vs-fg{fill:#F0EFF1;} .icon-vs-bg{fill:#424242;}</style><path class="icon-canvas-transparent" d="M0 0h16v16h-16v-16z" id="canvas"/><path class="icon-vs-out" d="M14.996 4.5v8c0 .827-.673 1.5-1.5 1.5h-2.496v2h-11v-13.5c0-.827.673-1.5 1.5-1.5h8.11l1 2h2.886c.827 0 1.5.673 1.5 1.5z" id="outline"/><g id="iconBg"><path class="icon-folder" d="M13.496 4h-3.504l-1-2h-7.492c-.275 0-.5.224-.5.5v4.5h10v6h2.496c.277 0 .5-.224.5-.5v-8c0-.276-.223-.5-.5-.5zm-11.496 0v-1h6.374l.5 1h-6.874z"/><path class="icon-vs-bg" d="M1 8v7h9v-7h-9zm1 1h1v1h-1v-1zm0 2h1v1h-1v-1zm0 3v-1h1v1h-1zm7 0h-5v-1h5v1zm0-2h-5v-1h5v1zm0-2h-5v-1h5v1z"/></g><path class="icon-vs-fg" d="M2 9h1v1h-1v-1zm0 2h1v1h-1v-1zm0 3v-1h1v1h-1zm7 0h-5v-1h5v1zm0-2h-5v-1h5v1zm0-2h-5v-1h5v1zm-7-7h6.374l.5 1h-6.874v-1z" id="iconFg"/></svg>

After

Width:  |  Height:  |  Size: 1015 B

11
ILSpy/Images/ListFolder.xaml

@ -0,0 +1,11 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M0,0L16,0 16,16 0,16z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M14.9961,4.5L14.9961,12.5C14.9961,13.327,14.3231,14,13.4961,14L11.0001,14 11.0001,16 9.99999999997669E-05,16 9.99999999997669E-05,12.5 9.99999999997669E-05,7 9.99999999997669E-05,2.5C9.99999999997669E-05,1.673,0.6731,1,1.5001,1L9.6101,1 10.6101,3 13.4961,3C14.3231,3,14.9961,3.673,14.9961,4.5" />
<GeometryDrawing Brush="#FFDCB67A" Geometry="F1M2,4L2,3 8.374,3 8.874,4z M13.496,4L10,4 9.992,4 8.992,2 1.5,2C1.225,2,1,2.224,1,2.5L1,7 11,7 11,13 13.496,13C13.773,13,13.996,12.776,13.996,12.5L13.996,4.5C13.996,4.224,13.773,4,13.496,4" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M9,10L4,10 4,9 9,9z M9,12L4,12 4,11 9,11z M9,14L4,14 4,13 9,13z M2,13L3,13 3,14 2,14z M2,11L3,11 3,12 2,12z M2,9L3,9 3,10 2,10z M1,15L10,15 10,8 1,8z" />
<GeometryDrawing Brush="#FFEFEFF0" Geometry="F1M2,3L8.374,3 8.874,4 2,4z M9,10L4,10 4,9 9,9z M9,12L4,12 4,11 9,11z M9,14L4,14 4,13 9,13z M2,13L3,13 3,14 2,14z M2,11L3,11 3,12 2,12z M2,9L3,9 3,10 2,10z" />
</DrawingGroup.Children>
</DrawingGroup>

1
ILSpy/Images/Metadata.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.st0{opacity:0}.st0,.st1{fill:#f6f6f6}.st2{fill:#424242}.st3{fill:#f0eff1}</style><g id="outline"><path class="st0" d="M0 0h16v16H0z"/><path class="st1" d="M15 4.465v7.07L8.303 16h-.606L1 11.535v-7.07L7.697 0h.605L15 4.465z"/></g><path class="st2" d="M8 1L2 5v6l6 4 6-4V5L8 1zm0 1.201l4.648 3.1-1.892 1.261-4.654-3.095L8 2.201zm-.5 11.264l-4.5-3v-1.53l4.5 3v1.53zm0-2.733l-4.5-3V6.268l4.5 3v1.464zM3.353 5.301l1.849-1.232 4.653 3.094L8 8.398 3.353 5.301zM13 10.465l-4.5 3v-1.53l4.5-3v1.53zm0-2.733l-4.5 3V9.268l4.5-3v1.464z" id="icon_x5F_bg"/><g id="icon_x5F_fg"><path class="st3" d="M8 2.201l4.648 3.1-1.892 1.261-4.654-3.095zM7.5 13.465l-4.5-3v-1.53l4.5 3zM7.5 10.732l-4.5-3V6.268l4.5 3zM3.353 5.301l1.848-1.233 4.653 3.094L8 8.398zM13 10.465l-4.5 3v-1.53l4.5-3zM13 7.732l-4.5 3V9.268l4.5-3z"/></g></svg>

After

Width:  |  Height:  |  Size: 873 B

15
ILSpy/Images/Metadata.xaml

@ -0,0 +1,15 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M7.6977,-0.000199999999999534L0.9997,4.4648 0.9997,11.5348 7.6977,15.9998 8.3027,15.9998 15.0007,11.5348 15.0007,4.4648 8.3027,-0.000199999999999534z" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M13,7.7324L8.5,10.7324 8.5,9.2674 13,6.2674z M13,10.4644L8.5,13.4644 8.5,11.9344 13,8.9344z M3.353,5.3004L5.201,4.0684 9.854,7.1624 8,8.3984z M7.5,10.7324L3,7.7324 3,6.2674 7.5,9.2674z M7.5,13.4644L3,10.4644 3,8.9344 7.5,11.9344z M8,2.2014L12.647,5.3004 10.756,6.5614 6.102,3.4664z M8,1.0004L2,5.0004 2,11.0004 8,15.0004 14,11.0004 14,5.0004z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M8,2.2012L12.647,5.3012 10.756,6.5612 6.102,3.4672z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M7.5,13.4648L3,10.4648 3,8.9348 7.5,11.9348z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M7.5,10.7324L3,7.7324 3,6.2674 7.5,9.2674z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M3.3525,5.3008L5.2015,4.0688 9.8545,7.1618 7.9995,8.3988z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M13,10.4648L8.5,13.4648 8.5,11.9348 13,8.9348z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M13,7.7324L8.5,10.7324 8.5,9.2674 13,6.2674z" />
</DrawingGroup.Children>
</DrawingGroup>

73
ILSpy/Images/MetadataFile.svg

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 16 16"
version="1.1"
id="svg4"
sodipodi:docname="MetadataFile.svg"
xml:space="preserve"
inkscape:version="1.3.1 (91b66b0783, 2023-11-16)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs4" /><sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="12.828125"
inkscape:cx="24.672351"
inkscape:cy="7.6004872"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" /><style
id="style1">.st0{opacity:0}.st0,.st1{fill:#f6f6f6}.st2{fill:#424242}.st3{fill:#f0eff1}</style><g
id="outline"
style="display:inline"><path
class="st0"
d="M 0,0 H 16 V 16 H 0 Z"
id="path1"
style="display:inline" /><path
class="st1"
d="M 10.023,1 H 3.964 C 3.012,1 2,1.701 2,3 V 8.556 C 0.81,9.25 0,10.525 0,12 c 0,2.206 1.794,4 4,4 a 3.971,3.971 0 0 0 2.618,-1 h 5.347 C 13.407,15 13.972,13.825 14,13 V 4.552 Z"
id="path2"
style="display:inline" /></g><g
id="icon_x5F_bg"><path
class="st2"
d="M 6,6 H 8 V 7 H 6 Z M 6,8 V 8.555 C 6.222,8.684 6.428,8.832 6.62,9 H 10 V 8 Z m 1.858,3 H 10 V 10 H 7.445 c 0.181,0.311 0.321,0.644 0.413,1 z"
id="path3"
style="display:inline" /><path
class="st2"
d="M 9.641,2 H 3.964 C 3.964,2 3,2 3,3 V 8.142 A 3.978,3.978 0 0 1 4,8 V 3 h 5 v 3 h 3 v 7 H 7.858 a 3.945,3.945 0 0 1 -0.414,1 h 4.521 C 12.965,14 13,13 13,13 V 5 Z"
id="path4"
style="display:inline" /></g><path
class="st3"
d="M9 6V3H4v5c.735 0 1.417.213 2.009.562L6 8.555V8h4v1H6.62c-.005-.005-.012-.008-.018-.013.344.298.633.649.86 1.047-.006-.011-.01-.023-.017-.034H10v1H7.858l-.005-.017c.086.328.147.663.147 1.017 0 .348-.059.679-.142 1H12V6H9zM8 7H6V6h2v1z"
id="icon_x5F_fg" /><style
id="style1-9">.st0{opacity:0}.st0,.st1{fill:#f6f6f6}.st2{fill:#424242}.st3{fill:#f0eff1}</style><style
type="text/css"
id="style1-2">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{fill:#F6F6F6;} .icon-vs-fg{fill:#F0EFF1;} .icon-vs-bg{fill:#424242;}</style><g
id="g4"
transform="matrix(0.5,0,0,0.5,0,8)"
style="display:inline"><g
id="outline-9"><path
class="st0"
d="M 0,0 H 16 V 16 H 0 Z"
id="path1-3" /><path
class="st1"
d="m 15,4.465 v 7.07 L 8.303,16 H 7.697 L 1,11.535 V 4.465 L 7.697,0 h 0.605 z"
id="path2-8" /></g><path
class="st2"
d="M 8,1 2,5 v 6 l 6,4 6,-4 V 5 Z m 0,1.201 4.648,3.1 -1.892,1.261 -4.654,-3.095 z m -0.5,11.264 -4.5,-3 v -1.53 l 4.5,3 z m 0,-2.733 -4.5,-3 V 6.268 l 4.5,3 z M 3.353,5.301 5.202,4.069 9.855,7.163 8,8.398 Z m 9.647,5.164 -4.5,3 v -1.53 l 4.5,-3 z m 0,-2.733 -4.5,3 V 9.268 l 4.5,-3 z"
id="icon_x5F_bg-2" /><g
id="icon_x5F_fg-1"><path
class="st3"
d="m 8,2.201 4.648,3.1 -1.892,1.261 -4.654,-3.095 z m -0.5,11.264 -4.5,-3 v -1.53 l 4.5,3 z m 0,-2.733 -4.5,-3 V 6.268 l 4.5,3 z M 3.353,5.301 5.201,4.068 9.854,7.162 8,8.398 Z m 9.647,5.164 -4.5,3 v -1.53 l 4.5,-3 z m 0,-2.733 -4.5,3 V 9.268 l 4.5,-3 z"
id="path3-0" /></g></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

29
ILSpy/Images/MetadataFile.xaml

@ -0,0 +1,29 @@
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ClipGeometry="M0,0 V16 H16 V0 H0 Z">
<DrawingGroup Opacity="1">
<GeometryDrawing Geometry="F1 M16,16z M0,0z M0,0L16,0 16,16 0,16z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FFF6F6F6" Opacity="0" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1 M16,16z M0,0z M10.023,1L3.964,1C3.012,1,2,1.701,2,3L2,8.556C0.81,9.25 0,10.525 0,12 0,14.206 1.794,16 4,16A3.971,3.971,0,0,0,6.618,15L11.965,15C13.407,15,13.972,13.825,14,13L14,4.552z" />
</DrawingGroup>
<DrawingGroup Opacity="1">
<GeometryDrawing Brush="#FF424242" Geometry="F1 M16,16z M0,0z M6,6L8,6 8,7 6,7z M6,8L6,8.555C6.222,8.684,6.428,8.832,6.62,9L10,9 10,8z M7.858,11L10,11 10,10 7.445,10C7.626,10.311,7.766,10.644,7.858,11z" />
<GeometryDrawing Brush="#FF424242" Geometry="F1 M16,16z M0,0z M9.641,2L3.964,2C3.964,2,3,2,3,3L3,8.142A3.978,3.978,0,0,1,4,8L4,3 9,3 9,6 12,6 12,13 7.858,13A3.945,3.945,0,0,1,7.444,14L11.965,14C12.965,14,13,13,13,13L13,5z" />
</DrawingGroup>
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1 M16,16z M0,0z M9,6L9,3 4,3 4,8C4.735,8,5.417,8.213,6.009,8.562L6,8.555 6,8 10,8 10,9 6.62,9C6.615,8.995 6.608,8.992 6.602,8.987 6.946,9.285 7.235,9.636 7.462,10.034 7.456,10.023 7.452,10.011 7.445,10L10,10 10,11 7.858,11 7.853,10.983C7.939,11.311 8,11.646 8,12 8,12.348 7.941,12.679 7.858,13L12,13 12,6 9,6z M8,7L6,7 6,6 8,6 8,7z" />
<DrawingGroup Opacity="1" Transform="0.5,0,0,0.5,0,8">
<DrawingGroup Opacity="1">
<GeometryDrawing Geometry="F1 M16,16z M0,0z M0,0L16,0 16,16 0,16z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FFF6F6F6" Opacity="0" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1 M16,16z M0,0z M15,4.465L15,11.535 8.303,16 7.697,16 1,11.535 1,4.465 7.697,0 8.302,0z" />
</DrawingGroup>
<GeometryDrawing Brush="#FF424242" Geometry="F1 M16,16z M0,0z M8,1L2,5 2,11 8,15 14,11 14,5z M8,2.201L12.648,5.301 10.756,6.562 6.102,3.467z M7.5,13.465L3,10.465 3,8.935 7.5,11.935z M7.5,10.732L3,7.732 3,6.268 7.5,9.268z M3.353,5.301L5.202,4.069 9.855,7.163 8,8.398z M13,10.465L8.5,13.465 8.5,11.935 13,8.935z M13,7.732L8.5,10.732 8.5,9.268 13,6.268z" />
<DrawingGroup Opacity="1">
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1 M16,16z M0,0z M8,2.201L12.648,5.301 10.756,6.562 6.102,3.467z M7.5,13.465L3,10.465 3,8.935 7.5,11.935z M7.5,10.732L3,7.732 3,6.268 7.5,9.268z M3.353,5.301L5.201,4.068 9.854,7.162 8,8.398z M13,10.465L8.5,13.465 8.5,11.935 13,8.935z M13,7.732L8.5,10.732 8.5,9.268 13,6.268z" />
</DrawingGroup>
</DrawingGroup>
</DrawingGroup>

1
ILSpy/Images/MetadataTable.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.icon-canvas-transparent{opacity:0;fill:#f6f6f6}.icon-vs-out{fill:#f6f6f6}.icon-vs-bg{fill:#424242}.icon-vs-fg{fill:#f0eff1}</style><path class="icon-canvas-transparent" d="M16 16H0V0h16v16z" id="canvas"/><path class="icon-vs-out" d="M16 1v14h-4.78c-.55.609-1.337 1-2.22 1H5c-.884 0-1.674-.39-2.223-1H1v-1.796A2.977 2.977 0 0 1 0 11c0-.883.391-1.67 1-2.22V1h15z" id="outline"/><path class="icon-vs-fg" d="M7 8h3v2h-.174A3.004 3.004 0 0 0 7 8zm0-1h3V5H7v2zM3 7h3V5H3v2zm8-2v2h3V5h-3zm1 8h2v-2h-2.798c.497.544.798 1.249.798 2zm-1-3h3V8h-3v2z" id="iconFg"/><g id="iconBg"><path class="icon-vs-bg" d="M15 2v12h-3.184c.112-.314.184-.648.184-1h2v-2h-2.798a2.996 2.996 0 0 0-.738-.607l-.621-.35c-.004-.015-.012-.028-.017-.043H10V8H3c-.352 0-.686.072-1 .184V2h13zM6 5H3v2h3V5zm4 0H7v2h3V5zm4 3h-3v2h3V8zm0-3h-3v2h3V5zm-4.027 6.264a2.965 2.965 0 0 1-.275 1.024A.99.99 0 0 1 10 13a1 1 0 0 1-1 1H5a1.001 1.001 0 0 1 0-2l1-1H5c-1.103 0-2 .897-2 2 0 1.102.897 2 2 2h4c1.102 0 2-.898 2-2 0-.748-.417-1.393-1.027-1.736zM3 10h4a1.001 1.001 0 0 1 0 2l-1 1h1c1.102 0 2-.897 2-2s-.898-2-2-2H3c-1.103 0-2 .897-2 2 0 .748.417 1.393 1.027 1.736a2.96 2.96 0 0 1 .275-1.024A.99.99 0 0 1 2 11c0-.551.449-1 1-1z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

10
ILSpy/Images/MetadataTable.xaml

@ -0,0 +1,10 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M16,1L16,15 11.22,15C10.67,15.609,9.883,16,9,16L5,16C4.116,16,3.326,15.61,2.776,15L1,15 1,13.204C0.378,12.643 0,11.851 0,11 0,10.117 0.391,9.33 1,8.78L1,1z" />
<GeometryDrawing Brush="#FFEFEFF0" Geometry="F1M11,10L14,10 14,8 11,8z M12,13L14,13 14,11 11.202,11C11.699,11.544,12,12.249,12,13 M11,7L14,7 14,5 11,5z M3,7L6,7 6,5 3,5z M7,7L10,7 10,5 7,5z M7,8L10,8 10,10 9.826,10C9.412,8.837,8.303,8,7,8" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M3,10L7,10C7.552,10 8,10.449 8,11 8,11.551 7.552,12 7,12L6,13 7,13C8.103,13 9,12.104 9,11 9,9.896 8.103,9 7,9L3,9C1.897,9 1,9.896 1,11 1,11.748 1.417,12.394 2.027,12.736 2.059,12.372 2.15,12.027 2.302,11.713 2.116,11.531 2,11.279 2,11 2,10.449 2.449,10 3,10 M9.974,11.264C9.941,11.628 9.85,11.973 9.698,12.287 9.884,12.469 10,12.721 10,13 10,13.552 9.552,14 9,14L5,14C4.449,14 4,13.552 4,13 4,12.449 4.449,12 5,12L6,11 5,11C3.897,11 3,11.896 3,13 3,14.103 3.897,15 5,15L9,15C10.103,15 11,14.103 11,13 11,12.252 10.583,11.606 9.974,11.264 M14,5L11,5 11,7 14,7z M14,8L11,8 11,10 14,10z M10,5L7,5 7,7 10,7z M6,5L3,5 3,7 6,7z M15,2L15,14 11.815,14C11.928,13.686,12,13.353,12,13L14,13 14,11 11.202,11C10.988,10.766,10.75,10.553,10.465,10.393L9.844,10.043C9.839,10.027,9.831,10.015,9.826,10L10,10 10,8 7,8 6,8 3,8C2.647,8,2.314,8.072,2,8.184L2,2z" />
</DrawingGroup.Children>
</DrawingGroup>

1
ILSpy/Images/MetadataTableGroup.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.icon-canvas-transparent{opacity:0;fill:#f6f6f6}.icon-vs-out{fill:#f6f6f6}.icon-vs-bg{fill:#424242}.icon-vs-fg{fill:#f0eff1}</style><path class="icon-canvas-transparent" d="M16 0v16H0V0h16z" id="canvas"/><path class="icon-vs-out" d="M16 6v10H4v-3H0V3h3V0h12v6h1z" id="outline"/><path class="icon-vs-bg" d="M2 7h2v1H2v1h2v1H2v1h2v1H1V4h10v2H2v1zm11-3h-1v1h1v1h1V1H4v2h9v1zm2 3v8H5V7h10zm-7 6H6v1h2v-1zm0-2H6v1h2v-1zm0-2H6v1h2V9zm3 4H9v1h2v-1zm0-2H9v1h2v-1zm0-2H9v1h2V9zm3 4h-2v1h2v-1zm0-2h-2v1h2v-1zm0-2h-2v1h2V9z" id="iconBg"/><g id="iconFg"><path class="icon-vs-fg" d="M2 6h2v1H2V6zm0 3h2V8H2v1zm4 5h2v-1H6v1zm7-9h-1v1h1V5zm0-2h-1v1h1V3zM2 11h2v-1H2v1zm4 1h2v-1H6v1zm3 2h2v-1H9v1zm-3-4h2V9H6v1zm6 4h2v-1h-2v1zm0-5v1h2V9h-2zm0 3h2v-1h-2v1zm-3 0h2v-1H9v1zm0-2h2V9H9v1z"/></g></svg>

After

Width:  |  Height:  |  Size: 847 B

10
ILSpy/Images/MetadataTableGroup.xaml

@ -0,0 +1,10 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M2.9997,-0.000199999999999534L2.9997,3.0008 -0.000300000000000189,3.0008 -0.000300000000000189,13.0008 3.9997,13.0008 3.9997,15.9998 16.0007,15.9998 16.0007,5.9998 15.0007,5.9998 15.0007,-0.000199999999999534z" />
<GeometryDrawing Brush="#FF424242" Geometry="F1M14,9L12,9 12,10 14,10z M14,11L12,11 12,12 14,12z M14,13L12,13 12,14 14,14z M11,9L9,9 9,10 11,10z M11,11L9,11 9,12 11,12z M11,13L9,13 9,14 11,14z M8,9L6,9 6,10 8,10z M8,11L6,11 6,12 8,12z M8,13L6,13 6,14 8,14z M15,15L5,15 5,7 15,7z M13,4L12,4 12,5 13,5 13,6 14,6 14,1 4,1 4,3 13,3z M2,7L4,7 4,8 2,8 2,9 4,9 4,10 2,10 2,11 4,11 4,12 1,12 1,4 11,4 11,6 2,6z" />
<GeometryDrawing Brush="#FFEFEFF0" Geometry="F1M9,10L11,10 11,9 9,9z M9,12L11,12 11,11 9,11z M12,12L14,12 14,11 12,11z M12,10L14,10 14,9 12,9z M12,14L14,14 14,13 12,13z M6,10L8,10 8,9 6,9z M9,14L11,14 11,13 9,13z M6,12L8,12 8,11 6,11z M2,11L4,11 4,10 2,10z M13,3L12,3 12,4 13,4z M13,5L12,5 12,6 13,6z M6,14L8,14 8,13 6,13z M2,9L4,9 4,8 2,8z M2,6L4,6 4,7 2,7z" />
</DrawingGroup.Children>
</DrawingGroup>

1
ILSpy/Images/ProgramDebugDatabase.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.st0{opacity:0}.st0,.st1{fill:#f6f6f6}.st2{fill:#424242}.st3{fill:#f0eff1}</style><g id="outline"><path class="st0" d="M0 0h16v16H0z"/><path class="st1" d="M10.023 1H3.964C3.012 1 2 1.701 2 3v5.556C.81 9.25 0 10.525 0 12c0 2.206 1.794 4 4 4a3.971 3.971 0 0 0 2.618-1h5.347c1.442 0 2.007-1.175 2.035-2V4.552L10.023 1z"/></g><g id="icon_x5F_bg"><path class="st2" d="M6 6h2v1H6zM6 8v.555c.222.129.428.277.62.445H10V8H6zM7.858 11H10v-1H7.445c.181.311.321.644.413 1z"/><circle class="st2" cx="4" cy="12" r="3"/><path class="st2" d="M9.641 2H3.964S3 2 3 3v5.142A3.978 3.978 0 0 1 4 8V3h5v3h3v7H7.858a3.945 3.945 0 0 1-.414 1h4.521c1 0 1.035-1 1.035-1V5L9.641 2z"/></g><path class="st3" d="M9 6V3H4v5c.735 0 1.417.213 2.009.562L6 8.555V8h4v1H6.62c-.005-.005-.012-.008-.018-.013.344.298.633.649.86 1.047-.006-.011-.01-.023-.017-.034H10v1H7.858l-.005-.017c.086.328.147.663.147 1.017 0 .348-.059.679-.142 1H12V6H9zM8 7H6V6h2v1z" id="icon_x5F_fg"/></svg>

After

Width:  |  Height:  |  Size: 1010 B

14
ILSpy/Images/ProgramDebugDatabase.xaml

@ -0,0 +1,14 @@
<!-- This file was generated by the AiToXaml tool.-->
<!-- Tool Version: 14.0.22307.0 -->
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ClipGeometry="M0,0 V16 H16 V0 H0 Z">
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M10.0225,1L3.9635,1C3.0115,1,2.0005,1.701,2.0005,3L2.0005,8.556C0.810500000000001,9.25 0.000500000000000611,10.525 0.000500000000000611,12 0.000500000000000611,14.206 1.7945,16 4.0005,16 5.0055,16 5.9145,15.614 6.6175,15L11.9645,15C13.4075,15,13.9715,13.825,14.0005,13L14.0005,4.552z" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M6,7L8,7 8,6 6,6z" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M6,8L6,8.555C6.222,8.684,6.428,8.832,6.62,9L10,9 10,8z" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M7.8584,11L10.0004,11 10.0004,10 7.4454,10C7.6264,10.311,7.7664,10.644,7.8584,11" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M7,12C7,10.344 5.657,9 4,9 2.343,9 1,10.344 1,12 1,13.656 2.343,15 4,15 5.657,15 7,13.656 7,12" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M9.6406,2L3.9636,2C3.9636,2,2.9996,2,2.9996,3L2.9996,8.142C3.3216,8.059,3.6526,8,3.9996,8L3.9996,3 8.9996,3 8.9996,6 11.9996,6 11.9996,13 7.8576,13C7.7656,13.355,7.6246,13.689,7.4436,14L11.9646,14C12.9646,14,12.9996,13,12.9996,13L12.9996,5z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M8,7L6,7 6,6 8,6z M9,6L9,3 4,3 4,8C4.735,8 5.417,8.213 6.009,8.562 6.006,8.56 6.003,8.557 6,8.555L6,8 10,8 10,9 6.62,9C6.615,8.995 6.608,8.992 6.602,8.987 6.946,9.285 7.235,9.637 7.462,10.034 7.456,10.023 7.452,10.011 7.445,10L10,10 10,11 7.858,11C7.857,10.994 7.854,10.989 7.853,10.983 7.939,11.311 8,11.646 8,12 8,12.348 7.941,12.679 7.858,13L12,13 12,6z" />
</DrawingGroup.Children>
</DrawingGroup>

9
ILSpy/Images/README.md

@ -25,10 +25,18 @@ Icons used in ILSpy:
| Folder.Closed | x | x | VS 2017 Icon Pack (Folder) | | | Folder.Closed | x | x | VS 2017 Icon Pack (Folder) | |
| Folder.Open | x | x | VS 2017 Icon Pack (FolderOpen) | | | Folder.Open | x | x | VS 2017 Icon Pack (FolderOpen) | |
| Forward | x | x | VS 2017 Icon Pack (Forward) | | | Forward | x | x | VS 2017 Icon Pack (Forward) | |
| Header | x | x | VS 2017 Icon Pack (PageHeader) | |
| Heap | x | x | VS 2017 Icon Pack (Datalist) | |
| Indexer | x | x | VS 2017 Icon Pack (Indexer) | | | Indexer | x | x | VS 2017 Icon Pack (Indexer) | |
| Interface | x | x | VS 2017 Icon Pack (Interface) | | | Interface | x | x | VS 2017 Icon Pack (Interface) | |
| Library | x | x | VS 2017 Icon Pack (Library) | | | Library | x | x | VS 2017 Icon Pack (Library) | |
| ListFolder | x | x | VS 2017 Icon Pack (ListFolder) | |
| ListFolder.Open | x | x | VS 2017 Icon Pack (ListFolderOpen) | |
| Literal | x | x | VS 2017 Icon Pack (Literal) | | | Literal | x | x | VS 2017 Icon Pack (Literal) | |
| Metadata | x | x | VS 2017 Icon Pack (Metadata) | |
| MetadataFile | x | x | combined ProgramDebugDatabase + Metadata | |
| MetadataTable | x | x | VS 2017 Icon Pack (LinkedTable) | |
| MetadataTableGroup | x | x | VS 2017 Icon Pack (LinkedTableGroup) | |
| Method | x | x | VS 2017 Icon Pack (Method) | | | Method | x | x | VS 2017 Icon Pack (Method) | |
| Namespace | x | x | VS 2017 Icon Pack (Namespace) | | | Namespace | x | x | VS 2017 Icon Pack (Namespace) | |
| OK | x | x | VS 2017 Icon Pack (StatusOK) | | | OK | x | x | VS 2017 Icon Pack (StatusOK) | |
@ -42,6 +50,7 @@ Icons used in ILSpy:
| OverlayProtectedInternal | x | x | combined OverlayProtected and OverlayInternal | | | OverlayProtectedInternal | x | x | combined OverlayProtected and OverlayInternal | |
| OverlayStatic | x | x | custom | | | OverlayStatic | x | x | custom | |
| PInvokeMethod | x | x | based on VS 2017 Icon Pack (ExtensionMethod) with rotated arrow | | | PInvokeMethod | x | x | based on VS 2017 Icon Pack (ExtensionMethod) with rotated arrow | |
| ProgramDebugDatabase | x | x | VS 2017 Icon Pack (ProgramDebugDatabase) | |
| Property | x | x | VS 2017 Icon Pack (Property) | | | Property | x | x | VS 2017 Icon Pack (Property) | |
| ReferenceFolder | x | x | combined VS 2017 Icon Pack (Reference) two times | | | ReferenceFolder | x | x | combined VS 2017 Icon Pack (Reference) two times | |
| Refresh | x | x | VS 2017 Icon Pack (Refresh) | | | Refresh | x | x | VS 2017 Icon Pack (Refresh) | |

4
ILSpy/MainWindow.xaml.cs

@ -1307,7 +1307,7 @@ namespace ICSharpCode.ILSpy
break; break;
case EntityReference unresolvedEntity: case EntityReference unresolvedEntity:
string protocol = unresolvedEntity.Protocol ?? "decompile"; string protocol = unresolvedEntity.Protocol ?? "decompile";
PEFile file = unresolvedEntity.ResolveAssembly(assemblyList); PEFile file = unresolvedEntity.ResolveAssembly(assemblyList) as PEFile;
if (file == null) if (file == null)
{ {
break; break;
@ -1378,7 +1378,7 @@ namespace ICSharpCode.ILSpy
{ {
e.Handled = true; e.Handled = true;
OpenFileDialog dlg = new OpenFileDialog(); OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd|Nuget Packages (*.nupkg)|*.nupkg|All files|*.*"; dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd|Nuget Packages (*.nupkg)|*.nupkg|Portable Program Database (*.pdb)|*.pdb|All files|*.*";
dlg.Multiselect = true; dlg.Multiselect = true;
dlg.RestoreDirectory = true; dlg.RestoreDirectory = true;
if (dlg.ShowDialog() == true) if (dlg.ShowDialog() == true)

2
ILSpy/Metadata/CoffHeaderTreeNode.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => "COFF Header"; public override object Text => "COFF Header";
public override object Icon => Images.Literal; public override object Icon => Images.Header;
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)
{ {

37
ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs

@ -29,14 +29,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class AssemblyRefTableTreeNode : MetadataTableTreeNode internal class AssemblyRefTableTreeNode : MetadataTableTreeNode
{ {
public AssemblyRefTableTreeNode(PEFile module) public AssemblyRefTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.AssemblyReference, module) : base(HandleKind.AssemblyReference, metadataFile)
{ {
} }
public override object Text => $"23 AssemblyRef ({module.Metadata.GetTableRowCount(TableIndex.AssemblyRef)})"; public override object Text => $"23 AssemblyRef ({metadataFile.Metadata.GetTableRowCount(TableIndex.AssemblyRef)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -44,13 +42,12 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata;
var list = new List<AssemblyRefEntry>(); var list = new List<AssemblyRefEntry>();
AssemblyRefEntry scrollTargetEntry = default; AssemblyRefEntry scrollTargetEntry = default;
foreach (var row in metadata.AssemblyReferences) foreach (var row in metadataFile.Metadata.AssemblyReferences)
{ {
AssemblyRefEntry entry = new AssemblyRefEntry(module, row); AssemblyRefEntry entry = new AssemblyRefEntry(metadataFile, row);
if (scrollTarget == MetadataTokens.GetRowNumber(row)) if (scrollTarget == MetadataTokens.GetRowNumber(row))
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -71,9 +68,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct AssemblyRefEntry struct AssemblyRefEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly AssemblyReferenceHandle handle; readonly AssemblyReferenceHandle handle;
readonly System.Reflection.Metadata.AssemblyReference assemblyRef; readonly System.Reflection.Metadata.AssemblyReference assemblyRef;
@ -81,9 +76,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.AssemblyRef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.AssemblyRef)
+ metadata.GetTableRowSize(TableIndex.AssemblyRef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.AssemblyRef) * (RID - 1);
public Version Version => assemblyRef.Version; public Version Version => assemblyRef.Version;
@ -101,26 +96,24 @@ namespace ICSharpCode.ILSpy.Metadata
get { get {
if (assemblyRef.PublicKeyOrToken.IsNil) if (assemblyRef.PublicKeyOrToken.IsNil)
return null; return null;
System.Collections.Immutable.ImmutableArray<byte> token = metadata.GetBlobContent(assemblyRef.PublicKeyOrToken); System.Collections.Immutable.ImmutableArray<byte> token = metadataFile.Metadata.GetBlobContent(assemblyRef.PublicKeyOrToken);
return token.ToHexString(token.Length); return token.ToHexString(token.Length);
} }
} }
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(assemblyRef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(assemblyRef.Name):X} \"{Name}\"";
public string Name => metadata.GetString(assemblyRef.Name); public string Name => metadataFile.Metadata.GetString(assemblyRef.Name);
public string CultureTooltip => $"{MetadataTokens.GetHeapOffset(assemblyRef.Culture):X} \"{Culture}\""; public string CultureTooltip => $"{MetadataTokens.GetHeapOffset(assemblyRef.Culture):X} \"{Culture}\"";
public string Culture => metadata.GetString(assemblyRef.Culture); public string Culture => metadataFile.Metadata.GetString(assemblyRef.Culture);
public AssemblyRefEntry(PEFile module, AssemblyReferenceHandle handle) public AssemblyRefEntry(MetadataFile metadataFile, AssemblyReferenceHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.assemblyRef = metadata.GetAssemblyReference(handle); this.assemblyRef = metadataFile.Metadata.GetAssemblyReference(handle);
} }
} }

23
ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs

@ -17,7 +17,6 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
@ -29,14 +28,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class AssemblyTableTreeNode : MetadataTableTreeNode internal class AssemblyTableTreeNode : MetadataTableTreeNode
{ {
public AssemblyTableTreeNode(PEFile module) public AssemblyTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.AssemblyDefinition, module) : base(HandleKind.AssemblyDefinition, metadataFile)
{ {
} }
public override object Text => $"20 Assembly ({module.Metadata.GetTableRowCount(TableIndex.Assembly)})"; public override object Text => $"20 Assembly ({metadataFile.Metadata.GetTableRowCount(TableIndex.Assembly)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -44,9 +41,9 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
if (module.IsAssembly) if (metadataFile.Metadata.IsAssembly)
{ {
view.ItemsSource = new[] { new AssemblyEntry(module) }; view.ItemsSource = new[] { new AssemblyEntry(metadataFile.Metadata, metadataFile.MetadataOffset) };
} }
else else
{ {
@ -57,10 +54,9 @@ namespace ICSharpCode.ILSpy.Metadata
return true; return true;
} }
struct AssemblyEntry readonly struct AssemblyEntry
{ {
readonly int metadataOffset; readonly int metadataOffset;
readonly PEFile module;
readonly MetadataReader metadata; readonly MetadataReader metadata;
readonly AssemblyDefinition assembly; readonly AssemblyDefinition assembly;
@ -96,11 +92,10 @@ namespace ICSharpCode.ILSpy.Metadata
public string Culture => metadata.GetString(assembly.Culture); public string Culture => metadata.GetString(assembly.Culture);
public AssemblyEntry(PEFile module) public AssemblyEntry(MetadataReader metadata, int metadataOffset)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadata = metadata;
this.module = module; this.metadataOffset = metadataOffset;
this.metadata = module.Metadata;
this.assembly = metadata.GetAssemblyDefinition(); this.assembly = metadata.GetAssemblyDefinition();
} }
} }

33
ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs

@ -23,22 +23,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class ClassLayoutTableTreeNode : MetadataTableTreeNode class ClassLayoutTableTreeNode : MetadataTableTreeNode
{ {
public ClassLayoutTableTreeNode(PEFile module) public ClassLayoutTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x0F, module) : base((HandleKind)0x0F, metadataFile)
{ {
} }
public override object Text => $"0F ClassLayout ({module.Metadata.GetTableRowCount(TableIndex.ClassLayout)})"; public override object Text => $"0F ClassLayout ({metadataFile.Metadata.GetTableRowCount(TableIndex.ClassLayout)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -46,18 +42,16 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata;
var list = new List<ClassLayoutEntry>(); var list = new List<ClassLayoutEntry>();
var length = metadata.GetTableRowCount(TableIndex.ClassLayout); var length = metadataFile.Metadata.GetTableRowCount(TableIndex.ClassLayout);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadataFile.Metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
ClassLayoutEntry scrollTargetEntry = default; ClassLayoutEntry scrollTargetEntry = default;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
ClassLayoutEntry entry = new ClassLayoutEntry(module, ptr, metadataOffset, rid); ClassLayoutEntry entry = new ClassLayoutEntry(metadataFile, ptr, rid);
if (scrollTarget == rid) if (scrollTarget == rid)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -92,8 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ClassLayoutEntry struct ClassLayoutEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly ClassLayout classLayout; readonly ClassLayout classLayout;
public int RID { get; } public int RID { get; }
@ -107,11 +100,11 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, classLayout.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference("metadata", classLayout.Parent));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, classLayout.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, classLayout.Parent);
[ColumnInfo("X4", Kind = ColumnKind.Other)] [ColumnInfo("X4", Kind = ColumnKind.Other)]
public ushort PackingSize => classLayout.PackingSize; public ushort PackingSize => classLayout.PackingSize;
@ -119,14 +112,14 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public uint ClassSize => classLayout.ClassSize; public uint ClassSize => classLayout.ClassSize;
public ClassLayoutEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public ClassLayoutEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var metadata = metadataFile.Metadata;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.ClassLayout) var rowOffset = metadata.GetTableMetadataOffset(TableIndex.ClassLayout)
+ metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1); + metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
this.classLayout = new ClassLayout(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4); this.classLayout = new ClassLayout(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4);
this.parentTooltip = null; this.parentTooltip = null;
} }

36
ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs

@ -21,8 +21,6 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
@ -30,14 +28,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ConstantTableTreeNode : MetadataTableTreeNode internal class ConstantTableTreeNode : MetadataTableTreeNode
{ {
public ConstantTableTreeNode(PEFile module) public ConstantTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x0B, module) : base((HandleKind)0x0B, metadataFile)
{ {
} }
public override object Text => $"0B Constant ({module.Metadata.GetTableRowCount(TableIndex.Constant)})"; public override object Text => $"0B Constant ({metadataFile.Metadata.GetTableRowCount(TableIndex.Constant)})";
public override object Icon => Images.Literal;
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)
{ {
@ -45,14 +41,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<ConstantEntry>(); var list = new List<ConstantEntry>();
ConstantEntry scrollTargetEntry = default; ConstantEntry scrollTargetEntry = default;
for (int row = 1; row <= metadata.GetTableRowCount(TableIndex.Constant); row++) for (int row = 1; row <= metadata.GetTableRowCount(TableIndex.Constant); row++)
{ {
ConstantEntry entry = new ConstantEntry(module, MetadataTokens.ConstantHandle(row)); ConstantEntry entry = new ConstantEntry(metadataFile, MetadataTokens.ConstantHandle(row));
if (scrollTarget == row) if (scrollTarget == row)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -73,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ConstantEntry struct ConstantEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly EntityHandle handle; readonly EntityHandle handle;
readonly Constant constant; readonly Constant constant;
@ -83,9 +77,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.Constant) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Constant)
+ metadata.GetTableRowSize(TableIndex.Constant) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.Constant) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public ConstantTypeCode Type => constant.TypeCode; public ConstantTypeCode Type => constant.TypeCode;
@ -97,11 +91,11 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, constant.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, constant.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, constant.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, constant.Parent);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Value => MetadataTokens.GetHeapOffset(constant.Value); public int Value => MetadataTokens.GetHeapOffset(constant.Value);
@ -112,13 +106,11 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public ConstantEntry(PEFile module, ConstantHandle handle) public ConstantEntry(MetadataFile metadataFile, ConstantHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.constant = metadata.GetConstant(handle); this.constant = metadataFile.Metadata.GetConstant(handle);
this.parentTooltip = null; this.parentTooltip = null;
} }
} }

40
ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs

@ -21,22 +21,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class CustomAttributeTableTreeNode : MetadataTableTreeNode class CustomAttributeTableTreeNode : MetadataTableTreeNode
{ {
public CustomAttributeTableTreeNode(PEFile module) public CustomAttributeTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.CustomAttribute, module) : base(HandleKind.CustomAttribute, metadataFile)
{ {
} }
public override object Text => $"0C CustomAttribute ({module.Metadata.GetTableRowCount(TableIndex.CustomAttribute)})"; public override object Text => $"0C CustomAttribute ({metadataFile.Metadata.GetTableRowCount(TableIndex.CustomAttribute)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -44,14 +40,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<CustomAttributeEntry>(); var list = new List<CustomAttributeEntry>();
CustomAttributeEntry scrollTargetEntry = default; CustomAttributeEntry scrollTargetEntry = default;
foreach (var row in metadata.CustomAttributes) foreach (var row in metadata.CustomAttributes)
{ {
CustomAttributeEntry entry = new CustomAttributeEntry(module, row); CustomAttributeEntry entry = new CustomAttributeEntry(metadataFile, row);
if (scrollTarget == MetadataTokens.GetRowNumber(row)) if (scrollTarget == MetadataTokens.GetRowNumber(row))
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -73,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct CustomAttributeEntry struct CustomAttributeEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly CustomAttributeHandle handle; readonly CustomAttributeHandle handle;
readonly CustomAttribute customAttr; readonly CustomAttribute customAttr;
@ -83,31 +77,31 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.CustomAttribute) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.CustomAttribute)
+ metadata.GetTableRowSize(TableIndex.CustomAttribute) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.CustomAttribute) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Parent => MetadataTokens.GetToken(customAttr.Parent); public int Parent => MetadataTokens.GetToken(customAttr.Parent);
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, customAttr.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, customAttr.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, customAttr.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, customAttr.Parent);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Constructor => MetadataTokens.GetToken(customAttr.Constructor); public int Constructor => MetadataTokens.GetToken(customAttr.Constructor);
public void OnConstructorClick() public void OnConstructorClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, customAttr.Constructor, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, customAttr.Constructor, protocol: "metadata"));
} }
string constructorTooltip; string constructorTooltip;
public string ConstructorTooltip => GenerateTooltip(ref constructorTooltip, module, customAttr.Constructor); public string ConstructorTooltip => GenerateTooltip(ref constructorTooltip, metadataFile, customAttr.Constructor);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Value => MetadataTokens.GetHeapOffset(customAttr.Value); public int Value => MetadataTokens.GetHeapOffset(customAttr.Value);
@ -118,13 +112,11 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public CustomAttributeEntry(PEFile module, CustomAttributeHandle handle) public CustomAttributeEntry(MetadataFile metadataFile, CustomAttributeHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.customAttr = metadata.GetCustomAttribute(handle); this.customAttr = metadataFile.Metadata.GetCustomAttribute(handle);
this.parentTooltip = null; this.parentTooltip = null;
this.constructorTooltip = null; this.constructorTooltip = null;
} }

36
ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class DeclSecurityTableTreeNode : MetadataTableTreeNode class DeclSecurityTableTreeNode : MetadataTableTreeNode
{ {
public DeclSecurityTableTreeNode(PEFile module) public DeclSecurityTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.DeclarativeSecurityAttribute, module) : base(HandleKind.DeclarativeSecurityAttribute, metadataFile)
{ {
} }
public override object Text => $"0E DeclSecurity ({module.Metadata.GetTableRowCount(TableIndex.DeclSecurity)})"; public override object Text => $"0E DeclSecurity ({metadataFile.Metadata.GetTableRowCount(TableIndex.DeclSecurity)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,14 +41,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<DeclSecurityEntry>(); var list = new List<DeclSecurityEntry>();
DeclSecurityEntry scrollTargetEntry = default; DeclSecurityEntry scrollTargetEntry = default;
foreach (var row in metadata.DeclarativeSecurityAttributes) foreach (var row in metadata.DeclarativeSecurityAttributes)
{ {
var entry = new DeclSecurityEntry(module, row); var entry = new DeclSecurityEntry(metadataFile, row);
if (scrollTarget == MetadataTokens.GetRowNumber(row)) if (scrollTarget == MetadataTokens.GetRowNumber(row))
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -74,9 +70,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct DeclSecurityEntry struct DeclSecurityEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly DeclarativeSecurityAttributeHandle handle; readonly DeclarativeSecurityAttributeHandle handle;
readonly DeclarativeSecurityAttribute declSecAttr; readonly DeclarativeSecurityAttribute declSecAttr;
@ -84,20 +78,20 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.DeclSecurity) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.DeclSecurity)
+ metadata.GetTableRowSize(TableIndex.DeclSecurity) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.DeclSecurity) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Parent => MetadataTokens.GetToken(declSecAttr.Parent); public int Parent => MetadataTokens.GetToken(declSecAttr.Parent);
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, declSecAttr.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, declSecAttr.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, declSecAttr.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, declSecAttr.Parent);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public DeclarativeSecurityAction Action => declSecAttr.Action; public DeclarativeSecurityAction Action => declSecAttr.Action;
@ -117,13 +111,11 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public DeclSecurityEntry(PEFile module, DeclarativeSecurityAttributeHandle handle) public DeclSecurityEntry(MetadataFile metadataFile, DeclarativeSecurityAttributeHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.declSecAttr = metadata.GetDeclarativeSecurityAttribute(handle); this.declSecAttr = metadataFile.Metadata.GetDeclarativeSecurityAttribute(handle);
this.parentTooltip = null; this.parentTooltip = null;
} }
} }

41
ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class EventMapTableTreeNode : MetadataTableTreeNode class EventMapTableTreeNode : MetadataTableTreeNode
{ {
public EventMapTableTreeNode(PEFile module) public EventMapTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x12, module) : base((HandleKind)0x12, metadataFile)
{ {
} }
public override object Text => $"12 EventMap ({module.Metadata.GetTableRowCount(TableIndex.EventMap)})"; public override object Text => $"12 EventMap ({metadataFile.Metadata.GetTableRowCount(TableIndex.EventMap)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,17 +41,16 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<EventMapEntry>(); var list = new List<EventMapEntry>();
EventMapEntry scrollTargetEntry = default; EventMapEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.EventMap); var length = metadata.GetTableRowCount(TableIndex.EventMap);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
EventMapEntry entry = new EventMapEntry(module, ptr, metadataOffset, rid); EventMapEntry entry = new EventMapEntry(metadataFile, ptr, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -89,8 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct EventMapEntry struct EventMapEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly EventMap eventMap; readonly EventMap eventMap;
public int RID { get; } public int RID { get; }
@ -104,33 +98,32 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, eventMap.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, eventMap.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, eventMap.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, eventMap.Parent);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int EventList => MetadataTokens.GetToken(eventMap.EventList); public int EventList => MetadataTokens.GetToken(eventMap.EventList);
public void OnEventListClick() public void OnEventListClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, eventMap.EventList, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, eventMap.EventList, protocol: "metadata"));
} }
string eventListTooltip; string eventListTooltip;
public string EventListTooltip => GenerateTooltip(ref eventListTooltip, module, eventMap.EventList); public string EventListTooltip => GenerateTooltip(ref eventListTooltip, metadataFile, eventMap.EventList);
public EventMapEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public EventMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.EventMap) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.EventMap)
+ metadata.GetTableRowSize(TableIndex.EventMap) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.EventMap) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; int typeDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
int eventDefSize = metadata.GetTableRowCount(TableIndex.Event) < ushort.MaxValue ? 2 : 4; int eventDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.Event) < ushort.MaxValue ? 2 : 4;
this.eventMap = new EventMap(ptr.Slice(rowOffset), typeDefSize, eventDefSize); this.eventMap = new EventMap(ptr.Slice(rowOffset), typeDefSize, eventDefSize);
this.parentTooltip = null; this.parentTooltip = null;
this.eventListTooltip = null; this.eventListTooltip = null;

44
ILSpy/Metadata/CorTables/EventTableTreeNode.cs

@ -22,8 +22,6 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
@ -32,14 +30,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class EventTableTreeNode : MetadataTableTreeNode internal class EventTableTreeNode : MetadataTableTreeNode
{ {
public EventTableTreeNode(PEFile module) public EventTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.EventDefinition, module) : base(HandleKind.EventDefinition, metadataFile)
{ {
} }
public override object Text => $"14 Event ({module.Metadata.GetTableRowCount(TableIndex.Event)})"; public override object Text => $"14 Event ({metadataFile.Metadata.GetTableRowCount(TableIndex.Event)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -47,14 +43,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<EventDefEntry>(); var list = new List<EventDefEntry>();
EventDefEntry scrollTargetEntry = default; EventDefEntry scrollTargetEntry = default;
foreach (var row in metadata.EventDefinitions) foreach (var row in metadata.EventDefinitions)
{ {
EventDefEntry entry = new EventDefEntry(module, row); EventDefEntry entry = new EventDefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -76,9 +72,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct EventDefEntry : IMemberTreeNode struct EventDefEntry : IMemberTreeNode
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly EventDefinitionHandle handle; readonly EventDefinitionHandle handle;
readonly EventDefinition eventDef; readonly EventDefinition eventDef;
@ -86,9 +80,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.Event) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Event)
+ metadata.GetTableRowSize(TableIndex.Event) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.Event) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public EventAttributes Attributes => eventDef.Attributes; public EventAttributes Attributes => eventDef.Attributes;
@ -99,28 +93,30 @@ namespace ICSharpCode.ILSpy.Metadata
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(eventDef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(eventDef.Name):X} \"{Name}\"";
public string Name => metadata.GetString(eventDef.Name); public string Name => metadataFile.Metadata.GetString(eventDef.Name);
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); IEntity IMemberTreeNode.Member {
get {
return ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule)?.GetDefinition(handle);
}
}
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Type => MetadataTokens.GetToken(eventDef.Type); public int Type => MetadataTokens.GetToken(eventDef.Type);
public void OnTypeClick() public void OnTypeClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, eventDef.Type, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, eventDef.Type, protocol: "metadata"));
} }
string typeTooltip; string typeTooltip;
public string TypeTooltip => GenerateTooltip(ref typeTooltip, module, eventDef.Type); public string TypeTooltip => GenerateTooltip(ref typeTooltip, metadataFile, eventDef.Type);
public EventDefEntry(PEFile module, EventDefinitionHandle handle) public EventDefEntry(MetadataFile metadataFile, EventDefinitionHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.eventDef = metadata.GetEventDefinition(handle); this.eventDef = metadataFile.Metadata.GetEventDefinition(handle);
this.typeTooltip = null; this.typeTooltip = null;
} }
} }

37
ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs

@ -22,21 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ExportedTypeTableTreeNode : MetadataTableTreeNode internal class ExportedTypeTableTreeNode : MetadataTableTreeNode
{ {
public ExportedTypeTableTreeNode(PEFile module) public ExportedTypeTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.ExportedType, module) : base(HandleKind.ExportedType, metadataFile)
{ {
} }
public override object Text => $"27 ExportedType ({module.Metadata.GetTableRowCount(TableIndex.ExportedType)})"; public override object Text => $"27 ExportedType ({metadataFile.Metadata.GetTableRowCount(TableIndex.ExportedType)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -44,13 +41,13 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<ExportedTypeEntry>(); var list = new List<ExportedTypeEntry>();
ExportedTypeEntry scrollTargetEntry = default; ExportedTypeEntry scrollTargetEntry = default;
foreach (var row in metadata.ExportedTypes) foreach (var row in metadata.ExportedTypes)
{ {
ExportedTypeEntry entry = new ExportedTypeEntry(module.Reader.PEHeaders.MetadataStartOffset, module, row, metadata.GetExportedType(row)); ExportedTypeEntry entry = new ExportedTypeEntry(metadataFile, row, metadataFile.Metadata.GetExportedType(row));
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -72,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ExportedTypeEntry struct ExportedTypeEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly ExportedTypeHandle handle; readonly ExportedTypeHandle handle;
readonly ExportedType type; readonly ExportedType type;
@ -82,9 +77,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.ExportedType) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ExportedType)
+ metadata.GetTableRowSize(TableIndex.ExportedType) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.ExportedType) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public TypeAttributes Attributes => type.Attributes; public TypeAttributes Attributes => type.Attributes;
@ -104,28 +99,26 @@ namespace ICSharpCode.ILSpy.Metadata
public string TypeNameTooltip => $"{MetadataTokens.GetHeapOffset(type.Name):X} \"{TypeName}\""; public string TypeNameTooltip => $"{MetadataTokens.GetHeapOffset(type.Name):X} \"{TypeName}\"";
public string TypeName => metadata.GetString(type.Name); public string TypeName => metadataFile.Metadata.GetString(type.Name);
public string TypeNamespaceTooltip => $"{MetadataTokens.GetHeapOffset(type.Namespace):X} \"{TypeNamespace}\""; public string TypeNamespaceTooltip => $"{MetadataTokens.GetHeapOffset(type.Namespace):X} \"{TypeNamespace}\"";
public string TypeNamespace => metadata.GetString(type.Namespace); public string TypeNamespace => metadataFile.Metadata.GetString(type.Namespace);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Implementation => MetadataTokens.GetToken(type.Implementation); public int Implementation => MetadataTokens.GetToken(type.Implementation);
public void OnImplementationClick() public void OnImplementationClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, type.Implementation, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, type.Implementation, protocol: "metadata"));
} }
string implementationTooltip; string implementationTooltip;
public string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, module, type.Implementation); public string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, metadataFile, type.Implementation);
public ExportedTypeEntry(int metadataOffset, PEFile module, ExportedTypeHandle handle, ExportedType type) public ExportedTypeEntry(MetadataFile metadataFile, ExportedTypeHandle handle, ExportedType type)
{ {
this.metadataOffset = metadataOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.type = type; this.type = type;
this.implementationTooltip = null; this.implementationTooltip = null;

35
ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs

@ -23,22 +23,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldLayoutTableTreeNode : MetadataTableTreeNode internal class FieldLayoutTableTreeNode : MetadataTableTreeNode
{ {
public FieldLayoutTableTreeNode(PEFile module) public FieldLayoutTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x10, module) : base((HandleKind)0x10, metadataFile)
{ {
} }
public override object Text => $"10 FieldLayout ({module.Metadata.GetTableRowCount(TableIndex.FieldLayout)})"; public override object Text => $"10 FieldLayout ({metadataFile.Metadata.GetTableRowCount(TableIndex.FieldLayout)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -46,17 +42,16 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<FieldLayoutEntry>(); var list = new List<FieldLayoutEntry>();
FieldLayoutEntry scrollTargetEntry = default; FieldLayoutEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.FieldLayout); var length = metadata.GetTableRowCount(TableIndex.FieldLayout);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
FieldLayoutEntry entry = new FieldLayoutEntry(module, ptr, metadataOffset, rid); FieldLayoutEntry entry = new FieldLayoutEntry(metadataFile, ptr, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -90,8 +85,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct FieldLayoutEntry struct FieldLayoutEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly FieldLayout fieldLayout; readonly FieldLayout fieldLayout;
public int RID { get; } public int RID { get; }
@ -105,24 +99,23 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnFieldClick() public void OnFieldClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, fieldLayout.Field, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, fieldLayout.Field, protocol: "metadata"));
} }
string fieldTooltip; string fieldTooltip;
public string FieldTooltip => GenerateTooltip(ref fieldTooltip, module, fieldLayout.Field); public string FieldTooltip => GenerateTooltip(ref fieldTooltip, metadataFile, fieldLayout.Field);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public int FieldOffset => fieldLayout.Offset; public int FieldOffset => fieldLayout.Offset;
public FieldLayoutEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public FieldLayoutEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.FieldLayout) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldLayout)
+ metadata.GetTableRowSize(TableIndex.FieldLayout) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.FieldLayout) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4; int fieldDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;
this.fieldLayout = new FieldLayout(ptr.Slice(rowOffset), fieldDefSize); this.fieldLayout = new FieldLayout(ptr.Slice(rowOffset), fieldDefSize);
this.fieldTooltip = null; this.fieldTooltip = null;
} }

37
ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldMarshalTableTreeNode : MetadataTableTreeNode internal class FieldMarshalTableTreeNode : MetadataTableTreeNode
{ {
public FieldMarshalTableTreeNode(PEFile module) public FieldMarshalTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x0D, module) : base((HandleKind)0x0D, metadataFile)
{ {
} }
public override object Text => $"0D FieldMarshal ({module.Metadata.GetTableRowCount(TableIndex.FieldMarshal)})"; public override object Text => $"0D FieldMarshal ({metadataFile.Metadata.GetTableRowCount(TableIndex.FieldMarshal)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,17 +41,16 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<FieldMarshalEntry>(); var list = new List<FieldMarshalEntry>();
FieldMarshalEntry scrollTargetEntry = default; FieldMarshalEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.FieldMarshal); var length = metadata.GetTableRowCount(TableIndex.FieldMarshal);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
FieldMarshalEntry entry = new FieldMarshalEntry(module, ptr, metadataOffset, rid); FieldMarshalEntry entry = new FieldMarshalEntry(metadataFile, ptr, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -89,8 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct FieldMarshalEntry struct FieldMarshalEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly FieldMarshal fieldMarshal; readonly FieldMarshal fieldMarshal;
public int RID { get; } public int RID { get; }
@ -104,25 +98,24 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, fieldMarshal.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, fieldMarshal.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, fieldMarshal.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, fieldMarshal.Parent);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int NativeType => MetadataTokens.GetHeapOffset(fieldMarshal.NativeType); public int NativeType => MetadataTokens.GetHeapOffset(fieldMarshal.NativeType);
public FieldMarshalEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public FieldMarshalEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.FieldMarshal) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldMarshal)
+ metadata.GetTableRowSize(TableIndex.FieldMarshal) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.FieldMarshal) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int hasFieldMarshalRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param); int hasFieldMarshalRefSize = metadataFile.Metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param);
int blobHeapSize = metadata.GetHeapSize(HeapIndex.Blob) < ushort.MaxValue ? 2 : 4; int blobHeapSize = metadataFile.Metadata.GetHeapSize(HeapIndex.Blob) < ushort.MaxValue ? 2 : 4;
this.fieldMarshal = new FieldMarshal(ptr.Slice(rowOffset), blobHeapSize, hasFieldMarshalRefSize); this.fieldMarshal = new FieldMarshal(ptr.Slice(rowOffset), blobHeapSize, hasFieldMarshalRefSize);
this.parentTooltip = null; this.parentTooltip = null;
} }

34
ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs

@ -23,22 +23,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldRVATableTreeNode : MetadataTableTreeNode internal class FieldRVATableTreeNode : MetadataTableTreeNode
{ {
public FieldRVATableTreeNode(PEFile module) public FieldRVATableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x1D, module) : base((HandleKind)0x1D, metadataFile)
{ {
} }
public override object Text => $"1D FieldRVA ({module.Metadata.GetTableRowCount(TableIndex.FieldRva)})"; public override object Text => $"1D FieldRVA ({metadataFile.Metadata.GetTableRowCount(TableIndex.FieldRva)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -46,17 +42,17 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<FieldRVAEntry>(); var list = new List<FieldRVAEntry>();
FieldRVAEntry scrollTargetEntry = default; FieldRVAEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.FieldRva); var length = metadata.GetTableRowCount(TableIndex.FieldRva);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; int metadataOffset = metadataFile.MetadataOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
FieldRVAEntry entry = new FieldRVAEntry(module, ptr, metadataOffset, rid); FieldRVAEntry entry = new FieldRVAEntry(metadataFile, metadataOffset, ptr, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -90,8 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct FieldRVAEntry struct FieldRVAEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly FieldRVA fieldRVA; readonly FieldRVA fieldRVA;
public int RID { get; } public int RID { get; }
@ -105,24 +100,23 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnFieldClick() public void OnFieldClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, fieldRVA.Field, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, fieldRVA.Field, protocol: "metadata"));
} }
string fieldTooltip; string fieldTooltip;
public string FieldTooltip => GenerateTooltip(ref fieldTooltip, module, fieldRVA.Field); public string FieldTooltip => GenerateTooltip(ref fieldTooltip, metadataFile, fieldRVA.Field);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public int FieldOffset => fieldRVA.Offset; public int FieldOffset => fieldRVA.Offset;
public FieldRVAEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public FieldRVAEntry(MetadataFile metadataFile, int metadataOffset, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.FieldRva) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldRva)
+ metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataOffset + rowOffset;
int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4; int fieldDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;
this.fieldRVA = new FieldRVA(ptr.Slice(rowOffset), fieldDefSize); this.fieldRVA = new FieldRVA(ptr.Slice(rowOffset), fieldDefSize);
this.fieldTooltip = null; this.fieldTooltip = null;
} }

41
ILSpy/Metadata/CorTables/FieldTableTreeNode.cs

@ -21,13 +21,8 @@ using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
@ -36,21 +31,19 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldTableTreeNode : MetadataTableTreeNode internal class FieldTableTreeNode : MetadataTableTreeNode
{ {
public FieldTableTreeNode(PEFile module) public FieldTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.FieldDefinition, module) : base(HandleKind.FieldDefinition, metadataFile)
{ {
} }
public override object Text => $"04 Field ({module.Metadata.GetTableRowCount(TableIndex.Field)})"; public override object Text => $"04 Field ({metadataFile.Metadata.GetTableRowCount(TableIndex.Field)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
tabPage.Title = Text.ToString(); tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<FieldDefEntry>(); var list = new List<FieldDefEntry>();
@ -58,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
foreach (var row in metadata.FieldDefinitions) foreach (var row in metadata.FieldDefinitions)
{ {
var entry = new FieldDefEntry(module, row); var entry = new FieldDefEntry(metadataFile, row);
if (scrollTarget == entry.RID) if (scrollTarget == entry.RID)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -80,9 +73,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct FieldDefEntry : IMemberTreeNode struct FieldDefEntry : IMemberTreeNode
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly FieldDefinitionHandle handle; readonly FieldDefinitionHandle handle;
readonly FieldDefinition fieldDef; readonly FieldDefinition fieldDef;
@ -90,9 +81,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.Field) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Field)
+ metadata.GetTableRowSize(TableIndex.Field) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.Field) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public FieldAttributes Attributes => fieldDef.Attributes; public FieldAttributes Attributes => fieldDef.Attributes;
@ -104,25 +95,23 @@ namespace ICSharpCode.ILSpy.Metadata
FlagGroup.CreateMultipleChoiceGroup(typeof(FieldAttributes), "Flags:", (int)otherFlagsMask, (int)(fieldDef.Attributes & otherFlagsMask), includeAll: false), FlagGroup.CreateMultipleChoiceGroup(typeof(FieldAttributes), "Flags:", (int)otherFlagsMask, (int)(fieldDef.Attributes & otherFlagsMask), includeAll: false),
}; };
public string Name => metadata.GetString(fieldDef.Name); public string Name => metadataFile.Metadata.GetString(fieldDef.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(fieldDef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(fieldDef.Name):X} \"{Name}\"";
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule)?.GetDefinition(handle);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(fieldDef.Signature); public int Signature => MetadataTokens.GetHeapOffset(fieldDef.Signature);
string signatureTooltip; string signatureTooltip;
public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);
public FieldDefEntry(PEFile module, FieldDefinitionHandle handle) public FieldDefEntry(MetadataFile metadataFile, FieldDefinitionHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.fieldDef = metadata.GetFieldDefinition(handle); this.fieldDef = metadataFile.Metadata.GetFieldDefinition(handle);
this.signatureTooltip = null; this.signatureTooltip = null;
} }
} }

34
ILSpy/Metadata/CorTables/FileTableTreeNode.cs

@ -27,14 +27,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
class FileTableTreeNode : MetadataTableTreeNode class FileTableTreeNode : MetadataTableTreeNode
{ {
public FileTableTreeNode(PEFile module) public FileTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.AssemblyFile, module) : base(HandleKind.AssemblyFile, metadataFile)
{ {
} }
public override object Text => $"26 File ({module.Metadata.GetTableRowCount(TableIndex.File)})"; public override object Text => $"26 File ({metadataFile.Metadata.GetTableRowCount(TableIndex.File)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -42,14 +40,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<FileEntry>(); var list = new List<FileEntry>();
FileEntry scrollTargetEntry = default; FileEntry scrollTargetEntry = default;
foreach (var row in metadata.AssemblyFiles) foreach (var row in metadata.AssemblyFiles)
{ {
FileEntry entry = new FileEntry(module, row); FileEntry entry = new FileEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -71,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct FileEntry struct FileEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly AssemblyFileHandle handle; readonly AssemblyFileHandle handle;
readonly AssemblyFile assemblyFile; readonly AssemblyFile assemblyFile;
@ -81,16 +77,16 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.File) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.File)
+ metadata.GetTableRowSize(TableIndex.File) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.File) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public int Attributes => assemblyFile.ContainsMetadata ? 1 : 0; public int Attributes => assemblyFile.ContainsMetadata ? 1 : 0;
public string AttributesTooltip => assemblyFile.ContainsMetadata ? "ContainsMetaData" : "ContainsNoMetaData"; public string AttributesTooltip => assemblyFile.ContainsMetadata ? "ContainsMetaData" : "ContainsNoMetaData";
public string Name => metadata.GetString(assemblyFile.Name); public string Name => metadataFile.Metadata.GetString(assemblyFile.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(assemblyFile.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(assemblyFile.Name):X} \"{Name}\"";
@ -101,18 +97,16 @@ namespace ICSharpCode.ILSpy.Metadata
get { get {
if (assemblyFile.HashValue.IsNil) if (assemblyFile.HashValue.IsNil)
return null; return null;
System.Collections.Immutable.ImmutableArray<byte> token = metadata.GetBlobContent(assemblyFile.HashValue); System.Collections.Immutable.ImmutableArray<byte> token = metadataFile.Metadata.GetBlobContent(assemblyFile.HashValue);
return token.ToHexString(token.Length); return token.ToHexString(token.Length);
} }
} }
public FileEntry(PEFile module, AssemblyFileHandle handle) public FileEntry(MetadataFile metadataFile, AssemblyFileHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.assemblyFile = metadata.GetAssemblyFile(handle); this.assemblyFile = metadataFile.Metadata.GetAssemblyFile(handle);
} }
} }

43
ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs

@ -21,7 +21,6 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
@ -29,14 +28,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class GenericParamConstraintTableTreeNode : MetadataTableTreeNode internal class GenericParamConstraintTableTreeNode : MetadataTableTreeNode
{ {
public GenericParamConstraintTableTreeNode(PEFile module) public GenericParamConstraintTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.GenericParameterConstraint, module) : base(HandleKind.GenericParameterConstraint, metadataFile)
{ {
} }
public override object Text => $"2C GenericParamConstraint ({module.Metadata.GetTableRowCount(TableIndex.GenericParamConstraint)})"; public override object Text => $"2C GenericParamConstraint ({metadataFile.Metadata.GetTableRowCount(TableIndex.GenericParamConstraint)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -44,14 +41,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<GenericParamConstraintEntry>(); var list = new List<GenericParamConstraintEntry>();
GenericParamConstraintEntry scrollTargetEntry = default; GenericParamConstraintEntry scrollTargetEntry = default;
for (int row = 1; row <= metadata.GetTableRowCount(TableIndex.GenericParamConstraint); row++) for (int row = 1; row <= metadata.GetTableRowCount(TableIndex.GenericParamConstraint); row++)
{ {
GenericParamConstraintEntry entry = new GenericParamConstraintEntry(module, MetadataTokens.GenericParameterConstraintHandle(row)); GenericParamConstraintEntry entry = new GenericParamConstraintEntry(metadataFile, MetadataTokens.GenericParameterConstraintHandle(row));
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -72,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct GenericParamConstraintEntry struct GenericParamConstraintEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly GenericParameterConstraintHandle handle; readonly GenericParameterConstraintHandle handle;
readonly GenericParameterConstraint genericParamConstraint; readonly GenericParameterConstraint genericParamConstraint;
@ -82,16 +77,16 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.GenericParamConstraint) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.GenericParamConstraint)
+ metadata.GetTableRowSize(TableIndex.GenericParamConstraint) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.GenericParamConstraint) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Owner => MetadataTokens.GetToken(genericParamConstraint.Parameter); public int Owner => MetadataTokens.GetToken(genericParamConstraint.Parameter);
public void OnOwnerClick() public void OnOwnerClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, genericParamConstraint.Parameter, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, genericParamConstraint.Parameter, protocol: "metadata"));
} }
string ownerTooltip; string ownerTooltip;
@ -101,9 +96,9 @@ namespace ICSharpCode.ILSpy.Metadata
if (ownerTooltip == null) if (ownerTooltip == null)
{ {
ITextOutput output = new PlainTextOutput(); ITextOutput output = new PlainTextOutput();
var p = metadata.GetGenericParameter(genericParamConstraint.Parameter); var p = metadataFile.Metadata.GetGenericParameter(genericParamConstraint.Parameter);
output.Write("parameter " + p.Index + (p.Name.IsNil ? "" : " (" + metadata.GetString(p.Name) + ")") + " of "); output.Write("parameter " + p.Index + (p.Name.IsNil ? "" : " (" + metadataFile.Metadata.GetString(p.Name) + ")") + " of ");
p.Parent.WriteTo(module, output, default); p.Parent.WriteTo(metadataFile, output, default);
ownerTooltip = output.ToString(); ownerTooltip = output.ToString();
} }
return ownerTooltip; return ownerTooltip;
@ -115,19 +110,17 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnTypeClick() public void OnTypeClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, genericParamConstraint.Type, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, genericParamConstraint.Type, protocol: "metadata"));
} }
string typeTooltip; string typeTooltip;
public string TypeTooltip => GenerateTooltip(ref typeTooltip, module, genericParamConstraint.Type); public string TypeTooltip => GenerateTooltip(ref typeTooltip, metadataFile, genericParamConstraint.Type);
public GenericParamConstraintEntry(PEFile module, GenericParameterConstraintHandle handle) public GenericParamConstraintEntry(MetadataFile metadataFile, GenericParameterConstraintHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.genericParamConstraint = metadata.GetGenericParameterConstraint(handle); this.genericParamConstraint = metadataFile.Metadata.GetGenericParameterConstraint(handle);
this.ownerTooltip = null; this.ownerTooltip = null;
this.typeTooltip = null; this.typeTooltip = null;
} }

38
ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class GenericParamTableTreeNode : MetadataTableTreeNode internal class GenericParamTableTreeNode : MetadataTableTreeNode
{ {
public GenericParamTableTreeNode(PEFile module) public GenericParamTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.GenericParameter, module) : base(HandleKind.GenericParameter, metadataFile)
{ {
} }
public override object Text => $"2A GenericParam ({module.Metadata.GetTableRowCount(TableIndex.GenericParam)})"; public override object Text => $"2A GenericParam ({metadataFile.Metadata.GetTableRowCount(TableIndex.GenericParam)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -49,9 +45,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<GenericParamEntry>(); var list = new List<GenericParamEntry>();
GenericParamEntry scrollTargetEntry = default; GenericParamEntry scrollTargetEntry = default;
for (int row = 1; row <= module.Metadata.GetTableRowCount(TableIndex.GenericParam); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.GenericParam); row++)
{ {
GenericParamEntry entry = new GenericParamEntry(module, MetadataTokens.GenericParameterHandle(row)); GenericParamEntry entry = new GenericParamEntry(metadataFile, MetadataTokens.GenericParameterHandle(row));
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -72,9 +68,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct GenericParamEntry struct GenericParamEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly GenericParameterHandle handle; readonly GenericParameterHandle handle;
readonly GenericParameter genericParam; readonly GenericParameter genericParam;
@ -82,9 +76,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.GenericParam) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.GenericParam)
+ metadata.GetTableRowSize(TableIndex.GenericParam) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.GenericParam) * (RID - 1);
public int Number => genericParam.Index; public int Number => genericParam.Index;
@ -101,23 +95,21 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnOwnerClick() public void OnOwnerClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, genericParam.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, genericParam.Parent, protocol: "metadata"));
} }
string ownerTooltip; string ownerTooltip;
public string OwnerTooltip => GenerateTooltip(ref ownerTooltip, module, genericParam.Parent); public string OwnerTooltip => GenerateTooltip(ref ownerTooltip, metadataFile, genericParam.Parent);
public string Name => metadata.GetString(genericParam.Name); public string Name => metadataFile.Metadata.GetString(genericParam.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(genericParam.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(genericParam.Name):X} \"{Name}\"";
public GenericParamEntry(PEFile module, GenericParameterHandle handle) public GenericParamEntry(MetadataFile metadataFile, GenericParameterHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.genericParam = metadata.GetGenericParameter(handle); this.genericParam = metadataFile.Metadata.GetGenericParameter(handle);
this.ownerTooltip = null; this.ownerTooltip = null;
} }
} }

45
ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs

@ -23,8 +23,6 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using Mono.Cecil; using Mono.Cecil;
@ -33,14 +31,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
class ImplMapTableTreeNode : MetadataTableTreeNode class ImplMapTableTreeNode : MetadataTableTreeNode
{ {
public ImplMapTableTreeNode(PEFile module) public ImplMapTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x1C, module) : base((HandleKind)0x1C, metadataFile)
{ {
} }
public override object Text => $"1C ImplMap ({module.Metadata.GetTableRowCount(TableIndex.ImplMap)})"; public override object Text => $"1C ImplMap ({metadataFile.Metadata.GetTableRowCount(TableIndex.ImplMap)})";
public override object Icon => Images.Literal;
@ -50,17 +46,16 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<ImplMapEntry>(); var list = new List<ImplMapEntry>();
ImplMapEntry scrollTargetEntry = default; ImplMapEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.ImplMap); var length = metadata.GetTableRowCount(TableIndex.ImplMap);
var span = metadata.AsReadOnlySpan(); var span = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
ImplMapEntry entry = new ImplMapEntry(module, span, metadataOffset, rid); ImplMapEntry entry = new ImplMapEntry(metadataFile, span, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -98,8 +93,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ImplMapEntry struct ImplMapEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly ImplMap implMap; readonly ImplMap implMap;
public int RID { get; } public int RID { get; }
@ -124,38 +118,37 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMemberForwardedClick() public void OnMemberForwardedClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, implMap.MemberForwarded, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, implMap.MemberForwarded, protocol: "metadata"));
} }
string memberForwardedTooltip; string memberForwardedTooltip;
public string MemberForwardedTooltip => GenerateTooltip(ref memberForwardedTooltip, module, implMap.MemberForwarded); public string MemberForwardedTooltip => GenerateTooltip(ref memberForwardedTooltip, metadataFile, implMap.MemberForwarded);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int ImportScope => MetadataTokens.GetToken(implMap.ImportScope); public int ImportScope => MetadataTokens.GetToken(implMap.ImportScope);
public void OnImportScopeClick() public void OnImportScopeClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, implMap.ImportScope, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, implMap.ImportScope, protocol: "metadata"));
} }
string importScopeTooltip; string importScopeTooltip;
public string ImportScopeTooltip => GenerateTooltip(ref importScopeTooltip, module, implMap.ImportScope); public string ImportScopeTooltip => GenerateTooltip(ref importScopeTooltip, metadataFile, implMap.ImportScope);
public string ImportName => metadata.GetString(implMap.ImportName); public string ImportName => metadataFile.Metadata.GetString(implMap.ImportName);
public string ImportNameTooltip => $"{MetadataTokens.GetHeapOffset(implMap.ImportName):X} \"{ImportName}\""; public string ImportNameTooltip => $"{MetadataTokens.GetHeapOffset(implMap.ImportName):X} \"{ImportName}\"";
public ImplMapEntry(PEFile module, ReadOnlySpan<byte> span, int metadataOffset, int row) public ImplMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> span, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.ImplMap) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ImplMap)
+ metadata.GetTableRowSize(TableIndex.ImplMap) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.ImplMap) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int moduleRefSize = metadata.GetTableRowCount(TableIndex.ModuleRef) < ushort.MaxValue ? 2 : 4; int moduleRefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.ModuleRef) < ushort.MaxValue ? 2 : 4;
int memberForwardedTagRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field); int memberForwardedTagRefSize = metadataFile.Metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field);
int stringHandleSize = metadata.GetHeapSize(HeapIndex.String) < ushort.MaxValue ? 2 : 4; int stringHandleSize = metadataFile.Metadata.GetHeapSize(HeapIndex.String) < ushort.MaxValue ? 2 : 4;
this.implMap = new ImplMap(span.Slice(rowOffset), moduleRefSize, memberForwardedTagRefSize, stringHandleSize); this.implMap = new ImplMap(span.Slice(rowOffset), moduleRefSize, memberForwardedTagRefSize, stringHandleSize);
this.importScopeTooltip = null; this.importScopeTooltip = null;
this.memberForwardedTooltip = null; this.memberForwardedTooltip = null;

40
ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class InterfaceImplTableTreeNode : MetadataTableTreeNode class InterfaceImplTableTreeNode : MetadataTableTreeNode
{ {
public InterfaceImplTableTreeNode(PEFile module) public InterfaceImplTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x09, module) : base((HandleKind)0x09, metadataFile)
{ {
} }
public override object Text => $"09 InterfaceImpl ({module.Metadata.GetTableRowCount(TableIndex.InterfaceImpl)})"; public override object Text => $"09 InterfaceImpl ({metadataFile.Metadata.GetTableRowCount(TableIndex.InterfaceImpl)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,17 +41,17 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<InterfaceImplEntry>(); var list = new List<InterfaceImplEntry>();
InterfaceImplEntry scrollTargetEntry = default; InterfaceImplEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.InterfaceImpl); var length = metadata.GetTableRowCount(TableIndex.InterfaceImpl);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; int metadataOffset = metadataFile.MetadataOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
InterfaceImplEntry entry = new InterfaceImplEntry(module, ptr, metadataOffset, rid); InterfaceImplEntry entry = new InterfaceImplEntry(metadataFile, ptr, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -89,8 +85,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct InterfaceImplEntry struct InterfaceImplEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly InterfaceImpl interfaceImpl; readonly InterfaceImpl interfaceImpl;
public int RID { get; } public int RID { get; }
@ -104,32 +99,31 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnClassClick() public void OnClassClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, interfaceImpl.Class, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, interfaceImpl.Class, protocol: "metadata"));
} }
string classTooltip; string classTooltip;
public string ClassTooltip => GenerateTooltip(ref classTooltip, module, interfaceImpl.Class); public string ClassTooltip => GenerateTooltip(ref classTooltip, metadataFile, interfaceImpl.Class);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Interface => MetadataTokens.GetToken(interfaceImpl.Interface); public int Interface => MetadataTokens.GetToken(interfaceImpl.Interface);
public void OnInterfaceClick() public void OnInterfaceClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, interfaceImpl.Interface, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, interfaceImpl.Interface, protocol: "metadata"));
} }
string interfaceTooltip; string interfaceTooltip;
public string InterfaceTooltip => GenerateTooltip(ref interfaceTooltip, module, interfaceImpl.Interface); public string InterfaceTooltip => GenerateTooltip(ref interfaceTooltip, metadataFile, interfaceImpl.Interface);
public InterfaceImplEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public InterfaceImplEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.InterfaceImpl) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.InterfaceImpl)
+ metadata.GetTableRowSize(TableIndex.InterfaceImpl) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.InterfaceImpl) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
this.interfaceImpl = new InterfaceImpl(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec)); this.interfaceImpl = new InterfaceImpl(ptr.Slice(rowOffset), metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadataFile.Metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec));
this.interfaceTooltip = null; this.interfaceTooltip = null;
this.classTooltip = null; this.classTooltip = null;
} }

38
ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class ManifestResourceTableTreeNode : MetadataTableTreeNode class ManifestResourceTableTreeNode : MetadataTableTreeNode
{ {
public ManifestResourceTableTreeNode(PEFile module) public ManifestResourceTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.ManifestResource, module) : base(HandleKind.ManifestResource, metadataFile)
{ {
} }
public override object Text => $"28 ManifestResource ({module.Metadata.GetTableRowCount(TableIndex.ManifestResource)})"; public override object Text => $"28 ManifestResource ({metadataFile.Metadata.GetTableRowCount(TableIndex.ManifestResource)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,14 +41,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<ManifestResourceEntry>(); var list = new List<ManifestResourceEntry>();
ManifestResourceEntry scrollTargetEntry = default; ManifestResourceEntry scrollTargetEntry = default;
foreach (var row in metadata.ManifestResources) foreach (var row in metadata.ManifestResources)
{ {
ManifestResourceEntry entry = new ManifestResourceEntry(module, row); ManifestResourceEntry entry = new ManifestResourceEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -74,9 +70,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ManifestResourceEntry struct ManifestResourceEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly ManifestResourceHandle handle; readonly ManifestResourceHandle handle;
readonly ManifestResource manifestResource; readonly ManifestResource manifestResource;
@ -84,16 +78,16 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.ManifestResource) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ManifestResource)
+ metadata.GetTableRowSize(TableIndex.ManifestResource) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.ManifestResource) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public ManifestResourceAttributes Attributes => manifestResource.Attributes; public ManifestResourceAttributes Attributes => manifestResource.Attributes;
public object AttributesTooltip => manifestResource.Attributes.ToString(); public object AttributesTooltip => manifestResource.Attributes.ToString();
public string Name => metadata.GetString(manifestResource.Name); public string Name => metadataFile.Metadata.GetString(manifestResource.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(manifestResource.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(manifestResource.Name):X} \"{Name}\"";
@ -102,19 +96,17 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnImplementationClick() public void OnImplementationClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, manifestResource.Implementation, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, manifestResource.Implementation, protocol: "metadata"));
} }
string implementationTooltip; string implementationTooltip;
public string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, module, manifestResource.Implementation); public string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, metadataFile, manifestResource.Implementation);
public ManifestResourceEntry(PEFile module, ManifestResourceHandle handle) public ManifestResourceEntry(MetadataFile metadataFile, ManifestResourceHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.manifestResource = metadata.GetManifestResource(handle); this.manifestResource = metadataFile.Metadata.GetManifestResource(handle);
this.implementationTooltip = null; this.implementationTooltip = null;
} }
} }

40
ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs

@ -21,22 +21,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MemberRefTableTreeNode : MetadataTableTreeNode internal class MemberRefTableTreeNode : MetadataTableTreeNode
{ {
public MemberRefTableTreeNode(PEFile module) public MemberRefTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.MemberReference, module) : base(HandleKind.MemberReference, metadataFile)
{ {
} }
public override object Text => $"0A MemberRef ({module.Metadata.GetTableRowCount(TableIndex.MemberRef)})"; public override object Text => $"0A MemberRef ({metadataFile.Metadata.GetTableRowCount(TableIndex.MemberRef)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -44,14 +40,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<MemberRefEntry>(); var list = new List<MemberRefEntry>();
MemberRefEntry scrollTargetEntry = default; MemberRefEntry scrollTargetEntry = default;
foreach (var row in metadata.MemberReferences) foreach (var row in metadata.MemberReferences)
{ {
MemberRefEntry entry = new MemberRefEntry(module, row); MemberRefEntry entry = new MemberRefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -73,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct MemberRefEntry struct MemberRefEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly MemberReferenceHandle handle; readonly MemberReferenceHandle handle;
readonly MemberReference memberRef; readonly MemberReference memberRef;
@ -83,22 +77,22 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.MemberRef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MemberRef)
+ metadata.GetTableRowSize(TableIndex.MemberRef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.MemberRef) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Parent => MetadataTokens.GetToken(memberRef.Parent); public int Parent => MetadataTokens.GetToken(memberRef.Parent);
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, memberRef.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, memberRef.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, memberRef.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, memberRef.Parent);
public string Name => metadata.GetString(memberRef.Name); public string Name => metadataFile.Metadata.GetString(memberRef.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(memberRef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(memberRef.Name):X} \"{Name}\"";
@ -106,15 +100,13 @@ namespace ICSharpCode.ILSpy.Metadata
public int Signature => MetadataTokens.GetHeapOffset(memberRef.Signature); public int Signature => MetadataTokens.GetHeapOffset(memberRef.Signature);
string signatureTooltip; string signatureTooltip;
public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);
public MemberRefEntry(PEFile module, MemberReferenceHandle handle) public MemberRefEntry(MetadataFile metadataFile, MemberReferenceHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.memberRef = metadata.GetMemberReference(handle); this.memberRef = metadataFile.Metadata.GetMemberReference(handle);
this.signatureTooltip = null; this.signatureTooltip = null;
this.parentTooltip = null; this.parentTooltip = null;
} }

44
ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs

@ -21,22 +21,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodImplTableTreeNode : MetadataTableTreeNode internal class MethodImplTableTreeNode : MetadataTableTreeNode
{ {
public MethodImplTableTreeNode(PEFile module) public MethodImplTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x19, module) : base((HandleKind)0x19, metadataFile)
{ {
} }
public override object Text => $"19 MethodImpl ({module.Metadata.GetTableRowCount(TableIndex.MethodImpl)})"; public override object Text => $"19 MethodImpl ({metadataFile.Metadata.GetTableRowCount(TableIndex.MethodImpl)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -48,9 +44,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<MethodImplEntry>(); var list = new List<MethodImplEntry>();
MethodImplEntry scrollTargetEntry = default; MethodImplEntry scrollTargetEntry = default;
for (int row = 1; row <= module.Metadata.GetTableRowCount(TableIndex.MethodImpl); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.MethodImpl); row++)
{ {
MethodImplEntry entry = new MethodImplEntry(module, MetadataTokens.MethodImplementationHandle(row)); MethodImplEntry entry = new MethodImplEntry(metadataFile, MetadataTokens.MethodImplementationHandle(row));
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -72,9 +68,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct MethodImplEntry struct MethodImplEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly MethodImplementationHandle handle; readonly MethodImplementationHandle handle;
readonly MethodImplementation methodImpl; readonly MethodImplementation methodImpl;
@ -82,50 +76,48 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.MethodDef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDef)
+ metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int MethodDeclaration => MetadataTokens.GetToken(methodImpl.MethodDeclaration); public int MethodDeclaration => MetadataTokens.GetToken(methodImpl.MethodDeclaration);
public void OnMethodDeclarationClick() public void OnMethodDeclarationClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, methodImpl.MethodDeclaration, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodImpl.MethodDeclaration, protocol: "metadata"));
} }
string methodDeclarationTooltip; string methodDeclarationTooltip;
public string MethodDeclarationTooltip => GenerateTooltip(ref methodDeclarationTooltip, module, methodImpl.MethodDeclaration); public string MethodDeclarationTooltip => GenerateTooltip(ref methodDeclarationTooltip, metadataFile, methodImpl.MethodDeclaration);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int MethodBody => MetadataTokens.GetToken(methodImpl.MethodBody); public int MethodBody => MetadataTokens.GetToken(methodImpl.MethodBody);
public void OnMethodBodyClick() public void OnMethodBodyClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, methodImpl.MethodBody, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodImpl.MethodBody, protocol: "metadata"));
} }
string methodBodyTooltip; string methodBodyTooltip;
public string MethodBodyTooltip => GenerateTooltip(ref methodBodyTooltip, module, methodImpl.MethodBody); public string MethodBodyTooltip => GenerateTooltip(ref methodBodyTooltip, metadataFile, methodImpl.MethodBody);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Type => MetadataTokens.GetToken(methodImpl.Type); public int Type => MetadataTokens.GetToken(methodImpl.Type);
public void OnTypeClick() public void OnTypeClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, methodImpl.Type, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodImpl.Type, protocol: "metadata"));
} }
string typeTooltip; string typeTooltip;
public string TypeTooltip => GenerateTooltip(ref typeTooltip, module, methodImpl.Type); public string TypeTooltip => GenerateTooltip(ref typeTooltip, metadataFile, methodImpl.Type);
public MethodImplEntry(PEFile module, MethodImplementationHandle handle) public MethodImplEntry(MetadataFile metadataFile, MethodImplementationHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.methodImpl = metadata.GetMethodImplementation(handle); this.methodImpl = metadataFile.Metadata.GetMethodImplementation(handle);
this.typeTooltip = null; this.typeTooltip = null;
this.methodBodyTooltip = null; this.methodBodyTooltip = null;
this.methodDeclarationTooltip = null; this.methodDeclarationTooltip = null;

39
ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodSemanticsTableTreeNode : MetadataTableTreeNode internal class MethodSemanticsTableTreeNode : MetadataTableTreeNode
{ {
public MethodSemanticsTableTreeNode(PEFile module) public MethodSemanticsTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x18, module) : base((HandleKind)0x18, metadataFile)
{ {
} }
public override object Text => $"18 MethodSemantics ({module.Metadata.GetTableRowCount(TableIndex.MethodSemantics)})"; public override object Text => $"18 MethodSemantics ({metadataFile.Metadata.GetTableRowCount(TableIndex.MethodSemantics)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,14 +41,13 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata;
var list = new List<MethodSemanticsEntry>(); var list = new List<MethodSemanticsEntry>();
MethodSemanticsEntry scrollTargetEntry = default; MethodSemanticsEntry scrollTargetEntry = default;
foreach (var row in metadata.GetMethodSemantics()) foreach (var row in metadataFile.Metadata.GetMethodSemantics())
{ {
MethodSemanticsEntry entry = new MethodSemanticsEntry(module, row.Handle, row.Semantics, row.Method, row.Association); MethodSemanticsEntry entry = new MethodSemanticsEntry(metadataFile, row.Handle, row.Semantics, row.Method, row.Association);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -74,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct MethodSemanticsEntry struct MethodSemanticsEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly Handle handle; readonly Handle handle;
readonly MethodSemanticsAttributes semantics; readonly MethodSemanticsAttributes semantics;
readonly MethodDefinitionHandle method; readonly MethodDefinitionHandle method;
@ -86,9 +79,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.MethodDef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDef)
+ metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public MethodSemanticsAttributes Semantics => semantics; public MethodSemanticsAttributes Semantics => semantics;
@ -100,28 +93,26 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodClick() public void OnMethodClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, method, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, method, protocol: "metadata"));
} }
string methodTooltip; string methodTooltip;
public string MethodTooltip => GenerateTooltip(ref methodTooltip, module, method); public string MethodTooltip => GenerateTooltip(ref methodTooltip, metadataFile, method);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Association => MetadataTokens.GetToken(association); public int Association => MetadataTokens.GetToken(association);
public void OnAssociationClick() public void OnAssociationClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, association, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, association, protocol: "metadata"));
} }
string associationTooltip; string associationTooltip;
public string AssociationTooltip => GenerateTooltip(ref associationTooltip, module, association); public string AssociationTooltip => GenerateTooltip(ref associationTooltip, metadataFile, association);
public MethodSemanticsEntry(PEFile module, Handle handle, MethodSemanticsAttributes semantics, MethodDefinitionHandle method, EntityHandle association) public MethodSemanticsEntry(MetadataFile metadataFile, Handle handle, MethodSemanticsAttributes semantics, MethodDefinitionHandle method, EntityHandle association)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.semantics = semantics; this.semantics = semantics;
this.method = method; this.method = method;

37
ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs

@ -22,21 +22,18 @@ using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodSpecTableTreeNode : MetadataTableTreeNode internal class MethodSpecTableTreeNode : MetadataTableTreeNode
{ {
public MethodSpecTableTreeNode(PEFile module) public MethodSpecTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.MethodSpecification, module) : base(HandleKind.MethodSpecification, metadataFile)
{ {
} }
public override object Text => $"2B MethodSpec ({module.Metadata.GetTableRowCount(TableIndex.MethodSpec)})"; public override object Text => $"2B MethodSpec ({metadataFile.Metadata.GetTableRowCount(TableIndex.MethodSpec)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -44,14 +41,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<MethodSpecEntry>(); var list = new List<MethodSpecEntry>();
MethodSpecEntry scrollTargetEntry = default; MethodSpecEntry scrollTargetEntry = default;
foreach (var row in metadata.GetMethodSpecifications()) foreach (var row in metadata.GetMethodSpecifications())
{ {
MethodSpecEntry entry = new MethodSpecEntry(module, row); MethodSpecEntry entry = new MethodSpecEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -73,9 +70,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct MethodSpecEntry struct MethodSpecEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly MethodSpecificationHandle handle; readonly MethodSpecificationHandle handle;
readonly MethodSpecification methodSpec; readonly MethodSpecification methodSpec;
@ -83,20 +78,20 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.MethodSpec) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodSpec)
+ metadata.GetTableRowSize(TableIndex.MethodSpec) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.MethodSpec) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Method => MetadataTokens.GetToken(methodSpec.Method); public int Method => MetadataTokens.GetToken(methodSpec.Method);
public void OnMethodClick() public void OnMethodClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, methodSpec.Method, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodSpec.Method, protocol: "metadata"));
} }
string methodTooltip; string methodTooltip;
public string MethodTooltip => GenerateTooltip(ref methodTooltip, module, methodSpec.Method); public string MethodTooltip => GenerateTooltip(ref methodTooltip, metadataFile, methodSpec.Method);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(methodSpec.Signature); public int Signature => MetadataTokens.GetHeapOffset(methodSpec.Signature);
@ -104,7 +99,7 @@ namespace ICSharpCode.ILSpy.Metadata
public string SignatureTooltip { public string SignatureTooltip {
get { get {
ITextOutput output = new PlainTextOutput(); ITextOutput output = new PlainTextOutput();
var signature = methodSpec.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), default); var signature = methodSpec.DecodeSignature(new DisassemblerSignatureTypeProvider(metadataFile, output), default);
bool first = true; bool first = true;
foreach (var type in signature) foreach (var type in signature)
{ {
@ -118,13 +113,11 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public MethodSpecEntry(PEFile module, MethodSpecificationHandle handle) public MethodSpecEntry(MetadataFile metadataFile, MethodSpecificationHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.methodSpec = metadata.GetMethodSpecification(handle); this.methodSpec = metadataFile.Metadata.GetMethodSpecification(handle);
this.methodTooltip = null; this.methodTooltip = null;
} }
} }

45
ILSpy/Metadata/CorTables/MethodTableTreeNode.cs

@ -16,18 +16,13 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Windows.Controls;
using System.Windows.Threading;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
@ -36,14 +31,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodTableTreeNode : MetadataTableTreeNode internal class MethodTableTreeNode : MetadataTableTreeNode
{ {
public MethodTableTreeNode(PEFile module) public MethodTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.MethodDefinition, module) : base(HandleKind.MethodDefinition, metadataFile)
{ {
} }
public override object Text => $"06 Method ({module.Metadata.GetTableRowCount(TableIndex.MethodDef)})"; public override object Text => $"06 Method ({metadataFile.Metadata.GetTableRowCount(TableIndex.MethodDef)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -51,13 +44,13 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<MethodDefEntry>(); var list = new List<MethodDefEntry>();
MethodDefEntry scrollTargetEntry = default; MethodDefEntry scrollTargetEntry = default;
foreach (var row in metadata.MethodDefinitions) foreach (var row in metadata.MethodDefinitions)
{ {
MethodDefEntry entry = new MethodDefEntry(module, row); MethodDefEntry entry = new MethodDefEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -79,9 +72,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct MethodDefEntry : IMemberTreeNode struct MethodDefEntry : IMemberTreeNode
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly MethodDefinitionHandle handle; readonly MethodDefinitionHandle handle;
readonly MethodDefinition methodDef; readonly MethodDefinition methodDef;
@ -89,9 +80,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.MethodDef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDef)
+ metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public MethodAttributes Attributes => methodDef.Attributes; public MethodAttributes Attributes => methodDef.Attributes;
@ -114,7 +105,7 @@ namespace ICSharpCode.ILSpy.Metadata
public int RVA => methodDef.RelativeVirtualAddress; public int RVA => methodDef.RelativeVirtualAddress;
public string Name => metadata.GetString(methodDef.Name); public string Name => metadataFile.Metadata.GetString(methodDef.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(methodDef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(methodDef.Name):X} \"{Name}\"";
@ -123,14 +114,14 @@ namespace ICSharpCode.ILSpy.Metadata
string signatureTooltip; string signatureTooltip;
public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int ParamList => MetadataTokens.GetToken(methodDef.GetParameters().FirstOrDefault()); public int ParamList => MetadataTokens.GetToken(methodDef.GetParameters().FirstOrDefault());
public void OnParamListClick() public void OnParamListClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, methodDef.GetParameters().FirstOrDefault(), protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, methodDef.GetParameters().FirstOrDefault(), protocol: "metadata"));
} }
string paramListTooltip; string paramListTooltip;
@ -139,19 +130,17 @@ namespace ICSharpCode.ILSpy.Metadata
var param = methodDef.GetParameters().FirstOrDefault(); var param = methodDef.GetParameters().FirstOrDefault();
if (param.IsNil) if (param.IsNil)
return null; return null;
return GenerateTooltip(ref paramListTooltip, module, param); return GenerateTooltip(ref paramListTooltip, metadataFile, param);
} }
} }
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule)?.GetDefinition(handle);
public MethodDefEntry(PEFile module, MethodDefinitionHandle handle) public MethodDefEntry(MetadataFile metadataFile, MethodDefinitionHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.methodDef = metadata.GetMethodDefinition(handle); this.methodDef = metadataFile.Metadata.GetMethodDefinition(handle);
this.signatureTooltip = null; this.signatureTooltip = null;
this.paramListTooltip = null; this.paramListTooltip = null;
} }

32
ILSpy/Metadata/CorTables/ModuleRefTableTreeNode.cs

@ -27,14 +27,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ModuleRefTableTreeNode : MetadataTableTreeNode internal class ModuleRefTableTreeNode : MetadataTableTreeNode
{ {
public ModuleRefTableTreeNode(PEFile module) public ModuleRefTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.ModuleReference, module) : base(HandleKind.ModuleReference, metadataFile)
{ {
} }
public override object Text => $"1A ModuleRef ({module.Metadata.GetTableRowCount(TableIndex.ModuleRef)})"; public override object Text => $"1A ModuleRef ({metadataFile.Metadata.GetTableRowCount(TableIndex.ModuleRef)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -42,14 +40,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<ModuleRefEntry>(); var list = new List<ModuleRefEntry>();
ModuleRefEntry scrollTargetEntry = default; ModuleRefEntry scrollTargetEntry = default;
foreach (var row in metadata.GetModuleReferences()) foreach (var row in metadata.GetModuleReferences())
{ {
ModuleRefEntry entry = new ModuleRefEntry(module, row); ModuleRefEntry entry = new ModuleRefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -71,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ModuleRefEntry struct ModuleRefEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly ModuleReferenceHandle handle; readonly ModuleReferenceHandle handle;
readonly ModuleReference moduleRef; readonly ModuleReference moduleRef;
@ -81,21 +77,19 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.ModuleRef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ModuleRef)
+ metadata.GetTableRowSize(TableIndex.ModuleRef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.ModuleRef) * (RID - 1);
public string Name => metadata.GetString(moduleRef.Name); public string Name => metadataFile.Metadata.GetString(moduleRef.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(moduleRef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(moduleRef.Name):X} \"{Name}\"";
public ModuleRefEntry(PEFile module, ModuleReferenceHandle handle) public ModuleRefEntry(MetadataFile metadataFile, ModuleReferenceHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.moduleRef = metadata.GetModuleReference(handle); this.moduleRef = metadataFile.Metadata.GetModuleReference(handle);
} }
} }

36
ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs

@ -27,14 +27,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ModuleTableTreeNode : MetadataTableTreeNode internal class ModuleTableTreeNode : MetadataTableTreeNode
{ {
public ModuleTableTreeNode(PEFile module) public ModuleTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.ModuleDefinition, module) : base(HandleKind.ModuleDefinition, metadataFile)
{ {
} }
public override object Text => $"00 Module ({module.Metadata.GetTableRowCount(TableIndex.Module)})"; public override object Text => $"00 Module ({metadataFile.Metadata.GetTableRowCount(TableIndex.Module)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -46,7 +44,7 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<ModuleEntry>(); var list = new List<ModuleEntry>();
ModuleEntry scrollTargetEntry = default; ModuleEntry scrollTargetEntry = default;
list.Add(new ModuleEntry(module, EntityHandle.ModuleDefinition)); list.Add(new ModuleEntry(metadataFile, EntityHandle.ModuleDefinition));
view.ItemsSource = list; view.ItemsSource = list;
@ -62,9 +60,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ModuleEntry struct ModuleEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly ModuleDefinitionHandle handle; readonly ModuleDefinitionHandle handle;
readonly ModuleDefinition moduleDef; readonly ModuleDefinition moduleDef;
@ -72,38 +68,36 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.Module) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Module)
+ metadata.GetTableRowSize(TableIndex.Module) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.Module) * (RID - 1);
public int Generation => moduleDef.Generation; public int Generation => moduleDef.Generation;
public string Name => metadata.GetString(moduleDef.Name); public string Name => metadataFile.Metadata.GetString(moduleDef.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(moduleDef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(moduleDef.Name):X} \"{Name}\"";
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Mvid => MetadataTokens.GetHeapOffset(moduleDef.Mvid); public int Mvid => MetadataTokens.GetHeapOffset(moduleDef.Mvid);
public string MvidTooltip => metadata.GetGuid(moduleDef.Mvid).ToString(); public string MvidTooltip => metadataFile.Metadata.GetGuid(moduleDef.Mvid).ToString();
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int GenerationId => MetadataTokens.GetHeapOffset(moduleDef.GenerationId); public int GenerationId => MetadataTokens.GetHeapOffset(moduleDef.GenerationId);
public string GenerationIdTooltip => moduleDef.GenerationId.IsNil ? null : metadata.GetGuid(moduleDef.GenerationId).ToString(); public string GenerationIdTooltip => moduleDef.GenerationId.IsNil ? null : metadataFile.Metadata.GetGuid(moduleDef.GenerationId).ToString();
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int BaseGenerationId => MetadataTokens.GetHeapOffset(moduleDef.BaseGenerationId); public int BaseGenerationId => MetadataTokens.GetHeapOffset(moduleDef.BaseGenerationId);
public string BaseGenerationIdTooltip => moduleDef.BaseGenerationId.IsNil ? null : metadata.GetGuid(moduleDef.BaseGenerationId).ToString(); public string BaseGenerationIdTooltip => moduleDef.BaseGenerationId.IsNil ? null : metadataFile.Metadata.GetGuid(moduleDef.BaseGenerationId).ToString();
public ModuleEntry(PEFile module, ModuleDefinitionHandle handle) public ModuleEntry(MetadataFile metadataFile, ModuleDefinitionHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.moduleDef = metadata.GetModuleDefinition(); this.moduleDef = metadataFile.Metadata.GetModuleDefinition();
} }
} }

39
ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class NestedClassTableTreeNode : MetadataTableTreeNode class NestedClassTableTreeNode : MetadataTableTreeNode
{ {
public NestedClassTableTreeNode(PEFile module) public NestedClassTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x29, module) : base((HandleKind)0x29, metadataFile)
{ {
} }
public override object Text => $"29 NestedClass ({module.Metadata.GetTableRowCount(TableIndex.NestedClass)})"; public override object Text => $"29 NestedClass ({metadataFile.Metadata.GetTableRowCount(TableIndex.NestedClass)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,17 +41,16 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<NestedClassEntry>(); var list = new List<NestedClassEntry>();
NestedClassEntry scrollTargetEntry = default; NestedClassEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.NestedClass); var length = metadata.GetTableRowCount(TableIndex.NestedClass);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
NestedClassEntry entry = new NestedClassEntry(module, ptr, metadataOffset, rid); NestedClassEntry entry = new NestedClassEntry(metadataFile, ptr, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -89,8 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct NestedClassEntry struct NestedClassEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly NestedClass nestedClass; readonly NestedClass nestedClass;
public int RID { get; } public int RID { get; }
@ -104,32 +98,31 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnNestedClassClick() public void OnNestedClassClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, nestedClass.Nested, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, nestedClass.Nested, protocol: "metadata"));
} }
string nestedClassTooltip; string nestedClassTooltip;
public string NestedClassTooltip => GenerateTooltip(ref nestedClassTooltip, module, nestedClass.Nested); public string NestedClassTooltip => GenerateTooltip(ref nestedClassTooltip, metadataFile, nestedClass.Nested);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int EnclosingClass => MetadataTokens.GetToken(nestedClass.Enclosing); public int EnclosingClass => MetadataTokens.GetToken(nestedClass.Enclosing);
public void OnEnclosingClassClick() public void OnEnclosingClassClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, nestedClass.Enclosing, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, nestedClass.Enclosing, protocol: "metadata"));
} }
string enclosingClassTooltip; string enclosingClassTooltip;
public string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, module, nestedClass.Enclosing); public string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, metadataFile, nestedClass.Enclosing);
public NestedClassEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public NestedClassEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.NestedClass) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.NestedClass)
+ metadata.GetTableRowSize(TableIndex.NestedClass) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.NestedClass) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; int typeDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
this.nestedClass = new NestedClass(ptr.Slice(rowOffset), typeDefSize); this.nestedClass = new NestedClass(ptr.Slice(rowOffset), typeDefSize);
this.nestedClassTooltip = null; this.nestedClassTooltip = null;
this.enclosingClassTooltip = null; this.enclosingClassTooltip = null;

32
ILSpy/Metadata/CorTables/ParamTableTreeNode.cs

@ -28,14 +28,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ParamTableTreeNode : MetadataTableTreeNode internal class ParamTableTreeNode : MetadataTableTreeNode
{ {
public ParamTableTreeNode(PEFile module) public ParamTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.Parameter, module) : base(HandleKind.Parameter, metadataFile)
{ {
} }
public override object Text => $"08 Param ({module.Metadata.GetTableRowCount(TableIndex.Param)})"; public override object Text => $"08 Param ({metadataFile.Metadata.GetTableRowCount(TableIndex.Param)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -47,9 +45,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<ParamEntry>(); var list = new List<ParamEntry>();
ParamEntry scrollTargetEntry = default; ParamEntry scrollTargetEntry = default;
for (int row = 1; row <= module.Metadata.GetTableRowCount(TableIndex.Param); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.Param); row++)
{ {
ParamEntry entry = new ParamEntry(module, MetadataTokens.ParameterHandle(row)); ParamEntry entry = new ParamEntry(metadataFile, MetadataTokens.ParameterHandle(row));
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -71,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct ParamEntry struct ParamEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly ParameterHandle handle; readonly ParameterHandle handle;
readonly Parameter param; readonly Parameter param;
@ -81,9 +77,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.Param) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Param)
+ metadata.GetTableRowSize(TableIndex.Param) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.Param) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public ParameterAttributes Attributes => param.Attributes; public ParameterAttributes Attributes => param.Attributes;
@ -92,19 +88,17 @@ namespace ICSharpCode.ILSpy.Metadata
FlagGroup.CreateMultipleChoiceGroup(typeof(ParameterAttributes), selectedValue: (int)param.Attributes, includeAll: false) FlagGroup.CreateMultipleChoiceGroup(typeof(ParameterAttributes), selectedValue: (int)param.Attributes, includeAll: false)
}; };
public string Name => metadata.GetString(param.Name); public string Name => metadataFile.Metadata.GetString(param.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(param.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(param.Name):X} \"{Name}\"";
public int Sequence => param.SequenceNumber; public int Sequence => param.SequenceNumber;
public ParamEntry(PEFile module, ParameterHandle handle) public ParamEntry(MetadataFile metadataFile, ParameterHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.param = metadata.GetParameter(handle); this.param = metadataFile.Metadata.GetParameter(handle);
} }
} }

41
ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs

@ -22,22 +22,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class PropertyMapTableTreeNode : MetadataTableTreeNode class PropertyMapTableTreeNode : MetadataTableTreeNode
{ {
public PropertyMapTableTreeNode(PEFile module) public PropertyMapTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x15, module) : base((HandleKind)0x15, metadataFile)
{ {
} }
public override object Text => $"15 PropertyMap ({module.Metadata.GetTableRowCount(TableIndex.PropertyMap)})"; public override object Text => $"15 PropertyMap ({metadataFile.Metadata.GetTableRowCount(TableIndex.PropertyMap)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -45,17 +41,16 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<PropertyMapEntry>(); var list = new List<PropertyMapEntry>();
PropertyMapEntry scrollTargetEntry = default; PropertyMapEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.PropertyMap); var length = metadata.GetTableRowCount(TableIndex.PropertyMap);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
PropertyMapEntry entry = new PropertyMapEntry(module, ptr, metadataOffset, rid); PropertyMapEntry entry = new PropertyMapEntry(metadataFile, ptr, rid);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -89,8 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct PropertyMapEntry struct PropertyMapEntry
{ {
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly PropertyMap propertyMap; readonly PropertyMap propertyMap;
public int RID { get; } public int RID { get; }
@ -104,33 +98,32 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, propertyMap.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, propertyMap.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, propertyMap.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, propertyMap.Parent);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int PropertyList => MetadataTokens.GetToken(propertyMap.PropertyList); public int PropertyList => MetadataTokens.GetToken(propertyMap.PropertyList);
public void OnPropertyListClick() public void OnPropertyListClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, propertyMap.PropertyList, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, propertyMap.PropertyList, protocol: "metadata"));
} }
string propertyListTooltip; string propertyListTooltip;
public string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, module, propertyMap.PropertyList); public string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, metadataFile, propertyMap.PropertyList);
public PropertyMapEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row) public PropertyMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.PropertyMap) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.PropertyMap)
+ metadata.GetTableRowSize(TableIndex.PropertyMap) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.PropertyMap) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; int typeDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
int propertyDefSize = metadata.GetTableRowCount(TableIndex.Property) < ushort.MaxValue ? 2 : 4; int propertyDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.Property) < ushort.MaxValue ? 2 : 4;
this.propertyMap = new PropertyMap(ptr.Slice(rowOffset), typeDefSize, propertyDefSize); this.propertyMap = new PropertyMap(ptr.Slice(rowOffset), typeDefSize, propertyDefSize);
this.propertyListTooltip = null; this.propertyListTooltip = null;
this.parentTooltip = null; this.parentTooltip = null;

38
ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs

@ -22,8 +22,6 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
@ -32,14 +30,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class PropertyTableTreeNode : MetadataTableTreeNode internal class PropertyTableTreeNode : MetadataTableTreeNode
{ {
public PropertyTableTreeNode(PEFile module) public PropertyTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.PropertyDefinition, module) : base(HandleKind.PropertyDefinition, metadataFile)
{ {
} }
public override object Text => $"17 Property ({module.Metadata.GetTableRowCount(TableIndex.Property)})"; public override object Text => $"17 Property ({metadataFile.Metadata.GetTableRowCount(TableIndex.Property)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -47,14 +43,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<PropertyDefEntry>(); var list = new List<PropertyDefEntry>();
PropertyDefEntry scrollTargetEntry = default; PropertyDefEntry scrollTargetEntry = default;
foreach (var row in metadata.PropertyDefinitions) foreach (var row in metadata.PropertyDefinitions)
{ {
PropertyDefEntry entry = new PropertyDefEntry(module, row); PropertyDefEntry entry = new PropertyDefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -76,9 +72,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct PropertyDefEntry : IMemberTreeNode struct PropertyDefEntry : IMemberTreeNode
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly PropertyDefinitionHandle handle; readonly PropertyDefinitionHandle handle;
readonly PropertyDefinition propertyDef; readonly PropertyDefinition propertyDef;
@ -86,9 +80,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.Property) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Property)
+ metadata.GetTableRowSize(TableIndex.Property) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.Property) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public PropertyAttributes Attributes => propertyDef.Attributes; public PropertyAttributes Attributes => propertyDef.Attributes;
@ -97,25 +91,23 @@ namespace ICSharpCode.ILSpy.Metadata
FlagGroup.CreateMultipleChoiceGroup(typeof(PropertyAttributes), selectedValue: (int)propertyDef.Attributes, includeAll: false), FlagGroup.CreateMultipleChoiceGroup(typeof(PropertyAttributes), selectedValue: (int)propertyDef.Attributes, includeAll: false),
}; };
public string Name => metadata.GetString(propertyDef.Name); public string Name => metadataFile.Metadata.GetString(propertyDef.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(propertyDef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(propertyDef.Name):X} \"{Name}\"";
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(propertyDef.Signature); public int Signature => MetadataTokens.GetHeapOffset(propertyDef.Signature);
string signatureTooltip; string signatureTooltip;
public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);
public PropertyDefEntry(PEFile module, PropertyDefinitionHandle handle) public PropertyDefEntry(MetadataFile metadataFile, PropertyDefinitionHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.propertyDef = metadata.GetPropertyDefinition(handle); this.propertyDef = metadataFile.Metadata.GetPropertyDefinition(handle);
this.signatureTooltip = null; this.signatureTooltip = null;
} }
} }

34
ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs

@ -21,22 +21,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class StandAloneSigTableTreeNode : MetadataTableTreeNode class StandAloneSigTableTreeNode : MetadataTableTreeNode
{ {
public StandAloneSigTableTreeNode(PEFile module) public StandAloneSigTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.StandaloneSignature, module) : base(HandleKind.StandaloneSignature, metadataFile)
{ {
} }
public override object Text => $"11 StandAloneSig ({module.Metadata.GetTableRowCount(TableIndex.StandAloneSig)})"; public override object Text => $"11 StandAloneSig ({metadataFile.Metadata.GetTableRowCount(TableIndex.StandAloneSig)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -48,9 +44,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<StandAloneSigEntry>(); var list = new List<StandAloneSigEntry>();
StandAloneSigEntry scrollTargetEntry = default; StandAloneSigEntry scrollTargetEntry = default;
for (int row = 1; row <= module.Metadata.GetTableRowCount(TableIndex.StandAloneSig); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.StandAloneSig); row++)
{ {
StandAloneSigEntry entry = new StandAloneSigEntry(module, MetadataTokens.StandaloneSignatureHandle(row)); StandAloneSigEntry entry = new StandAloneSigEntry(metadataFile, MetadataTokens.StandaloneSignatureHandle(row));
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -72,9 +68,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct StandAloneSigEntry struct StandAloneSigEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly StandaloneSignatureHandle handle; readonly StandaloneSignatureHandle handle;
readonly StandaloneSignature standaloneSig; readonly StandaloneSignature standaloneSig;
@ -82,23 +76,21 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.StandAloneSig) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.StandAloneSig)
+ metadata.GetTableRowSize(TableIndex.StandAloneSig) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.StandAloneSig) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(standaloneSig.Signature); public int Signature => MetadataTokens.GetHeapOffset(standaloneSig.Signature);
string signatureTooltip; string signatureTooltip;
public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);
public StandAloneSigEntry(PEFile module, StandaloneSignatureHandle handle) public StandAloneSigEntry(MetadataFile metadataFile, StandaloneSignatureHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.standaloneSig = metadata.GetStandaloneSignature(handle); this.standaloneSig = metadataFile.Metadata.GetStandaloneSignature(handle);
this.signatureTooltip = null; this.signatureTooltip = null;
} }
} }

55
ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs

@ -24,7 +24,6 @@ using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
@ -33,14 +32,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class TypeDefTableTreeNode : MetadataTableTreeNode internal class TypeDefTableTreeNode : MetadataTableTreeNode
{ {
public TypeDefTableTreeNode(PEFile module) public TypeDefTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.TypeDefinition, module) : base(HandleKind.TypeDefinition, metadataFile)
{ {
} }
public override object Text => $"02 TypeDef ({module.Metadata.GetTableRowCount(TableIndex.TypeDef)})"; public override object Text => $"02 TypeDef ({metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -48,14 +45,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<TypeDefEntry>(); var list = new List<TypeDefEntry>();
TypeDefEntry scrollTargetEntry = default; TypeDefEntry scrollTargetEntry = default;
foreach (var row in metadata.TypeDefinitions) foreach (var row in metadata.TypeDefinitions)
{ {
TypeDefEntry entry = new TypeDefEntry(module, row); TypeDefEntry entry = new TypeDefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -77,9 +74,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct TypeDefEntry : IMemberTreeNode struct TypeDefEntry : IMemberTreeNode
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly TypeDefinitionHandle handle; readonly TypeDefinitionHandle handle;
readonly TypeDefinition typeDef; readonly TypeDefinition typeDef;
@ -87,9 +82,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.TypeDef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.TypeDef)
+ metadata.GetTableRowSize(TableIndex.TypeDef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.TypeDef) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public TypeAttributes Attributes => typeDef.Attributes; public TypeAttributes Attributes => typeDef.Attributes;
@ -107,36 +102,36 @@ namespace ICSharpCode.ILSpy.Metadata
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(typeDef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(typeDef.Name):X} \"{Name}\"";
public string Name => metadata.GetString(typeDef.Name); public string Name => metadataFile.Metadata.GetString(typeDef.Name);
public string NamespaceTooltip => $"{MetadataTokens.GetHeapOffset(typeDef.Namespace):X} \"{Namespace}\""; public string NamespaceTooltip => $"{MetadataTokens.GetHeapOffset(typeDef.Namespace):X} \"{Namespace}\"";
public string Namespace => metadata.GetString(typeDef.Namespace); public string Namespace => metadataFile.Metadata.GetString(typeDef.Namespace);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int BaseType => MetadataTokens.GetToken(typeDef.BaseType); public int BaseType => MetadataTokens.GetToken(typeDef.BaseType);
public void OnBaseTypeClick() public void OnBaseTypeClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, typeDef.BaseType, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeDef.BaseType, protocol: "metadata"));
} }
public string BaseTypeTooltip { public string BaseTypeTooltip {
get { get {
var output = new PlainTextOutput(); var output = new PlainTextOutput();
var provider = new DisassemblerSignatureTypeProvider(module, output); var provider = new DisassemblerSignatureTypeProvider(metadataFile, output);
if (typeDef.BaseType.IsNil) if (typeDef.BaseType.IsNil)
return null; return null;
switch (typeDef.BaseType.Kind) switch (typeDef.BaseType.Kind)
{ {
case HandleKind.TypeDefinition: case HandleKind.TypeDefinition:
provider.GetTypeFromDefinition(module.Metadata, (TypeDefinitionHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature); provider.GetTypeFromDefinition(metadataFile.Metadata, (TypeDefinitionHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature);
return output.ToString(); return output.ToString();
case HandleKind.TypeReference: case HandleKind.TypeReference:
provider.GetTypeFromReference(module.Metadata, (TypeReferenceHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature); provider.GetTypeFromReference(metadataFile.Metadata, (TypeReferenceHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature);
return output.ToString(); return output.ToString();
case HandleKind.TypeSpecification: case HandleKind.TypeSpecification:
provider.GetTypeFromSpecification(module.Metadata, new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module), (TypeSpecificationHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature); provider.GetTypeFromSpecification(metadataFile.Metadata, new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), metadataFile.Metadata), (TypeSpecificationHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature);
return output.ToString(); return output.ToString();
default: default:
return null; return null;
@ -149,7 +144,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnFieldListClick() public void OnFieldListClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, typeDef.GetFields().FirstOrDefault(), protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeDef.GetFields().FirstOrDefault(), protocol: "metadata"));
} }
string fieldListTooltip; string fieldListTooltip;
@ -158,7 +153,7 @@ namespace ICSharpCode.ILSpy.Metadata
var field = typeDef.GetFields().FirstOrDefault(); var field = typeDef.GetFields().FirstOrDefault();
if (field.IsNil) if (field.IsNil)
return null; return null;
return GenerateTooltip(ref fieldListTooltip, module, field); return GenerateTooltip(ref fieldListTooltip, metadataFile, field);
} }
} }
@ -167,7 +162,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodListClick() public void OnMethodListClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, typeDef.GetMethods().FirstOrDefault(), protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeDef.GetMethods().FirstOrDefault(), protocol: "metadata"));
} }
string methodListTooltip; string methodListTooltip;
@ -176,19 +171,17 @@ namespace ICSharpCode.ILSpy.Metadata
var method = typeDef.GetMethods().FirstOrDefault(); var method = typeDef.GetMethods().FirstOrDefault();
if (method.IsNil) if (method.IsNil)
return null; return null;
return GenerateTooltip(ref methodListTooltip, module, method); return GenerateTooltip(ref methodListTooltip, metadataFile, method);
} }
} }
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle);
public TypeDefEntry(PEFile module, TypeDefinitionHandle handle) public TypeDefEntry(MetadataFile metadataFile, TypeDefinitionHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.typeDef = metadata.GetTypeDefinition(handle); this.typeDef = metadataFile.Metadata.GetTypeDefinition(handle);
this.methodListTooltip = null; this.methodListTooltip = null;
this.fieldListTooltip = null; this.fieldListTooltip = null;
} }

39
ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs

@ -21,21 +21,18 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class TypeRefTableTreeNode : MetadataTableTreeNode internal class TypeRefTableTreeNode : MetadataTableTreeNode
{ {
public TypeRefTableTreeNode(PEFile module) public TypeRefTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.TypeReference, module) : base(HandleKind.TypeReference, metadataFile)
{ {
} }
public override object Text => $"01 TypeRef ({module.Metadata.GetTableRowCount(TableIndex.TypeRef)})"; public override object Text => $"01 TypeRef ({metadataFile.Metadata.GetTableRowCount(TableIndex.TypeRef)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -43,14 +40,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<TypeRefEntry>(); var list = new List<TypeRefEntry>();
TypeRefEntry scrollTargetEntry = default; TypeRefEntry scrollTargetEntry = default;
foreach (var row in metadata.TypeReferences) foreach (var row in metadata.TypeReferences)
{ {
TypeRefEntry entry = new TypeRefEntry(module, row); TypeRefEntry entry = new TypeRefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget) if (entry.RID == this.scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -72,9 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct TypeRefEntry struct TypeRefEntry
{ {
readonly int metadataOffset; readonly MetadataFile metadataFile;
readonly PEFile module;
readonly MetadataReader metadata;
readonly TypeReferenceHandle handle; readonly TypeReferenceHandle handle;
readonly TypeReference typeRef; readonly TypeReference typeRef;
@ -82,36 +77,34 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public int Offset => metadataOffset public int Offset => metadataFile.MetadataOffset
+ metadata.GetTableMetadataOffset(TableIndex.TypeRef) + metadataFile.Metadata.GetTableMetadataOffset(TableIndex.TypeRef)
+ metadata.GetTableRowSize(TableIndex.TypeRef) * (RID - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.TypeRef) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int ResolutionScope => MetadataTokens.GetToken(typeRef.ResolutionScope); public int ResolutionScope => MetadataTokens.GetToken(typeRef.ResolutionScope);
public void OnResolutionScopeClick() public void OnResolutionScopeClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, typeRef.ResolutionScope, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, typeRef.ResolutionScope, protocol: "metadata"));
} }
string resolutionScopeTooltip; string resolutionScopeTooltip;
public string ResolutionScopeTooltip => GenerateTooltip(ref resolutionScopeTooltip, module, typeRef.ResolutionScope); public string ResolutionScopeTooltip => GenerateTooltip(ref resolutionScopeTooltip, metadataFile, typeRef.ResolutionScope);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(typeRef.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(typeRef.Name):X} \"{Name}\"";
public string Name => metadata.GetString(typeRef.Name); public string Name => metadataFile.Metadata.GetString(typeRef.Name);
public string NamespaceTooltip => $"{MetadataTokens.GetHeapOffset(typeRef.Namespace):X} \"{Namespace}\""; public string NamespaceTooltip => $"{MetadataTokens.GetHeapOffset(typeRef.Namespace):X} \"{Namespace}\"";
public string Namespace => metadata.GetString(typeRef.Namespace); public string Namespace => metadataFile.Metadata.GetString(typeRef.Namespace);
public TypeRefEntry(PEFile module, TypeReferenceHandle handle) public TypeRefEntry(MetadataFile metadataFile, TypeReferenceHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.metadataFile = metadataFile;
this.module = module;
this.metadata = module.Metadata;
this.handle = handle; this.handle = handle;
this.typeRef = metadata.GetTypeReference(handle); this.typeRef = metadataFile.Metadata.GetTypeReference(handle);
this.resolutionScopeTooltip = null; this.resolutionScopeTooltip = null;
} }
} }

22
ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs

@ -28,14 +28,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class TypeSpecTableTreeNode : MetadataTableTreeNode internal class TypeSpecTableTreeNode : MetadataTableTreeNode
{ {
public TypeSpecTableTreeNode(PEFile module) public TypeSpecTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.TypeSpecification, module) : base(HandleKind.TypeSpecification, metadataFile)
{ {
} }
public override object Text => $"1B TypeSpec ({module.Metadata.GetTableRowCount(TableIndex.TypeSpec)})"; public override object Text => $"1B TypeSpec ({metadataFile.Metadata.GetTableRowCount(TableIndex.TypeSpec)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -43,14 +41,14 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = module.Metadata; var metadata = metadataFile.Metadata;
var list = new List<TypeSpecEntry>(); var list = new List<TypeSpecEntry>();
TypeSpecEntry scrollTargetEntry = default; TypeSpecEntry scrollTargetEntry = default;
foreach (var row in metadata.GetTypeSpecifications()) foreach (var row in metadata.GetTypeSpecifications())
{ {
TypeSpecEntry entry = new TypeSpecEntry(module, row); TypeSpecEntry entry = new TypeSpecEntry(metadataFile, row);
if (scrollTarget.Equals(row)) if (scrollTarget.Equals(row))
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -73,7 +71,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct TypeSpecEntry struct TypeSpecEntry
{ {
readonly int metadataOffset; readonly int metadataOffset;
readonly PEFile module; readonly MetadataFile module;
readonly MetadataReader metadata; readonly MetadataReader metadata;
readonly TypeSpecificationHandle handle; readonly TypeSpecificationHandle handle;
readonly TypeSpecification typeSpec; readonly TypeSpecification typeSpec;
@ -97,11 +95,11 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public TypeSpecEntry(PEFile module, TypeSpecificationHandle handle) public TypeSpecEntry(MetadataFile metadataFile, TypeSpecificationHandle handle)
{ {
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; this.module = metadataFile;
this.module = module; this.metadataOffset = metadataFile.MetadataOffset;
this.metadata = module.Metadata; this.metadata = metadataFile.Metadata;
this.handle = handle; this.handle = handle;
this.typeSpec = metadata.GetTypeSpecification(handle); this.typeSpec = metadata.GetTypeSpecification(handle);
} }

6
ILSpy/Metadata/DataDirectoriesTreeNode.cs

@ -17,12 +17,9 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
@ -38,7 +35,8 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => "Data Directories"; public override object Text => "Data Directories";
public override object Icon => Images.Literal; public override object Icon => Images.ListFolder;
public override object ExpandedIcon => Images.ListFolderOpen;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {

3
ILSpy/Metadata/DebugDirectory/CodeViewTreeNode.cs

@ -21,7 +21,6 @@
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
@ -39,7 +38,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object ToolTip => "Associated PDB file description."; public override object ToolTip => "Associated PDB file description.";
public override object Icon => Images.Literal; public override object Icon => Images.MetadataTable;
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)
{ {

5
ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs

@ -23,7 +23,6 @@ using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
@ -39,9 +38,9 @@ namespace ICSharpCode.ILSpy.Metadata
this.entry = entry; this.entry = entry;
} }
override public object Text => $"{entry.Type}"; override public object Text => entry.Type.ToString();
public override object Icon => Images.Literal; public override object Icon => Images.MetadataTable;
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{ {

2
ILSpy/Metadata/DebugDirectory/PdbChecksumTreeNode.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.Metadata
+ "be present if multiple PDBs were produced during the build of the PE/COFF file\n" + "be present if multiple PDBs were produced during the build of the PE/COFF file\n"
+ "(for example, private and public symbols)."; + "(for example, private and public symbols).";
public override object Icon => Images.Literal; public override object Icon => Images.MetadataTable;
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)
{ {

13
ILSpy/Metadata/DebugDirectoryTreeNode.cs

@ -18,15 +18,11 @@
#nullable enable #nullable enable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
@ -43,7 +39,9 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => "Debug Directory"; public override object Text => "Debug Directory";
public override object Icon => Images.Literal; public override object Icon => Images.ListFolder;
public override object ExpandedIcon => Images.ListFolderOpen;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -78,8 +76,9 @@ namespace ICSharpCode.ILSpy.Metadata
break; break;
case DebugDirectoryEntryType.EmbeddedPortablePdb: case DebugDirectoryEntryType.EmbeddedPortablePdb:
var embeddedPortablePdbReader = module.Reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry).GetMetadataReader(); var embeddedPortablePdbProvider = module.Reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry);
this.Children.Add(new DebugMetadataTreeNode(module, isEmbedded: true, provider: embeddedPortablePdbReader)); var embeddedPortablePdbMetadataFile = new MetadataFile(module.FileName, embeddedPortablePdbProvider, isEmbedded: true);
this.Children.Add(new MetadataTreeNode(embeddedPortablePdbMetadataFile, "Debug Metadata (Embedded)"));
break; break;
case DebugDirectoryEntryType.PdbChecksum: case DebugDirectoryEntryType.PdbChecksum:

33
ILSpy/Metadata/DebugMetadataTablesTreeNode.cs

@ -16,13 +16,10 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
@ -30,42 +27,38 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
class DebugMetadataTablesTreeNode : ILSpyTreeNode class DebugMetadataTablesTreeNode : ILSpyTreeNode
{ {
private PEFile module; private MetadataFile metadataFile;
private bool isEmbedded;
private MetadataReader provider;
public DebugMetadataTablesTreeNode(PEFile module, bool isEmbedded, MetadataReader provider) public DebugMetadataTablesTreeNode(MetadataFile metadataFile)
{ {
this.module = module; this.metadataFile = metadataFile;
this.isEmbedded = isEmbedded;
this.provider = provider;
this.LazyLoading = true; this.LazyLoading = true;
} }
public override object Text => "Tables"; public override object Text => "Tables";
public override object Icon => Images.Literal; public override object Icon => Images.MetadataTableGroup;
protected override void LoadChildren() protected override void LoadChildren()
{ {
if (ShowTable(TableIndex.Document)) if (ShowTable(TableIndex.Document))
this.Children.Add(new DocumentTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new DocumentTableTreeNode(metadataFile));
if (ShowTable(TableIndex.MethodDebugInformation)) if (ShowTable(TableIndex.MethodDebugInformation))
this.Children.Add(new MethodDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new MethodDebugInformationTableTreeNode(metadataFile));
if (ShowTable(TableIndex.LocalScope)) if (ShowTable(TableIndex.LocalScope))
this.Children.Add(new LocalScopeTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new LocalScopeTableTreeNode(metadataFile));
if (ShowTable(TableIndex.LocalVariable)) if (ShowTable(TableIndex.LocalVariable))
this.Children.Add(new LocalVariableTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new LocalVariableTableTreeNode(metadataFile));
if (ShowTable(TableIndex.LocalConstant)) if (ShowTable(TableIndex.LocalConstant))
this.Children.Add(new LocalConstantTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new LocalConstantTableTreeNode(metadataFile));
if (ShowTable(TableIndex.ImportScope)) if (ShowTable(TableIndex.ImportScope))
this.Children.Add(new ImportScopeTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new ImportScopeTableTreeNode(metadataFile));
if (ShowTable(TableIndex.StateMachineMethod)) if (ShowTable(TableIndex.StateMachineMethod))
this.Children.Add(new StateMachineMethodTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new StateMachineMethodTableTreeNode(metadataFile));
if (ShowTable(TableIndex.CustomDebugInformation)) if (ShowTable(TableIndex.CustomDebugInformation))
this.Children.Add(new CustomDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); this.Children.Add(new CustomDebugInformationTableTreeNode(metadataFile));
bool ShowTable(TableIndex table) => !MainWindow.Instance.CurrentDisplaySettings.HideEmptyMetadataTables || this.provider.GetTableRowCount(table) > 0; bool ShowTable(TableIndex table) => !MainWindow.Instance.CurrentDisplaySettings.HideEmptyMetadataTables || metadataFile.Metadata.GetTableRowCount(table) > 0;
} }
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)

77
ILSpy/Metadata/DebugMetadataTreeNode.cs

@ -1,77 +0,0 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// 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.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata
{
class DebugMetadataTreeNode : ILSpyTreeNode
{
private PEFile module;
private MetadataReader provider;
private bool isEmbedded;
public DebugMetadataTreeNode(PEFile module, bool isEmbedded, MetadataReader provider)
{
this.module = module;
this.provider = provider;
this.isEmbedded = isEmbedded;
this.Text = "Debug Metadata (" + (isEmbedded ? "Embedded" : "From portable PDB") + ")";
this.LazyLoading = true;
}
public override object Text { get; }
public override object Icon => Images.Library;
public override bool View(TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
return false;
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, "Debug Metadata");
}
protected override void LoadChildren()
{
this.Children.Add(new DebugMetadataTablesTreeNode(module, this.isEmbedded, this.provider));
this.Children.Add(new StringHeapTreeNode(module, this.provider));
this.Children.Add(new UserStringHeapTreeNode(module, this.provider));
this.Children.Add(new GuidHeapTreeNode(module, this.provider));
this.Children.Add(new BlobHeapTreeNode(module, this.provider));
}
public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind)
{
return this.Children.OfType<MetadataTableTreeNode>().SingleOrDefault(x => x.Kind == kind);
}
}
}

46
ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs

@ -19,35 +19,25 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo; using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class CustomDebugInformationTableTreeNode : DebugMetadataTableTreeNode internal class CustomDebugInformationTableTreeNode : DebugMetadataTableTreeNode
{ {
private readonly bool isEmbedded; public CustomDebugInformationTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.CustomDebugInformation, metadataFile)
public CustomDebugInformationTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base(HandleKind.CustomDebugInformation, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"37 CustomDebugInformation ({metadata.GetTableRowCount(TableIndex.CustomDebugInformation)})"; public override object Text => $"37 CustomDebugInformation ({metadataFile.Metadata.GetTableRowCount(TableIndex.CustomDebugInformation)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -62,9 +52,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<CustomDebugInformationEntry>(); var list = new List<CustomDebugInformationEntry>();
CustomDebugInformationEntry scrollTargetEntry = default; CustomDebugInformationEntry scrollTargetEntry = default;
foreach (var row in metadata.CustomDebugInformation) foreach (var row in metadataFile.Metadata.CustomDebugInformation)
{ {
CustomDebugInformationEntry entry = new CustomDebugInformationEntry(module, metadata, isEmbedded, row); CustomDebugInformationEntry entry = new CustomDebugInformationEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -105,8 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata
class CustomDebugInformationEntry class CustomDebugInformationEntry
{ {
readonly int? offset; readonly int? offset;
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly CustomDebugInformationHandle handle; readonly CustomDebugInformationHandle handle;
readonly CustomDebugInformation debugInfo; readonly CustomDebugInformation debugInfo;
internal readonly CustomDebugInformationKind kind; internal readonly CustomDebugInformationKind kind;
@ -202,11 +191,11 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, debugInfo.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, debugInfo.Parent, protocol: "metadata"));
} }
string parentTooltip; string parentTooltip;
public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, debugInfo.Parent); public string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, debugInfo.Parent);
string kindString; string kindString;
public string Kind { public string Kind {
@ -217,7 +206,7 @@ namespace ICSharpCode.ILSpy.Metadata
Guid guid; Guid guid;
if (kind != CustomDebugInformationKind.None) if (kind != CustomDebugInformationKind.None)
{ {
guid = metadata.GetGuid(debugInfo.Kind); guid = metadataFile.Metadata.GetGuid(debugInfo.Kind);
} }
else else
{ {
@ -251,7 +240,7 @@ namespace ICSharpCode.ILSpy.Metadata
get { get {
if (debugInfo.Value.IsNil) if (debugInfo.Value.IsNil)
return "<nil>"; return "<nil>";
return metadata.GetBlobReader(debugInfo.Value).ToHexString(); return metadataFile.Metadata.GetBlobReader(debugInfo.Value).ToHexString();
} }
} }
@ -265,7 +254,7 @@ namespace ICSharpCode.ILSpy.Metadata
if (debugInfo.Value.IsNil) if (debugInfo.Value.IsNil)
return null; return null;
var reader = metadata.GetBlobReader(debugInfo.Value); var reader = metadataFile.Metadata.GetBlobReader(debugInfo.Value);
ArrayList list; ArrayList list;
switch (kind) switch (kind)
@ -324,15 +313,14 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public CustomDebugInformationEntry(PEFile module, MetadataReader metadata, bool isEmbedded, CustomDebugInformationHandle handle) public CustomDebugInformationEntry(MetadataFile metadataFile, CustomDebugInformationHandle handle)
{ {
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.CustomDebugInformation) this.metadataFile = metadataFile;
+ metadata.GetTableRowSize(TableIndex.CustomDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1); this.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.CustomDebugInformation)
this.module = module; + metadataFile.Metadata.GetTableRowSize(TableIndex.CustomDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1);
this.metadata = metadata;
this.handle = handle; this.handle = handle;
this.debugInfo = metadata.GetCustomDebugInformation(handle); this.debugInfo = metadataFile.Metadata.GetCustomDebugInformation(handle);
this.kind = GetKind(metadata, debugInfo.Kind); this.kind = GetKind(metadataFile.Metadata, debugInfo.Kind);
} }
} }

40
ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs

@ -18,7 +18,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
@ -30,17 +29,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class DocumentTableTreeNode : DebugMetadataTableTreeNode internal class DocumentTableTreeNode : DebugMetadataTableTreeNode
{ {
private readonly bool isEmbedded; public DocumentTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.Document, metadataFile)
public DocumentTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base(HandleKind.Document, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"30 Document ({metadata.GetTableRowCount(TableIndex.Document)})"; public override object Text => $"30 Document ({metadataFile.Metadata.GetTableRowCount(TableIndex.Document)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -51,9 +45,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<DocumentEntry>(); var list = new List<DocumentEntry>();
DocumentEntry scrollTargetEntry = default; DocumentEntry scrollTargetEntry = default;
foreach (var row in metadata.Documents) foreach (var row in metadataFile.Metadata.Documents)
{ {
DocumentEntry entry = new DocumentEntry(metadata, isEmbedded, row); DocumentEntry entry = new DocumentEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -73,10 +67,10 @@ namespace ICSharpCode.ILSpy.Metadata
return true; return true;
} }
struct DocumentEntry readonly struct DocumentEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataReader metadata; readonly MetadataFile metadataFile;
readonly DocumentHandle handle; readonly DocumentHandle handle;
readonly Document document; readonly Document document;
@ -84,9 +78,9 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public object Offset => offset == null ? "n/a" : (object)offset; public object Offset => offset == null ? "n/a" : offset;
public string Name => metadata.GetString(document.Name); public string Name => metadataFile.Metadata.GetString(document.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(document.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(document.Name):X} \"{Name}\"";
@ -97,7 +91,7 @@ namespace ICSharpCode.ILSpy.Metadata
get { get {
if (document.HashAlgorithm.IsNil) if (document.HashAlgorithm.IsNil)
return null; return null;
Guid guid = metadata.GetGuid(document.HashAlgorithm); Guid guid = metadataFile.Metadata.GetGuid(document.HashAlgorithm);
if (guid == KnownGuids.HashAlgorithmSHA1) if (guid == KnownGuids.HashAlgorithmSHA1)
return "SHA1 [ff1816ec-aa5e-4d10-87f7-6f4963833460]"; return "SHA1 [ff1816ec-aa5e-4d10-87f7-6f4963833460]";
if (guid == KnownGuids.HashAlgorithmSHA256) if (guid == KnownGuids.HashAlgorithmSHA256)
@ -113,7 +107,7 @@ namespace ICSharpCode.ILSpy.Metadata
get { get {
if (document.Hash.IsNil) if (document.Hash.IsNil)
return null; return null;
System.Collections.Immutable.ImmutableArray<byte> token = metadata.GetBlobContent(document.Hash); System.Collections.Immutable.ImmutableArray<byte> token = metadataFile.Metadata.GetBlobContent(document.Hash);
return token.ToHexString(token.Length); return token.ToHexString(token.Length);
} }
} }
@ -125,7 +119,7 @@ namespace ICSharpCode.ILSpy.Metadata
get { get {
if (document.Language.IsNil) if (document.Language.IsNil)
return null; return null;
Guid guid = metadata.GetGuid(document.Language); Guid guid = metadataFile.Metadata.GetGuid(document.Language);
if (guid == KnownGuids.CSharpLanguageGuid) if (guid == KnownGuids.CSharpLanguageGuid)
return "Visual C# [3f5162f8-07c6-11d3-9053-00c04fa302a1]"; return "Visual C# [3f5162f8-07c6-11d3-9053-00c04fa302a1]";
if (guid == KnownGuids.VBLanguageGuid) if (guid == KnownGuids.VBLanguageGuid)
@ -136,13 +130,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public DocumentEntry(MetadataReader metadata, bool isEmbedded, DocumentHandle handle) public DocumentEntry(MetadataFile metadataFile, DocumentHandle handle)
{ {
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.Document) this.metadataFile = metadataFile;
+ metadata.GetTableRowSize(TableIndex.Document) * (MetadataTokens.GetRowNumber(handle) - 1); this.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Document)
this.metadata = metadata; + metadataFile.Metadata.GetTableRowSize(TableIndex.Document) * (MetadataTokens.GetRowNumber(handle) - 1);
this.handle = handle; this.handle = handle;
this.document = metadata.GetDocument(handle); this.document = metadataFile.Metadata.GetDocument(handle);
} }
} }

41
ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs

@ -16,34 +16,23 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ImportScopeTableTreeNode : DebugMetadataTableTreeNode internal class ImportScopeTableTreeNode : DebugMetadataTableTreeNode
{ {
private readonly bool isEmbedded; public ImportScopeTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.ImportScope, metadataFile)
public ImportScopeTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base(HandleKind.ImportScope, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"35 ImportScope ({metadata.GetTableRowCount(TableIndex.ImportScope)})"; public override object Text => $"35 ImportScope ({metadataFile.Metadata.GetTableRowCount(TableIndex.ImportScope)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -54,9 +43,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<ImportScopeEntry>(); var list = new List<ImportScopeEntry>();
ImportScopeEntry scrollTargetEntry = default; ImportScopeEntry scrollTargetEntry = default;
foreach (var row in metadata.ImportScopes) foreach (var row in metadataFile.Metadata.ImportScopes)
{ {
ImportScopeEntry entry = new ImportScopeEntry(module, metadata, isEmbedded, row); ImportScopeEntry entry = new ImportScopeEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -76,11 +65,10 @@ namespace ICSharpCode.ILSpy.Metadata
return true; return true;
} }
struct ImportScopeEntry readonly struct ImportScopeEntry
{ {
readonly int? offset; readonly int? offset;
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly ImportScopeHandle handle; readonly ImportScopeHandle handle;
readonly ImportScope localScope; readonly ImportScope localScope;
@ -88,27 +76,26 @@ namespace ICSharpCode.ILSpy.Metadata
public int Token => MetadataTokens.GetToken(handle); public int Token => MetadataTokens.GetToken(handle);
public object Offset => offset == null ? "n/a" : (object)offset; public object Offset => offset == null ? "n/a" : offset;
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Parent => MetadataTokens.GetToken(localScope.Parent); public int Parent => MetadataTokens.GetToken(localScope.Parent);
public void OnParentClick() public void OnParentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.Parent, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.Parent, protocol: "metadata"));
} }
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Imports => MetadataTokens.GetHeapOffset(localScope.ImportsBlob); public int Imports => MetadataTokens.GetHeapOffset(localScope.ImportsBlob);
public ImportScopeEntry(PEFile module, MetadataReader metadata, bool isEmbedded, ImportScopeHandle handle) public ImportScopeEntry(MetadataFile metadataFile, ImportScopeHandle handle)
{ {
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.ImportScope) this.metadataFile = metadataFile;
+ metadata.GetTableRowSize(TableIndex.ImportScope) * (MetadataTokens.GetRowNumber(handle) - 1);
this.module = module;
this.metadata = metadata;
this.handle = handle; this.handle = handle;
this.localScope = metadata.GetImportScope(handle); this.localScope = metadataFile.Metadata.GetImportScope(handle);
this.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ImportScope)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.ImportScope) * (MetadataTokens.GetRowNumber(handle) - 1);
} }
} }

35
ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs

@ -16,32 +16,23 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class LocalConstantTableTreeNode : DebugMetadataTableTreeNode internal class LocalConstantTableTreeNode : DebugMetadataTableTreeNode
{ {
private readonly bool isEmbedded; public LocalConstantTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.LocalConstant, metadataFile)
public LocalConstantTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base(HandleKind.LocalConstant, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"34 LocalConstant ({metadata.GetTableRowCount(TableIndex.LocalConstant)})"; public override object Text => $"34 LocalConstant ({metadataFile.Metadata.GetTableRowCount(TableIndex.LocalConstant)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -52,9 +43,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<LocalConstantEntry>(); var list = new List<LocalConstantEntry>();
LocalConstantEntry scrollTargetEntry = default; LocalConstantEntry scrollTargetEntry = default;
foreach (var row in metadata.LocalConstants) foreach (var row in metadataFile.Metadata.LocalConstants)
{ {
LocalConstantEntry entry = new LocalConstantEntry(module, metadata, isEmbedded, row); LocalConstantEntry entry = new LocalConstantEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -77,8 +68,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct LocalConstantEntry struct LocalConstantEntry
{ {
readonly int? offset; readonly int? offset;
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly LocalConstantHandle handle; readonly LocalConstantHandle handle;
readonly LocalConstant localConst; readonly LocalConstant localConst;
@ -88,21 +78,20 @@ namespace ICSharpCode.ILSpy.Metadata
public object Offset => offset == null ? "n/a" : (object)offset; public object Offset => offset == null ? "n/a" : (object)offset;
public string Name => metadata.GetString(localConst.Name); public string Name => metadataFile.Metadata.GetString(localConst.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(localConst.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(localConst.Name):X} \"{Name}\"";
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(localConst.Signature); public int Signature => MetadataTokens.GetHeapOffset(localConst.Signature);
public LocalConstantEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalConstantHandle handle) public LocalConstantEntry(MetadataFile metadataFile, LocalConstantHandle handle)
{ {
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.LocalConstant) this.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.LocalConstant)
+ metadata.GetTableRowSize(TableIndex.LocalConstant) * (MetadataTokens.GetRowNumber(handle) - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.LocalConstant) * (MetadataTokens.GetRowNumber(handle) - 1);
this.module = module; this.metadataFile = metadataFile;
this.metadata = metadata;
this.handle = handle; this.handle = handle;
this.localConst = metadata.GetLocalConstant(handle); this.localConst = metadataFile.Metadata.GetLocalConstant(handle);
} }
} }

44
ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs

@ -16,34 +16,24 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class LocalScopeTableTreeNode : DebugMetadataTableTreeNode internal class LocalScopeTableTreeNode : DebugMetadataTableTreeNode
{ {
private readonly bool isEmbedded; public LocalScopeTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.LocalScope, metadataFile)
public LocalScopeTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base(HandleKind.LocalScope, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"32 LocalScope ({metadata.GetTableRowCount(TableIndex.LocalScope)})"; public override object Text => $"32 LocalScope ({metadataFile.Metadata.GetTableRowCount(TableIndex.LocalScope)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -54,9 +44,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<LocalScopeEntry>(); var list = new List<LocalScopeEntry>();
LocalScopeEntry scrollTargetEntry = default; LocalScopeEntry scrollTargetEntry = default;
foreach (var row in metadata.LocalScopes) foreach (var row in metadataFile.Metadata.LocalScopes)
{ {
LocalScopeEntry entry = new LocalScopeEntry(module, metadata, isEmbedded, row); LocalScopeEntry entry = new LocalScopeEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -79,8 +69,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct LocalScopeEntry struct LocalScopeEntry
{ {
readonly int? offset; readonly int? offset;
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly LocalScopeHandle handle; readonly LocalScopeHandle handle;
readonly LocalScope localScope; readonly LocalScope localScope;
@ -95,18 +84,18 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMethodClick() public void OnMethodClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.Method, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.Method, protocol: "metadata"));
} }
string methodTooltip; string methodTooltip;
public string MethodTooltip => GenerateTooltip(ref methodTooltip, module, localScope.Method); public string MethodTooltip => GenerateTooltip(ref methodTooltip, metadataFile, localScope.Method);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int ImportScope => MetadataTokens.GetToken(localScope.ImportScope); public int ImportScope => MetadataTokens.GetToken(localScope.ImportScope);
public void OnImportScopeClick() public void OnImportScopeClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.ImportScope, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.ImportScope, protocol: "metadata"));
} }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -114,7 +103,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnVariableListClick() public void OnVariableListClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.GetLocalVariables().FirstOrDefault(), protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.GetLocalVariables().FirstOrDefault(), protocol: "metadata"));
} }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -122,21 +111,20 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnConstantListClick() public void OnConstantListClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.GetLocalConstants().FirstOrDefault(), protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, localScope.GetLocalConstants().FirstOrDefault(), protocol: "metadata"));
} }
public int StartOffset => localScope.StartOffset; public int StartOffset => localScope.StartOffset;
public int Length => localScope.Length; public int Length => localScope.Length;
public LocalScopeEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalScopeHandle handle) public LocalScopeEntry(MetadataFile metadataFile, LocalScopeHandle handle)
{ {
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.LocalScope) this.metadataFile = metadataFile;
+ metadata.GetTableRowSize(TableIndex.LocalScope) * (MetadataTokens.GetRowNumber(handle) - 1); this.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.LocalScope)
this.module = module; + metadataFile.Metadata.GetTableRowSize(TableIndex.LocalScope) * (MetadataTokens.GetRowNumber(handle) - 1);
this.metadata = metadata;
this.handle = handle; this.handle = handle;
this.localScope = metadata.GetLocalScope(handle); this.localScope = metadataFile.Metadata.GetLocalScope(handle);
this.methodTooltip = null; this.methodTooltip = null;
} }
} }

31
ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs

@ -27,17 +27,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class LocalVariableTableTreeNode : DebugMetadataTableTreeNode internal class LocalVariableTableTreeNode : DebugMetadataTableTreeNode
{ {
private readonly bool isEmbedded; public LocalVariableTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.LocalVariable, metadataFile)
public LocalVariableTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base(HandleKind.LocalVariable, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"33 LocalVariable ({metadata.GetTableRowCount(TableIndex.LocalVariable)})"; public override object Text => $"33 LocalVariable ({metadataFile.Metadata.GetTableRowCount(TableIndex.LocalVariable)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -48,9 +43,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<LocalVariableEntry>(); var list = new List<LocalVariableEntry>();
LocalVariableEntry scrollTargetEntry = default; LocalVariableEntry scrollTargetEntry = default;
foreach (var row in metadata.LocalVariables) foreach (var row in metadataFile.Metadata.LocalVariables)
{ {
LocalVariableEntry entry = new LocalVariableEntry(module, metadata, isEmbedded, row); LocalVariableEntry entry = new LocalVariableEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -73,8 +68,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct LocalVariableEntry struct LocalVariableEntry
{ {
readonly int? offset; readonly int? offset;
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly LocalVariableHandle handle; readonly LocalVariableHandle handle;
readonly LocalVariable localVar; readonly LocalVariable localVar;
@ -93,18 +87,17 @@ namespace ICSharpCode.ILSpy.Metadata
public int Index => localVar.Index; public int Index => localVar.Index;
public string Name => metadata.GetString(localVar.Name); public string Name => metadataFile.Metadata.GetString(localVar.Name);
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(localVar.Name):X} \"{Name}\""; public string NameTooltip => $"{MetadataTokens.GetHeapOffset(localVar.Name):X} \"{Name}\"";
public LocalVariableEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalVariableHandle handle) public LocalVariableEntry(MetadataFile metadataFile, LocalVariableHandle handle)
{ {
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.LocalVariable) this.metadataFile = metadataFile;
+ metadata.GetTableRowSize(TableIndex.LocalVariable) * (MetadataTokens.GetRowNumber(handle) - 1); this.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.LocalVariable)
this.module = module; + metadataFile.Metadata.GetTableRowSize(TableIndex.LocalVariable) * (MetadataTokens.GetRowNumber(handle) - 1);
this.metadata = metadata;
this.handle = handle; this.handle = handle;
this.localVar = metadata.GetLocalVariable(handle); this.localVar = metadataFile.Metadata.GetLocalVariable(handle);
} }
} }

45
ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs

@ -16,9 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text; using System.Text;
@ -31,17 +29,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodDebugInformationTableTreeNode : DebugMetadataTableTreeNode internal class MethodDebugInformationTableTreeNode : DebugMetadataTableTreeNode
{ {
private readonly bool isEmbedded; public MethodDebugInformationTableTreeNode(MetadataFile metadataFile)
: base(HandleKind.MethodDebugInformation, metadataFile)
public MethodDebugInformationTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base(HandleKind.MethodDebugInformation, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"31 MethodDebugInformation ({metadata.GetTableRowCount(TableIndex.MethodDebugInformation)})"; public override object Text => $"31 MethodDebugInformation ({metadataFile.Metadata.GetTableRowCount(TableIndex.MethodDebugInformation)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -52,9 +45,9 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<MethodDebugInformationEntry>(); var list = new List<MethodDebugInformationEntry>();
MethodDebugInformationEntry scrollTargetEntry = default; MethodDebugInformationEntry scrollTargetEntry = default;
foreach (var row in metadata.MethodDebugInformation) foreach (var row in metadataFile.Metadata.MethodDebugInformation)
{ {
MethodDebugInformationEntry entry = new MethodDebugInformationEntry(module, metadata, isEmbedded, row); MethodDebugInformationEntry entry = new MethodDebugInformationEntry(metadataFile, row);
if (entry.RID == scrollTarget) if (entry.RID == scrollTarget)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -77,8 +70,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct MethodDebugInformationEntry struct MethodDebugInformationEntry
{ {
readonly int? offset; readonly int? offset;
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly MethodDebugInformationHandle handle; readonly MethodDebugInformationHandle handle;
readonly MethodDebugInformation debugInfo; readonly MethodDebugInformation debugInfo;
@ -93,15 +85,15 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnDocumentClick() public void OnDocumentClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, debugInfo.Document, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, debugInfo.Document, protocol: "metadata"));
} }
public string DocumentTooltip { public string DocumentTooltip {
get { get {
if (debugInfo.Document.IsNil) if (debugInfo.Document.IsNil)
return null; return null;
var document = metadata.GetDocument(debugInfo.Document); var document = metadataFile.Metadata.GetDocument(debugInfo.Document);
return $"{MetadataTokens.GetHeapOffset(document.Name):X} \"{metadata.GetString(document.Name)}\""; return $"{MetadataTokens.GetHeapOffset(document.Name):X} \"{metadataFile.Metadata.GetString(document.Name)}\"";
} }
} }
@ -126,7 +118,7 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnLocalSignatureClick() public void OnLocalSignatureClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, debugInfo.LocalSignature, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, debugInfo.LocalSignature, protocol: "metadata"));
} }
public string LocalSignatureTooltip { public string LocalSignatureTooltip {
@ -134,9 +126,9 @@ namespace ICSharpCode.ILSpy.Metadata
if (debugInfo.LocalSignature.IsNil) if (debugInfo.LocalSignature.IsNil)
return null; return null;
ITextOutput output = new PlainTextOutput(); ITextOutput output = new PlainTextOutput();
var context = new MetadataGenericContext(default(TypeDefinitionHandle), metadata); var context = new MetadataGenericContext(default(TypeDefinitionHandle), metadataFile.Metadata);
StandaloneSignature localSignature = module.Metadata.GetStandaloneSignature(debugInfo.LocalSignature); StandaloneSignature localSignature = metadataFile.Metadata.GetStandaloneSignature(debugInfo.LocalSignature);
var signatureDecoder = new DisassemblerSignatureTypeProvider(module, output); var signatureDecoder = new DisassemblerSignatureTypeProvider(metadataFile, output);
int index = 0; int index = 0;
foreach (var item in localSignature.DecodeLocalSignature(signatureDecoder, context)) foreach (var item in localSignature.DecodeLocalSignature(signatureDecoder, context))
{ {
@ -150,14 +142,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
public MethodDebugInformationEntry(PEFile module, MetadataReader metadata, bool isEmbedded, MethodDebugInformationHandle handle) public MethodDebugInformationEntry(MetadataFile metadataFile, MethodDebugInformationHandle handle)
{ {
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.MethodDebugInformation) this.metadataFile = metadataFile;
+ metadata.GetTableRowSize(TableIndex.MethodDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1); this.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDebugInformation)
this.module = module; + metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1);
this.metadata = metadata;
this.handle = handle; this.handle = handle;
this.debugInfo = metadata.GetMethodDebugInformation(handle); this.debugInfo = metadataFile.Metadata.GetMethodDebugInformation(handle);
} }
} }

48
ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs

@ -16,33 +16,23 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class StateMachineMethodTableTreeNode : DebugMetadataTableTreeNode internal class StateMachineMethodTableTreeNode : DebugMetadataTableTreeNode
{ {
readonly bool isEmbedded; public StateMachineMethodTableTreeNode(MetadataFile metadataFile)
: base((HandleKind)0x36, metadataFile)
public StateMachineMethodTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded)
: base((HandleKind)0x36, module, metadata)
{ {
this.isEmbedded = isEmbedded;
} }
public override object Text => $"36 StateMachineMethod ({metadata.GetTableRowCount(TableIndex.StateMachineMethod)})"; public override object Text => $"36 StateMachineMethod ({metadataFile.Metadata.GetTableRowCount(TableIndex.StateMachineMethod)})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
@ -52,13 +42,13 @@ namespace ICSharpCode.ILSpy.Metadata
var view = Helpers.PrepareDataGrid(tabPage, this); var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<StateMachineMethodEntry>(); var list = new List<StateMachineMethodEntry>();
StateMachineMethodEntry scrollTargetEntry = default; StateMachineMethodEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.StateMachineMethod); var length = metadataFile.Metadata.GetTableRowCount(TableIndex.StateMachineMethod);
var reader = metadata.AsBlobReader(); var reader = metadataFile.Metadata.AsBlobReader();
reader.Offset = metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod); reader.Offset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod);
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
StateMachineMethodEntry entry = new StateMachineMethodEntry(module, ref reader, isEmbedded, rid); StateMachineMethodEntry entry = new StateMachineMethodEntry(metadataFile, ref reader, rid);
if (scrollTarget == rid) if (scrollTarget == rid)
{ {
scrollTargetEntry = entry; scrollTargetEntry = entry;
@ -81,8 +71,7 @@ namespace ICSharpCode.ILSpy.Metadata
struct StateMachineMethodEntry struct StateMachineMethodEntry
{ {
readonly int? offset; readonly int? offset;
readonly PEFile module; readonly MetadataFile metadataFile;
readonly MetadataReader metadata;
readonly MethodDefinitionHandle moveNextMethod; readonly MethodDefinitionHandle moveNextMethod;
readonly MethodDefinitionHandle kickoffMethod; readonly MethodDefinitionHandle kickoffMethod;
@ -97,33 +86,32 @@ namespace ICSharpCode.ILSpy.Metadata
public void OnMoveNextMethodClick() public void OnMoveNextMethodClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, moveNextMethod, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, moveNextMethod, protocol: "metadata"));
} }
string moveNextMethodTooltip; string moveNextMethodTooltip;
public string MoveNextMethodTooltip => GenerateTooltip(ref moveNextMethodTooltip, module, moveNextMethod); public string MoveNextMethodTooltip => GenerateTooltip(ref moveNextMethodTooltip, metadataFile, moveNextMethod);
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int KickoffMethod => MetadataTokens.GetToken(kickoffMethod); public int KickoffMethod => MetadataTokens.GetToken(kickoffMethod);
public void OnKickofMethodClick() public void OnKickofMethodClick()
{ {
MainWindow.Instance.JumpToReference(new EntityReference(module, kickoffMethod, protocol: "metadata")); MainWindow.Instance.JumpToReference(new EntityReference(metadataFile, kickoffMethod, protocol: "metadata"));
} }
string kickoffMethodTooltip; string kickoffMethodTooltip;
public string KickoffMethodTooltip => GenerateTooltip(ref kickoffMethodTooltip, module, kickoffMethod); public string KickoffMethodTooltip => GenerateTooltip(ref kickoffMethodTooltip, metadataFile, kickoffMethod);
public StateMachineMethodEntry(PEFile module, ref BlobReader reader, bool isEmbedded, int row) public StateMachineMethodEntry(MetadataFile metadataFile, ref BlobReader reader, int row)
{ {
this.module = module; this.metadataFile = metadataFile;
this.metadata = module.Metadata;
this.RID = row; this.RID = row;
int rowOffset = metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod) int rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod)
+ metadata.GetTableRowSize(TableIndex.StateMachineMethod) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.StateMachineMethod) * (row - 1);
this.offset = isEmbedded ? null : (int?)rowOffset; this.offset = metadataFile.IsEmbedded ? null : (int?)rowOffset;
int methodDefSize = metadata.GetTableRowCount(TableIndex.MethodDef) < ushort.MaxValue ? 2 : 4; int methodDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.MethodDef) < ushort.MaxValue ? 2 : 4;
this.moveNextMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32()); this.moveNextMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32());
this.kickoffMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32()); this.kickoffMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32());
this.kickoffMethodTooltip = null; this.kickoffMethodTooltip = null;

4
ILSpy/Metadata/DosHeaderTreeNode.cs

@ -17,8 +17,6 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
@ -38,7 +36,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => "DOS Header"; public override object Text => "DOS Header";
public override object Icon => Images.Literal; public override object Icon => Images.Header;
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)
{ {

17
ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs

@ -16,21 +16,11 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
@ -39,11 +29,12 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
readonly List<BlobHeapEntry> list; readonly List<BlobHeapEntry> list;
public BlobHeapTreeNode(PEFile module, MetadataReader metadata) public BlobHeapTreeNode(MetadataFile metadataFile)
: base(HandleKind.Blob, module, metadata) : base(HandleKind.Blob, metadataFile)
{ {
list = new List<BlobHeapEntry>(); list = new List<BlobHeapEntry>();
var metadata = metadataFile.Metadata;
BlobHandle handle = MetadataTokens.BlobHandle(0); BlobHandle handle = MetadataTokens.BlobHandle(0);
do do
{ {
@ -55,8 +46,6 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => $"Blob Heap ({list.Count})"; public override object Text => $"Blob Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
tabPage.Title = Text.ToString(); tabPage.Title = Text.ToString();

8
ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs

@ -16,7 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
@ -30,10 +29,11 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
readonly List<GuidHeapEntry> list; readonly List<GuidHeapEntry> list;
public GuidHeapTreeNode(PEFile module, MetadataReader metadata) public GuidHeapTreeNode(MetadataFile metadataFile)
: base(HandleKind.Guid, module, metadata) : base(HandleKind.Guid, metadataFile)
{ {
list = new List<GuidHeapEntry>(); list = new List<GuidHeapEntry>();
var metadata = metadataFile.Metadata;
int count = metadata.GetHeapSize(HeapIndex.Guid) >> 4; int count = metadata.GetHeapSize(HeapIndex.Guid) >> 4;
for (int i = 1; i <= count; i++) for (int i = 1; i <= count; i++)
{ {
@ -44,8 +44,6 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => $"Guid Heap ({list.Count})"; public override object Text => $"Guid Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
tabPage.Title = Text.ToString(); tabPage.Title = Text.ToString();

17
ILSpy/Metadata/Heaps/StringHeapTreeNode.cs

@ -16,21 +16,11 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
@ -39,10 +29,11 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
readonly List<StringHeapEntry> list; readonly List<StringHeapEntry> list;
public StringHeapTreeNode(PEFile module, MetadataReader metadata) public StringHeapTreeNode(MetadataFile metadataFile)
: base(HandleKind.String, module, metadata) : base(HandleKind.String, metadataFile)
{ {
list = new List<StringHeapEntry>(); list = new List<StringHeapEntry>();
var metadata = metadataFile.Metadata;
StringHandle handle = MetadataTokens.StringHandle(0); StringHandle handle = MetadataTokens.StringHandle(0);
do do
{ {
@ -54,8 +45,6 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => $"String Heap ({list.Count})"; public override object Text => $"String Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
tabPage.Title = Text.ToString(); tabPage.Title = Text.ToString();

18
ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs

@ -16,21 +16,11 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
@ -39,11 +29,11 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
readonly List<UserStringHeapEntry> list; readonly List<UserStringHeapEntry> list;
public UserStringHeapTreeNode(PEFile module, MetadataReader metadata) public UserStringHeapTreeNode(MetadataFile metadataFile)
: base(HandleKind.UserString, module, metadata) : base(HandleKind.UserString, metadataFile)
{ {
list = new List<UserStringHeapEntry>(); list = new List<UserStringHeapEntry>();
var metadata = metadataFile.Metadata;
UserStringHandle handle = MetadataTokens.UserStringHandle(0); UserStringHandle handle = MetadataTokens.UserStringHandle(0);
do do
{ {
@ -55,8 +45,6 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => $"UserString Heap ({list.Count})"; public override object Text => $"UserString Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {
tabPage.Title = Text.ToString(); tabPage.Title = Text.ToString();

22
ILSpy/Metadata/MetadataHeapTreeNode.cs

@ -16,44 +16,34 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Threading; using System.Windows.Threading;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal abstract class MetadataHeapTreeNode : ILSpyTreeNode internal abstract class MetadataHeapTreeNode : ILSpyTreeNode
{ {
protected PEFile module; protected MetadataFile metadataFile;
protected MetadataReader metadata;
protected int scrollTarget; protected int scrollTarget;
public HandleKind Kind { get; } public HandleKind Kind { get; }
public MetadataHeapTreeNode(HandleKind kind, PEFile module, MetadataReader metadata) public override object Icon => Images.Heap;
{
this.module = module;
this.Kind = kind;
this.metadata = metadata;
}
internal void ScrollTo(Handle handle) public MetadataHeapTreeNode(HandleKind kind, MetadataFile metadataFile)
{ {
//this.scrollTarget = MetadataTokens.GetHeapOffset((EntityHandle)handle); this.Kind = kind;
this.metadataFile = metadataFile;
} }
protected void ScrollItemIntoView(DataGrid view, object item) protected void ScrollItemIntoView(DataGrid view, object item)
{ {
view.Loaded += View_Loaded; view.Loaded += View_Loaded;
view.Dispatcher.BeginInvoke((Action)(() => view.SelectItem(item)), DispatcherPriority.Background); view.Dispatcher.BeginInvoke(() => view.SelectItem(item), DispatcherPriority.Background);
} }
private void View_Loaded(object sender, System.Windows.RoutedEventArgs e) private void View_Loaded(object sender, System.Windows.RoutedEventArgs e)

25
ILSpy/Metadata/MetadataTableTreeNode.cs

@ -23,28 +23,30 @@ using System.Windows.Controls;
using System.Windows.Threading; using System.Windows.Threading;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal abstract class MetadataTableTreeNode : ILSpyTreeNode internal abstract class MetadataTableTreeNode : ILSpyTreeNode
{ {
protected PEFile module; protected readonly MetadataFile metadataFile;
protected int scrollTarget; protected int scrollTarget;
public HandleKind Kind { get; } public HandleKind Kind { get; }
public MetadataTableTreeNode(HandleKind kind, PEFile module) public override object Icon => Images.MetadataTable;
public MetadataTableTreeNode(HandleKind kind, MetadataFile metadataFile)
{ {
this.module = module;
this.Kind = kind; this.Kind = kind;
this.metadataFile = metadataFile;
} }
internal void ScrollTo(Handle handle) internal void ScrollTo(Handle handle)
{ {
this.scrollTarget = module.Metadata.GetRowNumber((EntityHandle)handle); this.scrollTarget = metadataFile.Metadata.GetRowNumber((EntityHandle)handle);
} }
protected void ScrollItemIntoView(DataGrid view, object item) protected void ScrollItemIntoView(DataGrid view, object item)
@ -62,7 +64,7 @@ namespace ICSharpCode.ILSpy.Metadata
this.scrollTarget = default; this.scrollTarget = default;
} }
protected static string GenerateTooltip(ref string tooltip, PEFile module, EntityHandle handle) protected static string GenerateTooltip(ref string tooltip, MetadataFile module, EntityHandle handle)
{ {
if (tooltip == null) if (tooltip == null)
{ {
@ -71,7 +73,7 @@ namespace ICSharpCode.ILSpy.Metadata
return null; return null;
} }
ITextOutput output = new PlainTextOutput(); ITextOutput output = new PlainTextOutput();
var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); var context = new MetadataGenericContext(default(TypeDefinitionHandle), module.Metadata);
var metadata = module.Metadata; var metadata = module.Metadata;
switch (handle.Kind) switch (handle.Kind)
{ {
@ -84,7 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata
output.Write(metadata.GetString(moduleReference.Name)); output.Write(metadata.GetString(moduleReference.Name));
break; break;
case HandleKind.AssemblyReference: case HandleKind.AssemblyReference:
var asmRef = new Decompiler.Metadata.AssemblyReference(module, (AssemblyReferenceHandle)handle); var asmRef = new Decompiler.Metadata.AssemblyReference(metadata, (AssemblyReferenceHandle)handle);
output.Write(asmRef.ToString()); output.Write(asmRef.ToString());
break; break;
case HandleKind.Parameter: case HandleKind.Parameter:
@ -132,12 +134,9 @@ namespace ICSharpCode.ILSpy.Metadata
internal abstract class DebugMetadataTableTreeNode : MetadataTableTreeNode internal abstract class DebugMetadataTableTreeNode : MetadataTableTreeNode
{ {
protected MetadataReader metadata; public DebugMetadataTableTreeNode(HandleKind kind, MetadataFile metadataFile)
: base(kind, metadataFile)
public DebugMetadataTableTreeNode(HandleKind kind, PEFile module, MetadataReader metadata)
: base(kind, module)
{ {
this.metadata = metadata;
} }
} }
} }

179
ILSpy/Metadata/MetadataTablesTreeNode.cs

@ -16,12 +16,12 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Collections.Generic; using System;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
@ -29,91 +29,120 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
class MetadataTablesTreeNode : ILSpyTreeNode class MetadataTablesTreeNode : ILSpyTreeNode
{ {
private PEFile module; readonly MetadataFile metadataFile;
public MetadataTablesTreeNode(PEFile module) public MetadataTablesTreeNode(MetadataFile metadataFile)
{ {
this.module = module; this.metadataFile = metadataFile;
this.LazyLoading = true; this.LazyLoading = true;
} }
public override object Text => "Tables"; public override object Text => "Tables";
public override object Icon => Images.Literal; public override object Icon => Images.MetadataTableGroup;
protected override void LoadChildren() protected override void LoadChildren()
{ {
if (ShowTable(TableIndex.Module)) foreach (var table in Enum.GetValues<TableIndex>())
this.Children.Add(new ModuleTableTreeNode(module)); {
if (ShowTable(TableIndex.TypeRef)) if (ShowTable(table, metadataFile.Metadata))
this.Children.Add(new TypeRefTableTreeNode(module)); this.Children.Add(CreateTableTreeNode(table, metadataFile));
if (ShowTable(TableIndex.TypeDef)) }
this.Children.Add(new TypeDefTableTreeNode(module)); }
if (ShowTable(TableIndex.Field))
this.Children.Add(new FieldTableTreeNode(module));
if (ShowTable(TableIndex.MethodDef))
this.Children.Add(new MethodTableTreeNode(module));
if (ShowTable(TableIndex.Param))
this.Children.Add(new ParamTableTreeNode(module));
if (ShowTable(TableIndex.InterfaceImpl))
this.Children.Add(new InterfaceImplTableTreeNode(module));
if (ShowTable(TableIndex.MemberRef))
this.Children.Add(new MemberRefTableTreeNode(module));
if (ShowTable(TableIndex.Constant))
this.Children.Add(new ConstantTableTreeNode(module));
if (ShowTable(TableIndex.CustomAttribute))
this.Children.Add(new CustomAttributeTableTreeNode(module));
if (ShowTable(TableIndex.FieldMarshal))
this.Children.Add(new FieldMarshalTableTreeNode(module));
if (ShowTable(TableIndex.DeclSecurity))
this.Children.Add(new DeclSecurityTableTreeNode(module));
if (ShowTable(TableIndex.ClassLayout))
this.Children.Add(new ClassLayoutTableTreeNode(module));
if (ShowTable(TableIndex.FieldLayout))
this.Children.Add(new FieldLayoutTableTreeNode(module));
if (ShowTable(TableIndex.StandAloneSig))
this.Children.Add(new StandAloneSigTableTreeNode(module));
if (ShowTable(TableIndex.EventMap))
this.Children.Add(new EventMapTableTreeNode(module));
if (ShowTable(TableIndex.Event))
this.Children.Add(new EventTableTreeNode(module));
if (ShowTable(TableIndex.PropertyMap))
this.Children.Add(new PropertyMapTableTreeNode(module));
if (ShowTable(TableIndex.Property))
this.Children.Add(new PropertyTableTreeNode(module));
if (ShowTable(TableIndex.MethodSemantics))
this.Children.Add(new MethodSemanticsTableTreeNode(module));
if (ShowTable(TableIndex.MethodImpl))
this.Children.Add(new MethodImplTableTreeNode(module));
if (ShowTable(TableIndex.ModuleRef))
this.Children.Add(new ModuleRefTableTreeNode(module));
if (ShowTable(TableIndex.TypeSpec))
this.Children.Add(new TypeSpecTableTreeNode(module));
if (ShowTable(TableIndex.ImplMap))
this.Children.Add(new ImplMapTableTreeNode(module));
if (ShowTable(TableIndex.FieldRva))
this.Children.Add(new FieldRVATableTreeNode(module));
if (ShowTable(TableIndex.Assembly))
this.Children.Add(new AssemblyTableTreeNode(module));
if (ShowTable(TableIndex.AssemblyRef))
this.Children.Add(new AssemblyRefTableTreeNode(module));
if (ShowTable(TableIndex.File))
this.Children.Add(new FileTableTreeNode(module));
if (ShowTable(TableIndex.ExportedType))
this.Children.Add(new ExportedTypeTableTreeNode(module));
if (ShowTable(TableIndex.ManifestResource))
this.Children.Add(new ManifestResourceTableTreeNode(module));
if (ShowTable(TableIndex.NestedClass))
this.Children.Add(new NestedClassTableTreeNode(module));
if (ShowTable(TableIndex.GenericParam))
this.Children.Add(new GenericParamTableTreeNode(module));
if (ShowTable(TableIndex.MethodSpec))
this.Children.Add(new MethodSpecTableTreeNode(module));
if (ShowTable(TableIndex.GenericParamConstraint))
this.Children.Add(new GenericParamConstraintTableTreeNode(module));
bool ShowTable(TableIndex table) => !MainWindow.Instance.CurrentDisplaySettings.HideEmptyMetadataTables || module.Metadata.GetTableRowCount(table) > 0; internal static bool ShowTable(TableIndex table, MetadataReader metadata) => !MainWindow.Instance.CurrentDisplaySettings.HideEmptyMetadataTables || metadata.GetTableRowCount(table) > 0;
internal static MetadataTableTreeNode CreateTableTreeNode(TableIndex table, MetadataFile metadataFile)
{
switch (table)
{
case TableIndex.Module:
return new ModuleTableTreeNode(metadataFile);
case TableIndex.TypeRef:
return new TypeRefTableTreeNode(metadataFile);
case TableIndex.TypeDef:
return new TypeDefTableTreeNode(metadataFile);
case TableIndex.Field:
return new FieldTableTreeNode(metadataFile);
case TableIndex.MethodDef:
return new MethodTableTreeNode(metadataFile);
case TableIndex.Param:
return new ParamTableTreeNode(metadataFile);
case TableIndex.InterfaceImpl:
return new InterfaceImplTableTreeNode(metadataFile);
case TableIndex.MemberRef:
return new MemberRefTableTreeNode(metadataFile);
case TableIndex.Constant:
return new ConstantTableTreeNode(metadataFile);
case TableIndex.CustomAttribute:
return new CustomAttributeTableTreeNode(metadataFile);
case TableIndex.FieldMarshal:
return new FieldMarshalTableTreeNode(metadataFile);
case TableIndex.DeclSecurity:
return new DeclSecurityTableTreeNode(metadataFile);
case TableIndex.ClassLayout:
return new ClassLayoutTableTreeNode(metadataFile);
case TableIndex.FieldLayout:
return new FieldLayoutTableTreeNode(metadataFile);
case TableIndex.StandAloneSig:
return new StandAloneSigTableTreeNode(metadataFile);
case TableIndex.EventMap:
return new EventMapTableTreeNode(metadataFile);
case TableIndex.Event:
return new EventTableTreeNode(metadataFile);
case TableIndex.PropertyMap:
return new PropertyMapTableTreeNode(metadataFile);
case TableIndex.Property:
return new PropertyTableTreeNode(metadataFile);
case TableIndex.MethodSemantics:
return new MethodSemanticsTableTreeNode(metadataFile);
case TableIndex.MethodImpl:
return new MethodImplTableTreeNode(metadataFile);
case TableIndex.ModuleRef:
return new ModuleRefTableTreeNode(metadataFile);
case TableIndex.TypeSpec:
return new TypeSpecTableTreeNode(metadataFile);
case TableIndex.ImplMap:
return new ImplMapTableTreeNode(metadataFile);
case TableIndex.FieldRva:
return new FieldRVATableTreeNode(metadataFile);
case TableIndex.Assembly:
return new AssemblyTableTreeNode(metadataFile);
case TableIndex.AssemblyRef:
return new AssemblyRefTableTreeNode(metadataFile);
case TableIndex.File:
return new FileTableTreeNode(metadataFile);
case TableIndex.ExportedType:
return new ExportedTypeTableTreeNode(metadataFile);
case TableIndex.ManifestResource:
return new ManifestResourceTableTreeNode(metadataFile);
case TableIndex.NestedClass:
return new NestedClassTableTreeNode(metadataFile);
case TableIndex.GenericParam:
return new GenericParamTableTreeNode(metadataFile);
case TableIndex.MethodSpec:
return new MethodSpecTableTreeNode(metadataFile);
case TableIndex.GenericParamConstraint:
return new GenericParamConstraintTableTreeNode(metadataFile);
case TableIndex.Document:
return new DocumentTableTreeNode(metadataFile);
case TableIndex.MethodDebugInformation:
return new MethodDebugInformationTableTreeNode(metadataFile);
case TableIndex.LocalScope:
return new LocalScopeTableTreeNode(metadataFile);
case TableIndex.LocalVariable:
return new LocalVariableTableTreeNode(metadataFile);
case TableIndex.LocalConstant:
return new LocalConstantTableTreeNode(metadataFile);
case TableIndex.ImportScope:
return new ImportScopeTableTreeNode(metadataFile);
case TableIndex.StateMachineMethod:
return new StateMachineMethodTableTreeNode(metadataFile);
case TableIndex.CustomDebugInformation:
return new CustomDebugInformationTableTreeNode(metadataFile);
default:
throw new ArgumentException($"Unsupported table index: {table}");
}
} }
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)

69
ILSpy/Metadata/MetadataTreeNode.cs

@ -21,11 +21,11 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Windows.Data; using System.Windows.Data;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
@ -33,19 +33,19 @@ namespace ICSharpCode.ILSpy.Metadata
{ {
class MetadataTreeNode : ILSpyTreeNode class MetadataTreeNode : ILSpyTreeNode
{ {
private readonly PEFile module; private readonly MetadataFile metadataFile;
private AssemblyTreeNode assemblyTreeNode; private readonly string title;
public MetadataTreeNode(PEFile module, AssemblyTreeNode assemblyTreeNode) public MetadataTreeNode(MetadataFile module, string title)
{ {
this.module = module; this.metadataFile = module;
this.assemblyTreeNode = assemblyTreeNode; this.title = title;
this.LazyLoading = true; this.LazyLoading = true;
} }
public override object Text => Resources.Metadata; public override object Text => title;
public override object Icon => Images.Library; public override object Icon => Images.Metadata;
public override bool View(TabPageModel tabPage) public override bool View(TabPageModel tabPage)
{ {
@ -57,21 +57,52 @@ namespace ICSharpCode.ILSpy.Metadata
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{ {
language.WriteCommentLine(output, "Metadata"); language.WriteCommentLine(output, title);
DumpMetadataInfo(language, output, this.metadataFile.Metadata);
}
internal static void DumpMetadataInfo(Language language, ITextOutput output, MetadataReader metadata)
{
language.WriteCommentLine(output, "MetadataKind: " + metadata.MetadataKind);
language.WriteCommentLine(output, "MetadataVersion: " + metadata.MetadataVersion);
if (metadata.DebugMetadataHeader is { } header)
{
output.WriteLine();
language.WriteCommentLine(output, "Header:");
language.WriteCommentLine(output, "Id: " + header.Id.ToHexString(header.Id.Length));
language.WriteCommentLine(output, "EntryPoint: " + MetadataTokens.GetToken(header.EntryPoint).ToString("X8"));
}
output.WriteLine();
language.WriteCommentLine(output, "Tables:");
foreach (var table in Enum.GetValues<TableIndex>())
{
int count = metadata.GetTableRowCount(table);
if (count > 0)
{
language.WriteCommentLine(output, $"{(byte)table:X2} {table}: {count} rows");
}
}
} }
protected override void LoadChildren() protected override void LoadChildren()
{ {
this.Children.Add(new DosHeaderTreeNode(module)); if (metadataFile is PEFile module)
this.Children.Add(new CoffHeaderTreeNode(module)); {
this.Children.Add(new OptionalHeaderTreeNode(module)); this.Children.Add(new DosHeaderTreeNode(module));
this.Children.Add(new DataDirectoriesTreeNode(module)); this.Children.Add(new CoffHeaderTreeNode(module));
this.Children.Add(new DebugDirectoryTreeNode(module)); this.Children.Add(new OptionalHeaderTreeNode(module));
this.Children.Add(new MetadataTablesTreeNode(module)); this.Children.Add(new DataDirectoriesTreeNode(module));
this.Children.Add(new StringHeapTreeNode(module, module.Metadata)); this.Children.Add(new DebugDirectoryTreeNode(module));
this.Children.Add(new UserStringHeapTreeNode(module, module.Metadata)); }
this.Children.Add(new GuidHeapTreeNode(module, module.Metadata)); this.Children.Add(new MetadataTablesTreeNode(metadataFile));
this.Children.Add(new BlobHeapTreeNode(module, module.Metadata)); this.Children.Add(new StringHeapTreeNode(metadataFile));
this.Children.Add(new UserStringHeapTreeNode(metadataFile));
this.Children.Add(new GuidHeapTreeNode(metadataFile));
this.Children.Add(new BlobHeapTreeNode(metadataFile));
} }
public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind) public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind)

2
ILSpy/Metadata/OptionalHeaderTreeNode.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => "Optional Header"; public override object Text => "Optional Header";
public override object Icon => Images.Literal; public override object Icon => Images.Header;
public override bool View(ViewModels.TabPageModel tabPage) public override bool View(ViewModels.TabPageModel tabPage)
{ {

6
ILSpy/TextView/AvalonEditTextOutput.cs

@ -260,7 +260,7 @@ namespace ICSharpCode.ILSpy.TextView
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = opCode }); references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = opCode });
} }
public void WriteReference(PEFile module, Handle handle, string text, string protocol = "decompile", bool isDefinition = false) public void WriteReference(MetadataFile metadata, Handle handle, string text, string protocol = "decompile", bool isDefinition = false)
{ {
WriteIndent(); WriteIndent();
int start = this.TextLength; int start = this.TextLength;
@ -268,9 +268,9 @@ namespace ICSharpCode.ILSpy.TextView
int end = this.TextLength; int end = this.TextLength;
if (isDefinition) if (isDefinition)
{ {
this.DefinitionLookup.AddDefinition((module, handle), this.TextLength); this.DefinitionLookup.AddDefinition((metadata, handle), this.TextLength);
} }
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = new EntityReference(module, handle, protocol), IsDefinition = isDefinition }); references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = new EntityReference(metadata, handle, protocol), IsDefinition = isDefinition });
} }
public void WriteReference(IType type, string text, bool isDefinition = false) public void WriteReference(IType type, string text, bool isDefinition = false)

3
ILSpy/TextView/DecompilerTextView.cs

@ -51,6 +51,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.OutputVisitor; using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Documentation; using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AvalonEdit; using ICSharpCode.ILSpy.AvalonEdit;
using ICSharpCode.ILSpy.Options; using ICSharpCode.ILSpy.Options;
@ -410,7 +411,7 @@ namespace ICSharpCode.ILSpy.TextView
} }
else if (segment.Reference is EntityReference unresolvedEntity) else if (segment.Reference is EntityReference unresolvedEntity)
{ {
var module = unresolvedEntity.ResolveAssembly(MainWindow.Instance.CurrentAssemblyList); var module = unresolvedEntity.ResolveAssembly(MainWindow.Instance.CurrentAssemblyList) as PEFile;
if (module == null) if (module == null)
return null; return null;
var typeSystem = new DecompilerTypeSystem(module, var typeSystem = new DecompilerTypeSystem(module,

32
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -29,7 +29,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Options; using ICSharpCode.ILSpy.Metadata;
using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.ViewModels; using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX;
@ -98,7 +98,18 @@ namespace ICSharpCode.ILSpy.TreeNodes
_ => Images.Library, _ => Images.Library,
}; };
} }
return Images.Assembly; if (loadResult.MetadataFile != null)
{
return loadResult.MetadataFile.Kind switch {
MetadataFile.MetadataFileKind.PortableExecutable => Images.Assembly,
MetadataFile.MetadataFileKind.ProgramDebugDatabase => Images.ProgramDebugDatabase,
_ => Images.MetadataFile,
};
}
else
{
return Images.Assembly;
}
} }
else else
{ {
@ -194,6 +205,15 @@ namespace ICSharpCode.ILSpy.TreeNodes
var package = loadResult.Package; var package = loadResult.Package;
this.Children.AddRange(PackageFolderTreeNode.LoadChildrenForFolder(package.RootFolder)); this.Children.AddRange(PackageFolderTreeNode.LoadChildrenForFolder(package.RootFolder));
} }
else if (loadResult.MetadataFile != null)
{
var metadata = loadResult.MetadataFile;
this.Children.Add(new MetadataTablesTreeNode(metadata));
this.Children.Add(new StringHeapTreeNode(metadata));
this.Children.Add(new UserStringHeapTreeNode(metadata));
this.Children.Add(new GuidHeapTreeNode(metadata));
this.Children.Add(new BlobHeapTreeNode(metadata));
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -205,12 +225,12 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
typeSystem = LoadedAssembly.GetTypeSystemOrNull(); typeSystem = LoadedAssembly.GetTypeSystemOrNull();
var assembly = (MetadataModule)typeSystem.MainModule; var assembly = (MetadataModule)typeSystem.MainModule;
this.Children.Add(new Metadata.MetadataTreeNode(module, this)); this.Children.Add(new MetadataTreeNode(module, Resources.Metadata));
Decompiler.DebugInfo.IDebugInfoProvider debugInfo = LoadedAssembly.GetDebugInfoOrNull(); Decompiler.DebugInfo.IDebugInfoProvider debugInfo = LoadedAssembly.GetDebugInfoOrNull();
if (debugInfo is PortableDebugInfoProvider ppdb if (debugInfo is PortableDebugInfoProvider ppdb
&& ppdb.GetMetadataReader() is System.Reflection.Metadata.MetadataReader reader) && ppdb.GetMetadataReader() is System.Reflection.Metadata.MetadataReader reader)
{ {
this.Children.Add(new Metadata.DebugMetadataTreeNode(module, ppdb.IsEmbedded, reader)); this.Children.Add(new MetadataTreeNode(ppdb.ToMetadataFile(), $"Debug Metadata ({(ppdb.IsEmbedded ? "Embedded" : "From portable PDB")})"));
} }
this.Children.Add(new ReferenceFolderTreeNode(module, this)); this.Children.Add(new ReferenceFolderTreeNode(module, this));
if (module.Resources.Any()) if (module.Resources.Any())
@ -374,6 +394,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
output.WriteLine("// " + LoadedAssembly.FileName); output.WriteLine("// " + LoadedAssembly.FileName);
DecompilePackage(loadResult.Package, output); DecompilePackage(loadResult.Package, output);
} }
else if (loadResult.MetadataFile != null)
{
output.WriteLine("// " + LoadedAssembly.FileName);
}
else else
{ {
LoadedAssembly.GetPEFileOrNullAsync().GetAwaiter().GetResult(); LoadedAssembly.GetPEFileOrNullAsync().GetAwaiter().GetResult();

Loading…
Cancel
Save