Browse Source

Reduce code duplication in Metadata tables by introducing a LoadTable method.

pull/3544/head
Siegfried Pammer 4 months ago
parent
commit
ff247168ec
  1. 30
      ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs
  2. 18
      ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs
  3. 29
      ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs
  4. 35
      ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs
  5. 35
      ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs
  6. 35
      ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs
  7. 41
      ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs
  8. 35
      ILSpy/Metadata/CorTables/EventTableTreeNode.cs
  9. 33
      ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs
  10. 39
      ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs
  11. 41
      ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs
  12. 39
      ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs
  13. 35
      ILSpy/Metadata/CorTables/FieldTableTreeNode.cs
  14. 36
      ILSpy/Metadata/CorTables/FileTableTreeNode.cs
  15. 33
      ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs
  16. 31
      ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs
  17. 44
      ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs
  18. 38
      ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs
  19. 34
      ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs
  20. 35
      ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs
  21. 32
      ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs
  22. 32
      ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs
  23. 35
      ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs
  24. 34
      ILSpy/Metadata/CorTables/MethodTableTreeNode.cs
  25. 35
      ILSpy/Metadata/CorTables/ModuleRefTableTreeNode.cs
  26. 27
      ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs
  27. 44
      ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs
  28. 32
      ILSpy/Metadata/CorTables/ParamTableTreeNode.cs
  29. 42
      ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs
  30. 34
      ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs
  31. 33
      ILSpy/Metadata/CorTables/PtrTableTreeNode.cs
  32. 31
      ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs
  33. 35
      ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs
  34. 35
      ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs
  35. 35
      ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs
  36. 39
      ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs
  37. 30
      ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs
  38. 31
      ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs
  39. 29
      ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs
  40. 29
      ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs
  41. 29
      ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs
  42. 30
      ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs
  43. 31
      ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs
  44. 51
      ILSpy/Metadata/MetadataTableTreeNode.cs

30
ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs

@ -26,44 +26,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class AssemblyRefTableTreeNode : MetadataTableTreeNode internal class AssemblyRefTableTreeNode : MetadataTableTreeNode<AssemblyRefTableTreeNode.AssemblyRefEntry>
{ {
public AssemblyRefTableTreeNode(MetadataFile metadataFile) public AssemblyRefTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.AssemblyRef, metadataFile) : base(TableIndex.AssemblyRef, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<AssemblyRefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<AssemblyRefEntry>(); var list = new List<AssemblyRefEntry>();
AssemblyRefEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.AssemblyReferences) foreach (var row in metadataFile.Metadata.AssemblyReferences)
{ {
AssemblyRefEntry entry = new AssemblyRefEntry(metadataFile, row); list.Add(new AssemblyRefEntry(metadataFile, row));
if (scrollTarget == MetadataTokens.GetRowNumber(row))
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
struct AssemblyRefEntry internal struct AssemblyRefEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly AssemblyReferenceHandle handle; readonly AssemblyReferenceHandle handle;

18
ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs

@ -17,6 +17,7 @@
// 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;
@ -25,33 +26,26 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class AssemblyTableTreeNode : MetadataTableTreeNode internal class AssemblyTableTreeNode : MetadataTableTreeNode<AssemblyTableTreeNode.AssemblyEntry>
{ {
public AssemblyTableTreeNode(MetadataFile metadataFile) public AssemblyTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Assembly, metadataFile) : base(TableIndex.Assembly, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<AssemblyEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
if (metadataFile.Metadata.IsAssembly) if (metadataFile.Metadata.IsAssembly)
{ {
view.ItemsSource = new[] { new AssemblyEntry(metadataFile.Metadata, metadataFile.MetadataOffset) }; return [new AssemblyEntry(metadataFile.Metadata, metadataFile.MetadataOffset)];
} }
else else
{ {
view.ItemsSource = Array.Empty<AssemblyEntry>(); return [];
} }
tabPage.Content = view;
return true;
} }
readonly struct AssemblyEntry internal readonly struct AssemblyEntry
{ {
readonly int metadataOffset; readonly int metadataOffset;
readonly MetadataReader metadata; readonly MetadataReader metadata;

29
ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs

@ -26,45 +26,26 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class ClassLayoutTableTreeNode : MetadataTableTreeNode internal class ClassLayoutTableTreeNode : MetadataTableTreeNode<ClassLayoutTableTreeNode.ClassLayoutEntry>
{ {
public ClassLayoutTableTreeNode(MetadataFile metadataFile) public ClassLayoutTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.ClassLayout, metadataFile) : base(TableIndex.ClassLayout, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ClassLayoutEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<ClassLayoutEntry>(); var list = new List<ClassLayoutEntry>();
var length = metadataFile.Metadata.GetTableRowCount(TableIndex.ClassLayout); var length = metadataFile.Metadata.GetTableRowCount(TableIndex.ClassLayout);
ReadOnlySpan<byte> ptr = metadataFile.Metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadataFile.Metadata.AsReadOnlySpan();
ClassLayoutEntry scrollTargetEntry = default;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
ClassLayoutEntry entry = new ClassLayoutEntry(metadataFile, ptr, rid); list.Add(new ClassLayoutEntry(metadataFile, ptr, rid));
if (scrollTarget == rid)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return true; return list;
} }
readonly struct ClassLayout readonly struct ClassLayout
@ -81,7 +62,7 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct ClassLayoutEntry internal struct ClassLayoutEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly ClassLayout classLayout; readonly ClassLayout classLayout;

35
ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs

@ -21,50 +21,27 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ConstantTableTreeNode : MetadataTableTreeNode internal class ConstantTableTreeNode : MetadataTableTreeNode<ConstantTableTreeNode.ConstantEntry>
{ {
public ConstantTableTreeNode(MetadataFile metadataFile) public ConstantTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Constant, metadataFile) : base(TableIndex.Constant, metadataFile)
{ {
} }
public override bool View(TabPageModel tabPage) protected override IReadOnlyList<ConstantEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<ConstantEntry>(); var list = new List<ConstantEntry>();
ConstantEntry scrollTargetEntry = default; for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.Constant); row++)
for (int row = 1; row <= metadata.GetTableRowCount(TableIndex.Constant); row++)
{ {
ConstantEntry entry = new ConstantEntry(metadataFile, MetadataTokens.ConstantHandle(row)); list.Add(new ConstantEntry(metadataFile, MetadataTokens.ConstantHandle(row)));
if (scrollTarget == row)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct ConstantEntry internal struct ConstantEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly EntityHandle handle; readonly EntityHandle handle;

35
ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs

@ -24,47 +24,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class CustomAttributeTableTreeNode : MetadataTableTreeNode class CustomAttributeTableTreeNode : MetadataTableTreeNode<CustomAttributeTableTreeNode.CustomAttributeEntry>
{ {
public CustomAttributeTableTreeNode(MetadataFile metadataFile) public CustomAttributeTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.CustomAttribute, metadataFile) : base(TableIndex.CustomAttribute, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<CustomAttributeEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<CustomAttributeEntry>(); var list = new List<CustomAttributeEntry>();
CustomAttributeEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.CustomAttributes)
foreach (var row in metadata.CustomAttributes)
{
CustomAttributeEntry entry = new CustomAttributeEntry(metadataFile, row);
if (scrollTarget == MetadataTokens.GetRowNumber(row))
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{ {
ScrollItemIntoView(view, scrollTargetEntry); list.Add(new CustomAttributeEntry(metadataFile, row));
} }
return list;
return true;
} }
struct CustomAttributeEntry internal struct CustomAttributeEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly CustomAttributeHandle handle; readonly CustomAttributeHandle handle;

35
ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs

@ -25,47 +25,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class DeclSecurityTableTreeNode : MetadataTableTreeNode class DeclSecurityTableTreeNode : MetadataTableTreeNode<DeclSecurityTableTreeNode.DeclSecurityEntry>
{ {
public DeclSecurityTableTreeNode(MetadataFile metadataFile) public DeclSecurityTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.DeclSecurity, metadataFile) : base(TableIndex.DeclSecurity, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<DeclSecurityEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<DeclSecurityEntry>(); var list = new List<DeclSecurityEntry>();
DeclSecurityEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.DeclarativeSecurityAttributes)
foreach (var row in metadata.DeclarativeSecurityAttributes)
{
var entry = new DeclSecurityEntry(metadataFile, row);
if (scrollTarget == MetadataTokens.GetRowNumber(row))
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{ {
ScrollItemIntoView(view, scrollTargetEntry); list.Add(new DeclSecurityEntry(metadataFile, row));
} }
return list;
return true;
} }
struct DeclSecurityEntry internal struct DeclSecurityEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly DeclarativeSecurityAttributeHandle handle; readonly DeclarativeSecurityAttributeHandle handle;

41
ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs

@ -25,46 +25,27 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class EventMapTableTreeNode : MetadataTableTreeNode class EventMapTableTreeNode : MetadataTableTreeNode<EventMapTableTreeNode.EventMapEntry>
{ {
public EventMapTableTreeNode(MetadataFile metadataFile) public EventMapTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.EventMap, metadataFile) : base(TableIndex.EventMap, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<EventMapEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<EventMapEntry>(); var list = new List<EventMapEntry>();
EventMapEntry scrollTargetEntry = default;
var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(TableIndex.EventMap); var length = metadata.GetTableRowCount(TableIndex.EventMap);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
int eventDefSize = metadata.GetTableRowCount(TableIndex.Event) < ushort.MaxValue ? 2 : 4;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
EventMapEntry entry = new EventMapEntry(metadataFile, ptr, rid); list.Add(new EventMapEntry(metadataFile, ptr, rid, typeDefSize, eventDefSize));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
readonly struct EventMap readonly struct EventMap
@ -79,15 +60,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct EventMapEntry internal struct EventMapEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly EventMap eventMap; readonly EventMap eventMap;
public int RID { get; } public int RID { get; }
public int Token => 0x12000000 | RID; public int Token => 0x12000000 | RID;
public int Offset { get; } public int Offset { get; }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -112,15 +91,13 @@ namespace ICSharpCode.ILSpy.Metadata
string eventListTooltip; string eventListTooltip;
public string EventListTooltip => GenerateTooltip(ref eventListTooltip, metadataFile, eventMap.EventList); public string EventListTooltip => GenerateTooltip(ref eventListTooltip, metadataFile, eventMap.EventList);
public EventMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row) public EventMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int typeDefSize, int eventDefSize)
{ {
this.metadataFile = metadataFile; this.metadataFile = metadataFile;
this.RID = row; this.RID = row;
var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.EventMap) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.EventMap)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.EventMap) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.EventMap) * (row - 1);
this.Offset = metadataFile.MetadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int typeDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < 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;

35
ILSpy/Metadata/CorTables/EventTableTreeNode.cs

@ -27,47 +27,24 @@ using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class EventTableTreeNode : MetadataTableTreeNode internal class EventTableTreeNode : MetadataTableTreeNode<EventTableTreeNode.EventDefEntry>
{ {
public EventTableTreeNode(MetadataFile metadataFile) public EventTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Event, metadataFile) : base(TableIndex.Event, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<EventDefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<EventDefEntry>(); var list = new List<EventDefEntry>();
EventDefEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.EventDefinitions)
foreach (var row in metadata.EventDefinitions)
{
EventDefEntry entry = new EventDefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{ {
ScrollItemIntoView(view, scrollTargetEntry); list.Add(new EventDefEntry(metadataFile, row));
} }
return list;
return true;
} }
struct EventDefEntry : IMemberTreeNode internal struct EventDefEntry : IMemberTreeNode
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly EventDefinitionHandle handle; readonly EventDefinitionHandle handle;

33
ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs

@ -25,46 +25,25 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ExportedTypeTableTreeNode : MetadataTableTreeNode internal class ExportedTypeTableTreeNode : MetadataTableTreeNode<ExportedTypeTableTreeNode.ExportedTypeEntry>
{ {
public ExportedTypeTableTreeNode(MetadataFile metadataFile) public ExportedTypeTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.ExportedType, metadataFile) : base(TableIndex.ExportedType, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ExportedTypeEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<ExportedTypeEntry>(); var list = new List<ExportedTypeEntry>();
ExportedTypeEntry scrollTargetEntry = default; var metadata = metadataFile.Metadata;
foreach (var row in metadata.ExportedTypes) foreach (var row in metadata.ExportedTypes)
{ {
ExportedTypeEntry entry = new ExportedTypeEntry(metadataFile, row, metadataFile.Metadata.GetExportedType(row)); list.Add(new ExportedTypeEntry(metadataFile, row, metadata.GetExportedType(row)));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
struct ExportedTypeEntry internal struct ExportedTypeEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly ExportedTypeHandle handle; readonly ExportedTypeHandle handle;

39
ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs

@ -26,46 +26,26 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldLayoutTableTreeNode : MetadataTableTreeNode internal class FieldLayoutTableTreeNode : MetadataTableTreeNode<FieldLayoutTableTreeNode.FieldLayoutEntry>
{ {
public FieldLayoutTableTreeNode(MetadataFile metadataFile) public FieldLayoutTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.FieldLayout, metadataFile) : base(TableIndex.FieldLayout, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<FieldLayoutEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<FieldLayoutEntry>(); var list = new List<FieldLayoutEntry>();
FieldLayoutEntry scrollTargetEntry = default;
var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(TableIndex.FieldLayout); var length = metadata.GetTableRowCount(TableIndex.FieldLayout);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
FieldLayoutEntry entry = new FieldLayoutEntry(metadataFile, ptr, rid); list.Add(new FieldLayoutEntry(metadataFile, ptr, rid, fieldDefSize));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
readonly struct FieldLayout readonly struct FieldLayout
@ -80,15 +60,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct FieldLayoutEntry internal struct FieldLayoutEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly FieldLayout fieldLayout; readonly FieldLayout fieldLayout;
public int RID { get; } public int RID { get; }
public int Token => 0x10000000 | RID; public int Token => 0x10000000 | RID;
public int Offset { get; } public int Offset { get; }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -105,14 +83,13 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public int FieldOffset => fieldLayout.Offset; public int FieldOffset => fieldLayout.Offset;
public FieldLayoutEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row) public FieldLayoutEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int fieldDefSize)
{ {
this.metadataFile = metadataFile; this.metadataFile = metadataFile;
this.RID = row; this.RID = row;
var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldLayout) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldLayout)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.FieldLayout) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.FieldLayout) * (row - 1);
this.Offset = metadataFile.MetadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
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;
} }

41
ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs

@ -25,46 +25,27 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldMarshalTableTreeNode : MetadataTableTreeNode internal class FieldMarshalTableTreeNode : MetadataTableTreeNode<FieldMarshalTableTreeNode.FieldMarshalEntry>
{ {
public FieldMarshalTableTreeNode(MetadataFile metadataFile) public FieldMarshalTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.FieldMarshal, metadataFile) : base(TableIndex.FieldMarshal, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<FieldMarshalEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<FieldMarshalEntry>(); var list = new List<FieldMarshalEntry>();
FieldMarshalEntry scrollTargetEntry = default;
var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(TableIndex.FieldMarshal); var length = metadata.GetTableRowCount(TableIndex.FieldMarshal);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int hasFieldMarshalRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param);
int blobHeapSize = metadata.GetHeapSize(HeapIndex.Blob) < ushort.MaxValue ? 2 : 4;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
FieldMarshalEntry entry = new FieldMarshalEntry(metadataFile, ptr, rid); list.Add(new FieldMarshalEntry(metadataFile, ptr, rid, blobHeapSize, hasFieldMarshalRefSize));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
readonly struct FieldMarshal readonly struct FieldMarshal
@ -79,15 +60,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct FieldMarshalEntry internal struct FieldMarshalEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly FieldMarshal fieldMarshal; readonly FieldMarshal fieldMarshal;
public int RID { get; } public int RID { get; }
public int Token => 0x0D000000 | RID; public int Token => 0x0D000000 | RID;
public int Offset { get; } public int Offset { get; }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -104,15 +83,13 @@ namespace ICSharpCode.ILSpy.Metadata
[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(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row) public FieldMarshalEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int blobHeapSize, int hasFieldMarshalRefSize)
{ {
this.metadataFile = metadataFile; this.metadataFile = metadataFile;
this.RID = row; this.RID = row;
var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldMarshal) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldMarshal)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.FieldMarshal) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.FieldMarshal) * (row - 1);
this.Offset = metadataFile.MetadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int hasFieldMarshalRefSize = metadataFile.Metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param);
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;
} }

39
ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs

@ -26,7 +26,7 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldRVATableTreeNode : MetadataTableTreeNode internal class FieldRVATableTreeNode : MetadataTableTreeNode<FieldRVATableTreeNode.FieldRVAEntry>
{ {
public FieldRVATableTreeNode(MetadataFile metadataFile) public FieldRVATableTreeNode(MetadataFile metadataFile)
: base(TableIndex.FieldRva, metadataFile) : base(TableIndex.FieldRva, metadataFile)
@ -35,40 +35,20 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => $"1D FieldRVA ({metadataFile.Metadata.GetTableRowCount(TableIndex.FieldRva)})"; public override object Text => $"1D FieldRVA ({metadataFile.Metadata.GetTableRowCount(TableIndex.FieldRva)})";
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<FieldRVAEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<FieldRVAEntry>(); var list = new List<FieldRVAEntry>();
FieldRVAEntry scrollTargetEntry = default;
var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(TableIndex.FieldRva); var length = metadata.GetTableRowCount(TableIndex.FieldRva);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = metadataFile.MetadataOffset; int metadataOffset = metadataFile.MetadataOffset;
int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
FieldRVAEntry entry = new FieldRVAEntry(metadataFile, metadataOffset, ptr, rid); list.Add(new FieldRVAEntry(metadataFile, metadataOffset, ptr, rid, fieldDefSize));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
readonly struct FieldRVA readonly struct FieldRVA
@ -83,15 +63,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct FieldRVAEntry internal struct FieldRVAEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly FieldRVA fieldRVA; readonly FieldRVA fieldRVA;
public int RID { get; } public int RID { get; }
public int Token => 0x1D000000 | RID; public int Token => 0x1D000000 | RID;
public int Offset { get; } public int Offset { get; }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -108,14 +86,13 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public int FieldOffset => fieldRVA.Offset; public int FieldOffset => fieldRVA.Offset;
public FieldRVAEntry(MetadataFile metadataFile, int metadataOffset, ReadOnlySpan<byte> ptr, int row) public FieldRVAEntry(MetadataFile metadataFile, int metadataOffset, ReadOnlySpan<byte> ptr, int row, int fieldDefSize)
{ {
this.metadataFile = metadataFile; this.metadataFile = metadataFile;
this.RID = row; this.RID = row;
var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldRva) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldRva)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1);
this.Offset = metadataOffset + rowOffset; this.Offset = metadataOffset + rowOffset;
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;
} }

35
ILSpy/Metadata/CorTables/FieldTableTreeNode.cs

@ -27,47 +27,24 @@ using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class FieldTableTreeNode : MetadataTableTreeNode internal class FieldTableTreeNode : MetadataTableTreeNode<FieldTableTreeNode.FieldDefEntry>
{ {
public FieldTableTreeNode(MetadataFile metadataFile) public FieldTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Field, metadataFile) : base(TableIndex.Field, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<FieldDefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<FieldDefEntry>(); var list = new List<FieldDefEntry>();
foreach (var row in metadataFile.Metadata.FieldDefinitions)
FieldDefEntry scrollTargetEntry = default;
foreach (var row in metadata.FieldDefinitions)
{ {
var entry = new FieldDefEntry(metadataFile, row); list.Add(new FieldDefEntry(metadataFile, row));
if (scrollTarget == entry.RID)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct FieldDefEntry : IMemberTreeNode internal struct FieldDefEntry : IMemberTreeNode
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly FieldDefinitionHandle handle; readonly FieldDefinitionHandle handle;

36
ILSpy/Metadata/CorTables/FileTableTreeNode.cs

@ -24,47 +24,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class FileTableTreeNode : MetadataTableTreeNode class FileTableTreeNode : MetadataTableTreeNode<FileTableTreeNode.FileEntry>
{ {
public FileTableTreeNode(MetadataFile metadataFile) public FileTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.File, metadataFile) : base(TableIndex.File, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<FileEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<FileEntry>(); var list = new List<FileEntry>();
FileEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.AssemblyFiles)
foreach (var row in metadata.AssemblyFiles)
{ {
FileEntry entry = new FileEntry(metadataFile, row); list.Add(new FileEntry(metadataFile, row));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct FileEntry internal struct FileEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly AssemblyFileHandle handle; readonly AssemblyFileHandle handle;
@ -106,6 +83,5 @@ namespace ICSharpCode.ILSpy.Metadata
this.assemblyFile = metadataFile.Metadata.GetAssemblyFile(handle); this.assemblyFile = metadataFile.Metadata.GetAssemblyFile(handle);
} }
} }
} }
} }

33
ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs

@ -26,46 +26,25 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class GenericParamConstraintTableTreeNode : MetadataTableTreeNode internal class GenericParamConstraintTableTreeNode : MetadataTableTreeNode<GenericParamConstraintTableTreeNode.GenericParamConstraintEntry>
{ {
public GenericParamConstraintTableTreeNode(MetadataFile metadataFile) public GenericParamConstraintTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.GenericParamConstraint, metadataFile) : base(TableIndex.GenericParamConstraint, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<GenericParamConstraintEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<GenericParamConstraintEntry>(); var list = new List<GenericParamConstraintEntry>();
GenericParamConstraintEntry scrollTargetEntry = default; var metadata = metadataFile.Metadata;
for (int row = 1; row <= metadata.GetTableRowCount(TableIndex.GenericParamConstraint); row++) for (int row = 1; row <= metadata.GetTableRowCount(TableIndex.GenericParamConstraint); row++)
{ {
GenericParamConstraintEntry entry = new GenericParamConstraintEntry(metadataFile, MetadataTokens.GenericParameterConstraintHandle(row)); list.Add(new GenericParamConstraintEntry(metadataFile, MetadataTokens.GenericParameterConstraintHandle(row)));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
view.ItemsSource = list; return list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct GenericParamConstraintEntry internal struct GenericParamConstraintEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly GenericParameterConstraintHandle handle; readonly GenericParameterConstraintHandle handle;

31
ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs

@ -25,45 +25,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class GenericParamTableTreeNode : MetadataTableTreeNode internal class GenericParamTableTreeNode : MetadataTableTreeNode<GenericParamTableTreeNode.GenericParamEntry>
{ {
public GenericParamTableTreeNode(MetadataFile metadataFile) public GenericParamTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.GenericParam, metadataFile) : base(TableIndex.GenericParam, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<GenericParamEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<GenericParamEntry>(); var list = new List<GenericParamEntry>();
GenericParamEntry scrollTargetEntry = default;
for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.GenericParam); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.GenericParam); row++)
{ {
GenericParamEntry entry = new GenericParamEntry(metadataFile, MetadataTokens.GenericParameterHandle(row)); list.Add(new GenericParamEntry(metadataFile, MetadataTokens.GenericParameterHandle(row)));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
struct GenericParamEntry internal struct GenericParamEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly GenericParameterHandle handle; readonly GenericParameterHandle handle;

44
ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs

@ -28,46 +28,27 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class ImplMapTableTreeNode : MetadataTableTreeNode class ImplMapTableTreeNode : MetadataTableTreeNode<ImplMapTableTreeNode.ImplMapEntry>
{ {
public ImplMapTableTreeNode(MetadataFile metadataFile) public ImplMapTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.ImplMap, metadataFile) : base(TableIndex.ImplMap, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ImplMapEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<ImplMapEntry>(); var list = new List<ImplMapEntry>();
ImplMapEntry scrollTargetEntry = default; var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(TableIndex.ImplMap); var length = metadata.GetTableRowCount(TableIndex.ImplMap);
var span = metadata.AsReadOnlySpan(); var span = metadata.AsReadOnlySpan();
int moduleRefSize = metadata.GetTableRowCount(TableIndex.ModuleRef) < ushort.MaxValue ? 2 : 4;
int memberForwardedTagRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field);
int stringHandleSize = metadata.GetHeapSize(HeapIndex.String) < ushort.MaxValue ? 2 : 4;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
ImplMapEntry entry = new ImplMapEntry(metadataFile, span, rid); list.Add(new ImplMapEntry(metadataFile, span, rid, moduleRefSize, memberForwardedTagRefSize, stringHandleSize));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
readonly struct ImplMap readonly struct ImplMap
@ -86,15 +67,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct ImplMapEntry internal struct ImplMapEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly ImplMap implMap; readonly ImplMap implMap;
public int RID { get; } public int RID { get; }
public int Token => 0x1C000000 | RID; public int Token => 0x1C000000 | RID;
public int Offset { get; } public int Offset { get; }
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
@ -134,16 +113,13 @@ namespace ICSharpCode.ILSpy.Metadata
public string ImportNameTooltip => $"{MetadataTokens.GetHeapOffset(implMap.ImportName):X} \"{ImportName}\""; public string ImportNameTooltip => $"{MetadataTokens.GetHeapOffset(implMap.ImportName):X} \"{ImportName}\"";
public ImplMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> span, int row) public ImplMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> span, int row, int moduleRefSize, int memberForwardedTagRefSize, int stringHandleSize)
{ {
this.metadataFile = metadataFile; this.metadataFile = metadataFile;
this.RID = row; this.RID = row;
var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ImplMap) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ImplMap)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.ImplMap) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.ImplMap) * (row - 1);
this.Offset = metadataFile.MetadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int moduleRefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.ModuleRef) < ushort.MaxValue ? 2 : 4;
int memberForwardedTagRefSize = metadataFile.Metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field);
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;

38
ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs

@ -25,47 +25,23 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class InterfaceImplTableTreeNode : MetadataTableTreeNode internal class InterfaceImplTableTreeNode : MetadataTableTreeNode<InterfaceImplTableTreeNode.InterfaceImplEntry>
{ {
public InterfaceImplTableTreeNode(MetadataFile metadataFile) public InterfaceImplTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.InterfaceImpl, metadataFile) : base(TableIndex.InterfaceImpl, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<InterfaceImplEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<InterfaceImplEntry>(); var list = new List<InterfaceImplEntry>();
InterfaceImplEntry scrollTargetEntry = default; var length = metadataFile.Metadata.GetTableRowCount(TableIndex.InterfaceImpl);
ReadOnlySpan<byte> ptr = metadataFile.Metadata.AsReadOnlySpan();
var length = metadata.GetTableRowCount(TableIndex.InterfaceImpl);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = metadataFile.MetadataOffset;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
InterfaceImplEntry entry = new InterfaceImplEntry(metadataFile, ptr, rid); list.Add(new InterfaceImplEntry(metadataFile, ptr, rid));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
readonly struct InterfaceImpl readonly struct InterfaceImpl
@ -80,7 +56,7 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct InterfaceImplEntry internal struct InterfaceImplEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly InterfaceImpl interfaceImpl; readonly InterfaceImpl interfaceImpl;

34
ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs

@ -25,47 +25,25 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class ManifestResourceTableTreeNode : MetadataTableTreeNode class ManifestResourceTableTreeNode : MetadataTableTreeNode<ManifestResourceTableTreeNode.ManifestResourceEntry>
{ {
public ManifestResourceTableTreeNode(MetadataFile metadataFile) public ManifestResourceTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.ManifestResource, metadataFile) : base(TableIndex.ManifestResource, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ManifestResourceEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<ManifestResourceEntry>(); var list = new List<ManifestResourceEntry>();
ManifestResourceEntry scrollTargetEntry = default; var metadata = metadataFile.Metadata;
foreach (var row in metadata.ManifestResources) foreach (var row in metadata.ManifestResources)
{ {
ManifestResourceEntry entry = new ManifestResourceEntry(metadataFile, row); list.Add(new ManifestResourceEntry(metadataFile, row));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct ManifestResourceEntry internal struct ManifestResourceEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly ManifestResourceHandle handle; readonly ManifestResourceHandle handle;

35
ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs

@ -24,47 +24,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MemberRefTableTreeNode : MetadataTableTreeNode internal class MemberRefTableTreeNode : MetadataTableTreeNode<MemberRefTableTreeNode.MemberRefEntry>
{ {
public MemberRefTableTreeNode(MetadataFile metadataFile) public MemberRefTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.MemberRef, metadataFile) : base(TableIndex.MemberRef, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<MemberRefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<MemberRefEntry>(); var list = new List<MemberRefEntry>();
MemberRefEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.MemberReferences)
foreach (var row in metadata.MemberReferences)
{ {
MemberRefEntry entry = new MemberRefEntry(metadataFile, row); list.Add(new MemberRefEntry(metadataFile, row));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct MemberRefEntry internal struct MemberRefEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly MemberReferenceHandle handle; readonly MemberReferenceHandle handle;

32
ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs

@ -24,46 +24,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodImplTableTreeNode : MetadataTableTreeNode internal class MethodImplTableTreeNode : MetadataTableTreeNode<MethodImplTableTreeNode.MethodImplEntry>
{ {
public MethodImplTableTreeNode(MetadataFile metadataFile) public MethodImplTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.MethodImpl, metadataFile) : base(TableIndex.MethodImpl, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<MethodImplEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<MethodImplEntry>(); var list = new List<MethodImplEntry>();
MethodImplEntry scrollTargetEntry = default;
for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.MethodImpl); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.MethodImpl); row++)
{ {
MethodImplEntry entry = new MethodImplEntry(metadataFile, MetadataTokens.MethodImplementationHandle(row)); list.Add(new MethodImplEntry(metadataFile, MetadataTokens.MethodImplementationHandle(row)));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct MethodImplEntry internal struct MethodImplEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly MethodImplementationHandle handle; readonly MethodImplementationHandle handle;

32
ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs

@ -25,46 +25,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodSemanticsTableTreeNode : MetadataTableTreeNode internal class MethodSemanticsTableTreeNode : MetadataTableTreeNode<MethodSemanticsTableTreeNode.MethodSemanticsEntry>
{ {
public MethodSemanticsTableTreeNode(MetadataFile metadataFile) public MethodSemanticsTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.MethodSemantics, metadataFile) : base(TableIndex.MethodSemantics, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<MethodSemanticsEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<MethodSemanticsEntry>(); var list = new List<MethodSemanticsEntry>();
MethodSemanticsEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.GetMethodSemantics()) foreach (var row in metadataFile.Metadata.GetMethodSemantics())
{ {
MethodSemanticsEntry entry = new MethodSemanticsEntry(metadataFile, row.Handle, row.Semantics, row.Method, row.Association); list.Add(new MethodSemanticsEntry(metadataFile, row.Handle, row.Semantics, row.Method, row.Association));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct MethodSemanticsEntry internal struct MethodSemanticsEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly Handle handle; readonly Handle handle;

35
ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs

@ -26,47 +26,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodSpecTableTreeNode : MetadataTableTreeNode internal class MethodSpecTableTreeNode : MetadataTableTreeNode<MethodSpecTableTreeNode.MethodSpecEntry>
{ {
public MethodSpecTableTreeNode(MetadataFile metadataFile) public MethodSpecTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.MethodSpec, metadataFile) : base(TableIndex.MethodSpec, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<MethodSpecEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<MethodSpecEntry>(); var list = new List<MethodSpecEntry>();
MethodSpecEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.GetMethodSpecifications())
foreach (var row in metadata.GetMethodSpecifications())
{
MethodSpecEntry entry = new MethodSpecEntry(metadataFile, row);
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{ {
ScrollItemIntoView(view, scrollTargetEntry); list.Add(new MethodSpecEntry(metadataFile, row));
} }
return list;
return true;
} }
struct MethodSpecEntry internal struct MethodSpecEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly MethodSpecificationHandle handle; readonly MethodSpecificationHandle handle;

34
ILSpy/Metadata/CorTables/MethodTableTreeNode.cs

@ -28,46 +28,24 @@ using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodTableTreeNode : MetadataTableTreeNode internal class MethodTableTreeNode : MetadataTableTreeNode<MethodTableTreeNode.MethodDefEntry>
{ {
public MethodTableTreeNode(MetadataFile metadataFile) public MethodTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.MethodDef, metadataFile) : base(TableIndex.MethodDef, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<MethodDefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<MethodDefEntry>(); var list = new List<MethodDefEntry>();
MethodDefEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.MethodDefinitions)
foreach (var row in metadata.MethodDefinitions)
{ {
MethodDefEntry entry = new MethodDefEntry(metadataFile, row); list.Add(new MethodDefEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct MethodDefEntry : IMemberTreeNode internal struct MethodDefEntry : IMemberTreeNode
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly MethodDefinitionHandle handle; readonly MethodDefinitionHandle handle;

35
ILSpy/Metadata/CorTables/ModuleRefTableTreeNode.cs

@ -24,47 +24,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ModuleRefTableTreeNode : MetadataTableTreeNode internal class ModuleRefTableTreeNode : MetadataTableTreeNode<ModuleRefTableTreeNode.ModuleRefEntry>
{ {
public ModuleRefTableTreeNode(MetadataFile metadataFile) public ModuleRefTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.ModuleRef, metadataFile) : base(TableIndex.ModuleRef, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ModuleRefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<ModuleRefEntry>(); var list = new List<ModuleRefEntry>();
ModuleRefEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.GetModuleReferences())
foreach (var row in metadata.GetModuleReferences())
{ {
ModuleRefEntry entry = new ModuleRefEntry(metadataFile, row); list.Add(new ModuleRefEntry(metadataFile, row));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct ModuleRefEntry internal struct ModuleRefEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly ModuleReferenceHandle handle; readonly ModuleReferenceHandle handle;

27
ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs

@ -24,38 +24,19 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ModuleTableTreeNode : MetadataTableTreeNode internal class ModuleTableTreeNode : MetadataTableTreeNode<ModuleTableTreeNode.ModuleEntry>
{ {
public ModuleTableTreeNode(MetadataFile metadataFile) public ModuleTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Module, metadataFile) : base(TableIndex.Module, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ModuleEntry> LoadTable()
{ {
tabPage.Title = Text.ToString(); return [new ModuleEntry(metadataFile, EntityHandle.ModuleDefinition)];
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<ModuleEntry>();
ModuleEntry scrollTargetEntry = default;
list.Add(new ModuleEntry(metadataFile, EntityHandle.ModuleDefinition));
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct ModuleEntry internal struct ModuleEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly ModuleDefinitionHandle handle; readonly ModuleDefinitionHandle handle;

44
ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs

@ -25,46 +25,25 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class NestedClassTableTreeNode : MetadataTableTreeNode class NestedClassTableTreeNode : MetadataTableTreeNode<NestedClassTableTreeNode.NestedClassEntry>
{ {
public NestedClassTableTreeNode(MetadataFile metadataFile) public NestedClassTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.NestedClass, metadataFile) : base(TableIndex.NestedClass, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<NestedClassEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<NestedClassEntry>(); var list = new List<NestedClassEntry>();
NestedClassEntry scrollTargetEntry = default; var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(TableIndex.NestedClass); var length = metadata.GetTableRowCount(TableIndex.NestedClass);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int typeDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
NestedClassEntry entry = new NestedClassEntry(metadataFile, ptr, rid); list.Add(new NestedClassEntry(metadataFile, ptr, rid, typeDefSize));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
readonly struct NestedClass readonly struct NestedClass
@ -79,47 +58,40 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct NestedClassEntry internal struct NestedClassEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly NestedClass nestedClass; readonly NestedClass nestedClass;
public int RID { get; } public int RID { get; }
public int Token => 0x29000000 | RID; public int Token => 0x29000000 | RID;
public int Offset { get; } public int Offset { get; }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
public int NestedClass => MetadataTokens.GetToken(nestedClass.Nested); public int NestedClass => MetadataTokens.GetToken(nestedClass.Nested);
public void OnNestedClassClick() public void OnNestedClassClick()
{ {
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Nested, protocol: "metadata"))); MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Nested, protocol: "metadata")));
} }
string nestedClassTooltip; string nestedClassTooltip;
public string NestedClassTooltip => GenerateTooltip(ref nestedClassTooltip, metadataFile, 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()
{ {
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Enclosing, protocol: "metadata"))); MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Enclosing, protocol: "metadata")));
} }
string enclosingClassTooltip; string enclosingClassTooltip;
public string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, metadataFile, nestedClass.Enclosing); public string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, metadataFile, nestedClass.Enclosing);
public NestedClassEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row) public NestedClassEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int typeDefSize)
{ {
this.metadataFile = metadataFile; this.metadataFile = metadataFile;
this.RID = row; this.RID = row;
var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.NestedClass) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.NestedClass)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.NestedClass) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.NestedClass) * (row - 1);
this.Offset = metadataFile.MetadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
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

@ -25,46 +25,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ParamTableTreeNode : MetadataTableTreeNode internal class ParamTableTreeNode : MetadataTableTreeNode<ParamTableTreeNode.ParamEntry>
{ {
public ParamTableTreeNode(MetadataFile metadataFile) public ParamTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Param, metadataFile) : base(TableIndex.Param, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ParamEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<ParamEntry>(); var list = new List<ParamEntry>();
ParamEntry scrollTargetEntry = default;
for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.Param); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.Param); row++)
{ {
ParamEntry entry = new ParamEntry(metadataFile, MetadataTokens.ParameterHandle(row)); list.Add(new ParamEntry(metadataFile, MetadataTokens.ParameterHandle(row)));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct ParamEntry internal struct ParamEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly ParameterHandle handle; readonly ParameterHandle handle;

42
ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs

@ -25,46 +25,26 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class PropertyMapTableTreeNode : MetadataTableTreeNode class PropertyMapTableTreeNode : MetadataTableTreeNode<PropertyMapTableTreeNode.PropertyMapEntry>
{ {
public PropertyMapTableTreeNode(MetadataFile metadataFile) public PropertyMapTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.PropertyMap, metadataFile) : base(TableIndex.PropertyMap, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<PropertyMapEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<PropertyMapEntry>(); var list = new List<PropertyMapEntry>();
PropertyMapEntry scrollTargetEntry = default; var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(TableIndex.PropertyMap); var length = metadata.GetTableRowCount(TableIndex.PropertyMap);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
int propertyDefSize = metadata.GetTableRowCount(TableIndex.Property) < ushort.MaxValue ? 2 : 4;
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
PropertyMapEntry entry = new PropertyMapEntry(metadataFile, ptr, rid); list.Add(new PropertyMapEntry(metadataFile, ptr, rid, typeDefSize, propertyDefSize));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
readonly struct PropertyMap readonly struct PropertyMap
@ -79,15 +59,13 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct PropertyMapEntry internal struct PropertyMapEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly PropertyMap propertyMap; readonly PropertyMap propertyMap;
public int RID { get; } public int RID { get; }
public int Token => 0x15000000 | RID; public int Token => 0x15000000 | RID;
public int Offset { get; } public int Offset { get; }
[ColumnInfo("X8", Kind = ColumnKind.Token)] [ColumnInfo("X8", Kind = ColumnKind.Token)]
@ -112,15 +90,13 @@ namespace ICSharpCode.ILSpy.Metadata
string propertyListTooltip; string propertyListTooltip;
public string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, metadataFile, propertyMap.PropertyList); public string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, metadataFile, propertyMap.PropertyList);
public PropertyMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row) public PropertyMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int typeDefSize, int propertyDefSize)
{ {
this.metadataFile = metadataFile; this.metadataFile = metadataFile;
this.RID = row; this.RID = row;
var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.PropertyMap) var rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.PropertyMap)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.PropertyMap) * (row - 1); + metadataFile.Metadata.GetTableRowSize(TableIndex.PropertyMap) * (row - 1);
this.Offset = metadataFile.MetadataOffset + rowOffset; this.Offset = metadataFile.MetadataOffset + rowOffset;
int typeDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < 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;

34
ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs

@ -27,47 +27,25 @@ using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class PropertyTableTreeNode : MetadataTableTreeNode internal class PropertyTableTreeNode : MetadataTableTreeNode<PropertyTableTreeNode.PropertyDefEntry>
{ {
public PropertyTableTreeNode(MetadataFile metadataFile) public PropertyTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Property, metadataFile) : base(TableIndex.Property, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<PropertyDefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<PropertyDefEntry>(); var list = new List<PropertyDefEntry>();
PropertyDefEntry scrollTargetEntry = default;
foreach (var row in metadata.PropertyDefinitions)
{
PropertyDefEntry entry = new PropertyDefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view; foreach (var row in metadataFile.Metadata.PropertyDefinitions)
if (scrollTargetEntry.RID > 0)
{ {
ScrollItemIntoView(view, scrollTargetEntry); list.Add(new PropertyDefEntry(metadataFile, row));
} }
return list;
return true;
} }
struct PropertyDefEntry : IMemberTreeNode internal struct PropertyDefEntry : IMemberTreeNode
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly PropertyDefinitionHandle handle; readonly PropertyDefinitionHandle handle;

33
ILSpy/Metadata/CorTables/PtrTableTreeNode.cs

@ -25,7 +25,7 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class PtrTableTreeNode : MetadataTableTreeNode class PtrTableTreeNode : MetadataTableTreeNode<PtrTableTreeNode.PtrEntry>
{ {
readonly TableIndex referencedTableKind; readonly TableIndex referencedTableKind;
@ -47,17 +47,11 @@ namespace ICSharpCode.ILSpy.Metadata
}; };
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<PtrEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<PtrEntry>(); var list = new List<PtrEntry>();
PtrEntry scrollTargetEntry = default;
var metadata = metadataFile.Metadata;
var length = metadata.GetTableRowCount(Kind); var length = metadata.GetTableRowCount(Kind);
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan(); ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
@ -65,24 +59,9 @@ namespace ICSharpCode.ILSpy.Metadata
for (int rid = 1; rid <= length; rid++) for (int rid = 1; rid <= length; rid++)
{ {
var entry = new PtrEntry(metadataFile, Kind, referencedTableKind, handleDefSize, ptr, rid); list.Add(new PtrEntry(metadataFile, Kind, referencedTableKind, handleDefSize, ptr, rid));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
readonly struct HandlePtr readonly struct HandlePtr
@ -95,7 +74,7 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
struct PtrEntry internal struct PtrEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly HandlePtr handlePtr; readonly HandlePtr handlePtr;

31
ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs

@ -24,46 +24,25 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
class StandAloneSigTableTreeNode : MetadataTableTreeNode class StandAloneSigTableTreeNode : MetadataTableTreeNode<StandAloneSigTableTreeNode.StandAloneSigEntry>
{ {
public StandAloneSigTableTreeNode(MetadataFile metadataFile) public StandAloneSigTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.StandAloneSig, metadataFile) : base(TableIndex.StandAloneSig, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<StandAloneSigEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<StandAloneSigEntry>(); var list = new List<StandAloneSigEntry>();
StandAloneSigEntry scrollTargetEntry = default;
for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.StandAloneSig); row++) for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.StandAloneSig); row++)
{ {
StandAloneSigEntry entry = new StandAloneSigEntry(metadataFile, MetadataTokens.StandaloneSignatureHandle(row)); list.Add(new StandAloneSigEntry(metadataFile, MetadataTokens.StandaloneSignatureHandle(row)));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return true; return list;
} }
struct StandAloneSigEntry internal struct StandAloneSigEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly StandaloneSignatureHandle handle; readonly StandaloneSignatureHandle handle;

35
ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs

@ -30,47 +30,24 @@ using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class TypeDefTableTreeNode : MetadataTableTreeNode internal class TypeDefTableTreeNode : MetadataTableTreeNode<TypeDefTableTreeNode.TypeDefEntry>
{ {
public TypeDefTableTreeNode(MetadataFile metadataFile) public TypeDefTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.TypeDef, metadataFile) : base(TableIndex.TypeDef, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<TypeDefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<TypeDefEntry>(); var list = new List<TypeDefEntry>();
TypeDefEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.TypeDefinitions)
foreach (var row in metadata.TypeDefinitions)
{
TypeDefEntry entry = new TypeDefEntry(metadataFile, row);
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{ {
ScrollItemIntoView(view, scrollTargetEntry); list.Add(new TypeDefEntry(metadataFile, row));
} }
return list;
return true;
} }
struct TypeDefEntry : IMemberTreeNode internal struct TypeDefEntry : IMemberTreeNode
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly TypeDefinitionHandle handle; readonly TypeDefinitionHandle handle;

35
ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs

@ -24,47 +24,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class TypeRefTableTreeNode : MetadataTableTreeNode internal class TypeRefTableTreeNode : MetadataTableTreeNode<TypeRefTableTreeNode.TypeRefEntry>
{ {
public TypeRefTableTreeNode(MetadataFile metadataFile) public TypeRefTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.TypeRef, metadataFile) : base(TableIndex.TypeRef, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<TypeRefEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<TypeRefEntry>(); var list = new List<TypeRefEntry>();
TypeRefEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.TypeReferences)
foreach (var row in metadata.TypeReferences)
{ {
TypeRefEntry entry = new TypeRefEntry(metadataFile, row); list.Add(new TypeRefEntry(metadataFile, row));
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
} }
return list;
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
return true;
} }
struct TypeRefEntry internal struct TypeRefEntry
{ {
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
readonly TypeReferenceHandle handle; readonly TypeReferenceHandle handle;

35
ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs

@ -26,47 +26,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class TypeSpecTableTreeNode : MetadataTableTreeNode internal class TypeSpecTableTreeNode : MetadataTableTreeNode<TypeSpecTableTreeNode.TypeSpecEntry>
{ {
public TypeSpecTableTreeNode(MetadataFile metadataFile) public TypeSpecTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.TypeSpec, metadataFile) : base(TableIndex.TypeSpec, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<TypeSpecEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var metadata = metadataFile.Metadata;
var list = new List<TypeSpecEntry>(); var list = new List<TypeSpecEntry>();
TypeSpecEntry scrollTargetEntry = default; foreach (var row in metadataFile.Metadata.GetTypeSpecifications())
foreach (var row in metadata.GetTypeSpecifications())
{
TypeSpecEntry entry = new TypeSpecEntry(metadataFile, row);
if (scrollTarget.Equals(row))
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{ {
ScrollItemIntoView(view, scrollTargetEntry); list.Add(new TypeSpecEntry(metadataFile, row));
} }
return list;
return true;
} }
struct TypeSpecEntry internal struct TypeSpecEntry
{ {
readonly int metadataOffset; readonly int metadataOffset;
readonly MetadataFile module; readonly MetadataFile module;

39
ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs

@ -29,46 +29,27 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class CustomDebugInformationTableTreeNode : DebugMetadataTableTreeNode internal class CustomDebugInformationTableTreeNode : DebugMetadataTableTreeNode<CustomDebugInformationTableTreeNode.CustomDebugInformationEntry>
{ {
public CustomDebugInformationTableTreeNode(MetadataFile metadataFile) public CustomDebugInformationTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.CustomDebugInformation, metadataFile) : base(TableIndex.CustomDebugInformation, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<CustomDebugInformationEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
view.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.VisibleWhenSelected;
view.RowDetailsTemplateSelector = new CustomDebugInformationDetailsTemplateSelector();
var list = new List<CustomDebugInformationEntry>(); var list = new List<CustomDebugInformationEntry>();
CustomDebugInformationEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.CustomDebugInformation) foreach (var row in metadataFile.Metadata.CustomDebugInformation)
{ {
CustomDebugInformationEntry entry = new CustomDebugInformationEntry(metadataFile, row); list.Add(new CustomDebugInformationEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry?.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
}
return true; protected override void ConfigureDataGrid(DataGrid view)
{
view.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.VisibleWhenSelected;
view.RowDetailsTemplateSelector = new CustomDebugInformationDetailsTemplateSelector();
} }
class CustomDebugInformationDetailsTemplateSelector : DataTemplateSelector class CustomDebugInformationDetailsTemplateSelector : DataTemplateSelector
@ -89,7 +70,7 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
class CustomDebugInformationEntry internal struct CustomDebugInformationEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;

30
ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs

@ -26,45 +26,25 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class DocumentTableTreeNode : DebugMetadataTableTreeNode internal class DocumentTableTreeNode : DebugMetadataTableTreeNode<DocumentTableTreeNode.DocumentEntry>
{ {
public DocumentTableTreeNode(MetadataFile metadataFile) public DocumentTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.Document, metadataFile) : base(TableIndex.Document, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<DocumentEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<DocumentEntry>(); var list = new List<DocumentEntry>();
DocumentEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.Documents) foreach (var row in metadataFile.Metadata.Documents)
{ {
DocumentEntry entry = new DocumentEntry(metadataFile, row); list.Add(new DocumentEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return true; return list;
} }
readonly struct DocumentEntry internal readonly struct DocumentEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;

31
ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs

@ -24,45 +24,24 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class ImportScopeTableTreeNode : DebugMetadataTableTreeNode internal class ImportScopeTableTreeNode : DebugMetadataTableTreeNode<ImportScopeTableTreeNode.ImportScopeEntry>
{ {
public ImportScopeTableTreeNode(MetadataFile metadataFile) public ImportScopeTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.ImportScope, metadataFile) : base(TableIndex.ImportScope, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<ImportScopeEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<ImportScopeEntry>(); var list = new List<ImportScopeEntry>();
ImportScopeEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.ImportScopes) foreach (var row in metadataFile.Metadata.ImportScopes)
{ {
ImportScopeEntry entry = new ImportScopeEntry(metadataFile, row); list.Add(new ImportScopeEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
readonly struct ImportScopeEntry internal readonly struct ImportScopeEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;

29
ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs

@ -24,45 +24,26 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class LocalConstantTableTreeNode : DebugMetadataTableTreeNode internal class LocalConstantTableTreeNode : DebugMetadataTableTreeNode<LocalConstantTableTreeNode.LocalConstantEntry>
{ {
public LocalConstantTableTreeNode(MetadataFile metadataFile) public LocalConstantTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.LocalConstant, metadataFile) : base(TableIndex.LocalConstant, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<LocalConstantEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<LocalConstantEntry>(); var list = new List<LocalConstantEntry>();
LocalConstantEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.LocalConstants) foreach (var row in metadataFile.Metadata.LocalConstants)
{ {
LocalConstantEntry entry = new LocalConstantEntry(metadataFile, row); list.Add(new LocalConstantEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return true; return list;
} }
struct LocalConstantEntry internal readonly struct LocalConstantEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;

29
ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs

@ -25,45 +25,26 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class LocalScopeTableTreeNode : DebugMetadataTableTreeNode internal class LocalScopeTableTreeNode : DebugMetadataTableTreeNode<LocalScopeTableTreeNode.LocalScopeEntry>
{ {
public LocalScopeTableTreeNode(MetadataFile metadataFile) public LocalScopeTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.LocalScope, metadataFile) : base(TableIndex.LocalScope, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<LocalScopeEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<LocalScopeEntry>(); var list = new List<LocalScopeEntry>();
LocalScopeEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.LocalScopes) foreach (var row in metadataFile.Metadata.LocalScopes)
{ {
LocalScopeEntry entry = new LocalScopeEntry(metadataFile, row); list.Add(new LocalScopeEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return true; return list;
} }
struct LocalScopeEntry internal struct LocalScopeEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;

29
ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs

@ -24,45 +24,26 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class LocalVariableTableTreeNode : DebugMetadataTableTreeNode internal class LocalVariableTableTreeNode : DebugMetadataTableTreeNode<LocalVariableTableTreeNode.LocalVariableEntry>
{ {
public LocalVariableTableTreeNode(MetadataFile metadataFile) public LocalVariableTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.LocalVariable, metadataFile) : base(TableIndex.LocalVariable, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<LocalVariableEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<LocalVariableEntry>(); var list = new List<LocalVariableEntry>();
LocalVariableEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.LocalVariables) foreach (var row in metadataFile.Metadata.LocalVariables)
{ {
LocalVariableEntry entry = new LocalVariableEntry(metadataFile, row); list.Add(new LocalVariableEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return true; return list;
} }
struct LocalVariableEntry internal struct LocalVariableEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;

30
ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs

@ -27,45 +27,25 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class MethodDebugInformationTableTreeNode : DebugMetadataTableTreeNode internal class MethodDebugInformationTableTreeNode : DebugMetadataTableTreeNode<MethodDebugInformationTableTreeNode.MethodDebugInformationEntry>
{ {
public MethodDebugInformationTableTreeNode(MetadataFile metadataFile) public MethodDebugInformationTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.MethodDebugInformation, metadataFile) : base(TableIndex.MethodDebugInformation, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<MethodDebugInformationEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<MethodDebugInformationEntry>(); var list = new List<MethodDebugInformationEntry>();
MethodDebugInformationEntry scrollTargetEntry = default;
foreach (var row in metadataFile.Metadata.MethodDebugInformation) foreach (var row in metadataFile.Metadata.MethodDebugInformation)
{ {
MethodDebugInformationEntry entry = new MethodDebugInformationEntry(metadataFile, row); list.Add(new MethodDebugInformationEntry(metadataFile, row));
if (entry.RID == scrollTarget)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
struct MethodDebugInformationEntry internal struct MethodDebugInformationEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;

31
ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs

@ -24,48 +24,28 @@ using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata namespace ICSharpCode.ILSpy.Metadata
{ {
internal class StateMachineMethodTableTreeNode : DebugMetadataTableTreeNode internal class StateMachineMethodTableTreeNode : DebugMetadataTableTreeNode<StateMachineMethodTableTreeNode.StateMachineMethodEntry>
{ {
public StateMachineMethodTableTreeNode(MetadataFile metadataFile) public StateMachineMethodTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.StateMachineMethod, metadataFile) : base(TableIndex.StateMachineMethod, metadataFile)
{ {
} }
public override bool View(ViewModels.TabPageModel tabPage) protected override IReadOnlyList<StateMachineMethodEntry> LoadTable()
{ {
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
var list = new List<StateMachineMethodEntry>(); var list = new List<StateMachineMethodEntry>();
StateMachineMethodEntry scrollTargetEntry = default;
var length = metadataFile.Metadata.GetTableRowCount(TableIndex.StateMachineMethod); var length = metadataFile.Metadata.GetTableRowCount(TableIndex.StateMachineMethod);
var reader = metadataFile.Metadata.AsBlobReader(); var reader = metadataFile.Metadata.AsBlobReader();
reader.Offset = metadataFile.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(metadataFile, ref reader, rid); list.Add(new StateMachineMethodEntry(metadataFile, ref reader, rid));
if (scrollTarget == rid)
{
scrollTargetEntry = entry;
}
list.Add(entry);
}
view.ItemsSource = list;
tabPage.Content = view;
if (scrollTargetEntry.RID > 0)
{
ScrollItemIntoView(view, scrollTargetEntry);
} }
return list;
return true;
} }
struct StateMachineMethodEntry internal struct StateMachineMethodEntry
{ {
readonly int? offset; readonly int? offset;
readonly MetadataFile metadataFile; readonly MetadataFile metadataFile;
@ -114,7 +94,6 @@ namespace ICSharpCode.ILSpy.Metadata
this.kickoffMethodTooltip = null; this.kickoffMethodTooltip = null;
this.moveNextMethodTooltip = null; this.moveNextMethodTooltip = null;
} }
} }
} }
} }

51
ILSpy/Metadata/MetadataTableTreeNode.cs

@ -16,7 +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.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Windows.Controls; using System.Windows.Controls;
@ -26,6 +26,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
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
{ {
@ -51,10 +52,18 @@ namespace ICSharpCode.ILSpy.Metadata
this.scrollTarget = metadataFile.Metadata.GetRowNumber((EntityHandle)handle); this.scrollTarget = metadataFile.Metadata.GetRowNumber((EntityHandle)handle);
} }
protected void ScrollItemIntoView(DataGrid view, object item) protected void ScrollRowIntoView(DataGrid view, int row)
{ {
view.Loaded += View_Loaded; if (!view.IsLoaded)
view.Dispatcher.BeginInvoke((Action)(() => view.SelectItem(item)), DispatcherPriority.Background); {
view.Loaded += View_Loaded;
}
else
{
View_Loaded(view, new System.Windows.RoutedEventArgs());
}
if (view.Items.Count > row && row >= 0)
view.Dispatcher.BeginInvoke(() => view.SelectItem(view.Items[row]), DispatcherPriority.Background);
} }
private void View_Loaded(object sender, System.Windows.RoutedEventArgs e) private void View_Loaded(object sender, System.Windows.RoutedEventArgs e)
@ -138,7 +147,39 @@ namespace ICSharpCode.ILSpy.Metadata
} }
} }
internal abstract class DebugMetadataTableTreeNode : MetadataTableTreeNode internal abstract class MetadataTableTreeNode<TEntry> : MetadataTableTreeNode
where TEntry : struct
{
public MetadataTableTreeNode(TableIndex kind, MetadataFile metadataFile)
: base(kind, metadataFile)
{
}
protected abstract IReadOnlyList<TEntry> LoadTable();
protected virtual void ConfigureDataGrid(DataGrid view)
{
}
public override bool View(TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
ConfigureDataGrid(view);
view.ItemsSource = LoadTable();
tabPage.Content = view;
ScrollRowIntoView(view, scrollTarget);
return true;
}
}
internal abstract class DebugMetadataTableTreeNode<TEntry> : MetadataTableTreeNode<TEntry>
where TEntry : struct
{ {
public DebugMetadataTableTreeNode(TableIndex kind, MetadataFile metadataFile) public DebugMetadataTableTreeNode(TableIndex kind, MetadataFile metadataFile)
: base(kind, metadataFile) : base(kind, metadataFile)

Loading…
Cancel
Save