Browse Source

Typed leaves for the last 3 enumerable cor tables

Replaces the universal placeholder for StandAloneSig, DeclSecurity, and
File. These three are the last CorTables that System.Reflection.Metadata
exposes as direct enumerations / typed handles. The remaining ~12 tables
(InterfaceImpl, NestedClass, ClassLayout, FieldLayout, FieldRva,
FieldMarshal, ImplMap, MethodImpl, MethodSemantics, EventMap,
PropertyMap, the *Ptr family) read raw little-endian metadata bytes via
Helpers.GetValueLittleEndian + coded-token reflection helpers in the
WPF tree, so they wait for the Helpers infrastructure port.

Assisted-by: Claude:claude-opus-4-7:Claude Code
pull/3755/head
Siegfried Pammer 2 months ago
parent
commit
dc97e1c8fd
  1. 81
      ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs
  2. 78
      ILSpy/Metadata/CorTables/FileTableTreeNode.cs
  3. 74
      ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs
  4. 3
      ILSpy/Metadata/MetadataTablesTreeNode.cs

81
ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Metadata;
namespace ILSpy.Metadata.CorTables
{
/// <summary>
/// View of the DeclSecurity table — declarative security attributes (CAS-era
/// <c>[SecurityPermission(...)]</c>) attached to assemblies, types, or methods. The
/// PermissionSet blob holds a serialised XML / binary permission descriptor.
/// </summary>
public sealed class DeclSecurityTableTreeNode : MetadataTableTreeNode<DeclSecurityTableTreeNode.DeclSecurityEntry>
{
public DeclSecurityTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.DeclSecurity, metadataFile)
{
}
protected override IReadOnlyList<DeclSecurityEntry> LoadTable()
{
var list = new List<DeclSecurityEntry>();
foreach (var row in metadataFile.Metadata.DeclarativeSecurityAttributes)
list.Add(new DeclSecurityEntry(metadataFile, row));
return list;
}
public sealed class DeclSecurityEntry
{
readonly MetadataFile metadataFile;
readonly DeclarativeSecurityAttributeHandle handle;
readonly DeclarativeSecurityAttribute declSecAttr;
public int RID => MetadataTokens.GetRowNumber(handle);
[ColumnInfo("X8")]
public int Token => MetadataTokens.GetToken(handle);
[ColumnInfo("X8")]
public int Offset => metadataFile.MetadataOffset
+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.DeclSecurity)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.DeclSecurity) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.Token)]
public int Parent => MetadataTokens.GetToken(declSecAttr.Parent);
[ColumnInfo("X8")]
public DeclarativeSecurityAction Action => declSecAttr.Action;
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int PermissionSet => MetadataTokens.GetHeapOffset(declSecAttr.PermissionSet);
public DeclSecurityEntry(MetadataFile metadataFile, DeclarativeSecurityAttributeHandle handle)
{
this.metadataFile = metadataFile;
this.handle = handle;
declSecAttr = metadataFile.Metadata.GetDeclarativeSecurityAttribute(handle);
}
}
}
}

78
ILSpy/Metadata/CorTables/FileTableTreeNode.cs

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Metadata;
namespace ILSpy.Metadata.CorTables
{
/// <summary>
/// View of the File table — multi-module assemblies list their constituent .netmodule
/// files here. Vanishingly rare in modern .NET; nearly every assembly is single-file.
/// </summary>
public sealed class FileTableTreeNode : MetadataTableTreeNode<FileTableTreeNode.FileEntry>
{
public FileTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.File, metadataFile)
{
}
protected override IReadOnlyList<FileEntry> LoadTable()
{
var list = new List<FileEntry>();
foreach (var row in metadataFile.Metadata.AssemblyFiles)
list.Add(new FileEntry(metadataFile, row));
return list;
}
public sealed class FileEntry
{
readonly MetadataFile metadataFile;
readonly AssemblyFileHandle handle;
readonly AssemblyFile assemblyFile;
public int RID => MetadataTokens.GetRowNumber(handle);
[ColumnInfo("X8")]
public int Token => MetadataTokens.GetToken(handle);
[ColumnInfo("X8")]
public int Offset => metadataFile.MetadataOffset
+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.File)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.File) * (RID - 1);
[ColumnInfo("X8")]
public int Attributes => assemblyFile.ContainsMetadata ? 1 : 0;
public string Name => metadataFile.Metadata.GetString(assemblyFile.Name);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int HashValue => MetadataTokens.GetHeapOffset(assemblyFile.HashValue);
public FileEntry(MetadataFile metadataFile, AssemblyFileHandle handle)
{
this.metadataFile = metadataFile;
this.handle = handle;
assemblyFile = metadataFile.Metadata.GetAssemblyFile(handle);
}
}
}
}

74
ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Metadata;
namespace ILSpy.Metadata.CorTables
{
/// <summary>
/// View of the StandAloneSig table — signatures referenced from outside their natural
/// owners: local-variable layouts for method bodies and call-site signatures for
/// <c>calli</c>. Each row carries a single blob signature handle.
/// </summary>
public sealed class StandAloneSigTableTreeNode : MetadataTableTreeNode<StandAloneSigTableTreeNode.StandAloneSigEntry>
{
public StandAloneSigTableTreeNode(MetadataFile metadataFile)
: base(TableIndex.StandAloneSig, metadataFile)
{
}
protected override IReadOnlyList<StandAloneSigEntry> LoadTable()
{
var list = new List<StandAloneSigEntry>();
for (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.StandAloneSig); row++)
list.Add(new StandAloneSigEntry(metadataFile, MetadataTokens.StandaloneSignatureHandle(row)));
return list;
}
public sealed class StandAloneSigEntry
{
readonly MetadataFile metadataFile;
readonly StandaloneSignatureHandle handle;
readonly StandaloneSignature standaloneSig;
public int RID => MetadataTokens.GetRowNumber(handle);
[ColumnInfo("X8")]
public int Token => MetadataTokens.GetToken(handle);
[ColumnInfo("X8")]
public int Offset => metadataFile.MetadataOffset
+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.StandAloneSig)
+ metadataFile.Metadata.GetTableRowSize(TableIndex.StandAloneSig) * (RID - 1);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(standaloneSig.Signature);
public StandAloneSigEntry(MetadataFile metadataFile, StandaloneSignatureHandle handle)
{
this.metadataFile = metadataFile;
this.handle = handle;
standaloneSig = metadataFile.Metadata.GetStandaloneSignature(handle);
}
}
}
}

3
ILSpy/Metadata/MetadataTablesTreeNode.cs

@ -94,6 +94,9 @@ namespace ILSpy.Metadata @@ -94,6 +94,9 @@ namespace ILSpy.Metadata
TableIndex.GenericParam => new GenericParamTableTreeNode(metadataFile),
TableIndex.MethodSpec => new MethodSpecTableTreeNode(metadataFile),
TableIndex.GenericParamConstraint => new GenericParamConstraintTableTreeNode(metadataFile),
TableIndex.StandAloneSig => new StandAloneSigTableTreeNode(metadataFile),
TableIndex.DeclSecurity => new DeclSecurityTableTreeNode(metadataFile),
TableIndex.File => new FileTableTreeNode(metadataFile),
_ => new UnsupportedMetadataTableTreeNode(table, metadataFile),
};
}

Loading…
Cancel
Save