Skip to content

Fix dump of TypeSpecs #189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 7, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 52 additions & 11 deletions MetadataProcessor.Shared/nanoDumperGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand Down Expand Up @@ -653,20 +653,19 @@ private void DumpTypeSpecifications(

_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(typeReference, out ushort index);

var typeSpec = new TypeSpec();
TypeSpec typeSpec = new TypeSpec();

// assume that real token index is the same as ours
// need to add one because ours is 0 indexed
realToken = new MetadataToken(TokenType.TypeSpec, index + 1).ToUInt32().ToString("X8");

typeSpec.ReferenceId = $"[{new nanoMetadataToken(NanoClrTable.TBL_TypeSpec, index)}] /*{realToken}*/";

// build name
StringBuilder typeSpecName = new StringBuilder();

if (typeReference is GenericParameter)
{
var genericParam = typeReference as GenericParameter;
GenericParameter genericParam = typeReference as GenericParameter;

typeSpecName.Append(typeReference.MetadataType);

Expand All @@ -683,19 +682,19 @@ private void DumpTypeSpecifications(

typeSpec.Name = typeSpecName.ToString();
}
else if (typeReference is GenericInstanceType)
else if (typeReference is GenericInstanceType genericInstanceType)
{
// type is a GenericInstance
// can't compare with Cecil MetadataToken because the tables have been cleaned-up and re-indexed

typeSpec.Name = typeReference.FullName;

foreach (var mr in _tablesContext.MethodReferencesTable.Items)
foreach (MethodReference mr in _tablesContext.MethodReferencesTable.Items)
{
if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(mr.DeclaringType, out ushort referenceId) &&
referenceId == index)
{
var memberRef = new MemberRef()
MemberRef memberRef = new MemberRef()
{
Name = mr.Name
};
Expand All @@ -712,12 +711,12 @@ private void DumpTypeSpecifications(
}
}

foreach (var ms in _tablesContext.MethodSpecificationTable.Items)
foreach (MethodSpecification ms in _tablesContext.MethodSpecificationTable.Items)
{
if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(ms.DeclaringType, out ushort referenceId) &&
referenceId == index)
{
var memberRef = new MemberRef()
MemberRef memberRef = new MemberRef()
{
Name = ms.Name
};
Expand All @@ -734,21 +733,63 @@ private void DumpTypeSpecifications(
}
}

foreach (var fr in _tablesContext.FieldReferencesTable.Items)
foreach (FieldReference fr in _tablesContext.FieldReferencesTable.Items)
{
if (_tablesContext.TypeSpecificationsTable.TryGetTypeReferenceId(fr.DeclaringType, out ushort referenceId) &&
referenceId == index)
{
var memberRef = new MemberRef()
MemberRef memberRef = new MemberRef()
{
Name = fr.Name
};

if (_tablesContext.FieldReferencesTable.TryGetFieldReferenceId(fr, out ushort fieldRefId))
{
realToken = fr.MetadataToken.ToInt32().ToString("X8");
memberRef.ReferenceId = $"[{new nanoMetadataToken(NanoClrTable.TBL_FieldRef, fieldRefId)}] /*{realToken}*/";
memberRef.Signature = fr.FieldType.TypeSignatureAsString();
}

typeSpec.MemberReferences.Add(memberRef);
}
}

if (genericInstanceType.ElementType is TypeDefinition definition)
{
foreach (MethodDefinition md in definition.Methods)
{
// skip compiler-generated or primitive helpers if you like
MemberRef memberRef = new MemberRef
{
Name = md.Name,
Signature = PrintSignatureForMethod(md)
};

// get the MethodDef RID from your MethodDefinitionTable
if (_tablesContext.MethodDefinitionTable.TryGetMethodReferenceId(md, out ushort defId))
{
realToken = md.MetadataToken.ToInt32().ToString("X8");
memberRef.ReferenceId = $"[{new nanoMetadataToken(NanoClrTable.TBL_MethodDef, defId)}] /*{realToken}*/";
}

typeSpec.MemberReferences.Add(memberRef);
}

// and similarly for fields if you want:
foreach (FieldDefinition fd in definition.Fields)
{
MemberRef memberRef = new MemberRef
{
Name = fd.Name,
Signature = fd.FieldType.TypeSignatureAsString()
};

if (_tablesContext.FieldsTable.TryGetFieldReferenceId(fd, false, out ushort fieldId))
{
realToken = fd.MetadataToken.ToInt32().ToString("X8");
memberRef.ReferenceId = $"[{new nanoMetadataToken(NanoClrTable.TBL_FieldDef, fieldId)}] /*{realToken}*/";
}

typeSpec.MemberReferences.Add(memberRef);
}
}
Expand Down