diff --git a/ICSharpCode.Decompiler/DebugInfo/KnownGuids.cs b/ICSharpCode.Decompiler/DebugInfo/KnownGuids.cs index 353b49acf..283818df5 100644 --- a/ICSharpCode.Decompiler/DebugInfo/KnownGuids.cs +++ b/ICSharpCode.Decompiler/DebugInfo/KnownGuids.cs @@ -10,11 +10,13 @@ namespace ICSharpCode.Decompiler.DebugInfo public static readonly Guid VBLanguageGuid = new Guid("3a12d0b8-c26c-11d0-b442-00a0244a1dd2"); public static readonly Guid FSharpLanguageGuid = new Guid("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3"); + // https://github.com/dotnet/roslyn/blob/main/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs public static readonly Guid StateMachineHoistedLocalScopes = new Guid("6DA9A61E-F8C7-4874-BE62-68BC5630DF71"); public static readonly Guid DynamicLocalVariables = new Guid("83C563C4-B4F3-47D5-B824-BA5441477EA8"); public static readonly Guid DefaultNamespaces = new Guid("58b2eab6-209f-4e4e-a22c-b2d0f910c782"); public static readonly Guid EditAndContinueLocalSlotMap = new Guid("755F52A8-91C5-45BE-B4B8-209571E552BD"); public static readonly Guid EditAndContinueLambdaAndClosureMap = new Guid("A643004C-0240-496F-A783-30D64F4979DE"); + public static readonly Guid EncStateMachineStateMap = new Guid("8B78CD68-2EDE-420B-980B-E15884B8AAA3"); public static readonly Guid EmbeddedSource = new Guid("0e8a571b-6926-466e-b4ad-8ab04611f5fe"); public static readonly Guid SourceLink = new Guid("CC110556-A091-4D38-9FEC-25AB9A351A6A"); public static readonly Guid MethodSteppingInformation = new Guid("54FD2AC5-E925-401A-9C2A-F94F171072F8"); diff --git a/ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs b/ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs index 4be8cd37a..4ad56815d 100644 --- a/ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs @@ -87,14 +87,14 @@ namespace ICSharpCode.ILSpy.Metadata public Version Version => assemblyRef.Version; - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public AssemblyFlags Flags => assemblyRef.Flags; public object FlagsTooltip => new FlagsTooltip((int)assemblyRef.Flags, null) { FlagGroup.CreateMultipleChoiceGroup(typeof(AssemblyFlags), selectedValue: (int)assemblyRef.Flags, includeAll: false) }; - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int PublicKeyOrToken => MetadataTokens.GetHeapOffset(assemblyRef.PublicKeyOrToken); public string PublicKeyOrTokenTooltip { diff --git a/ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs b/ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs index 4c16f6713..5d8409657 100644 --- a/ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs @@ -72,14 +72,14 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.Assembly) + metadata.GetTableRowSize(TableIndex.Assembly) * (RID - 1); - [StringFormat("X4")] + [ColumnInfo("X4", Kind = ColumnKind.Other)] public AssemblyHashAlgorithm HashAlgorithm => assembly.HashAlgorithm; public object HashAlgorithmTooltip => new FlagsTooltip() { FlagGroup.CreateSingleChoiceGroup(typeof(AssemblyHashAlgorithm), selectedValue: (int)assembly.HashAlgorithm, defaultFlag: new Flag("None (0000)", 0, false), includeAny: false) }; - [StringFormat("X4")] + [ColumnInfo("X4", Kind = ColumnKind.Other)] public AssemblyFlags Flags => assembly.Flags; public object FlagsTooltip => new FlagsTooltip() { diff --git a/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs b/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs index 97be91596..af78f3044 100644 --- a/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs @@ -100,8 +100,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(classLayout.Parent); public void OnParentClick() @@ -109,19 +108,13 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, classLayout.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)classLayout.Parent).WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, classLayout.Parent); - [StringFormat("X4")] + [ColumnInfo("X4", Kind = ColumnKind.Other)] public ushort PackingSize => classLayout.PackingSize; - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public uint ClassSize => classLayout.ClassSize; public ClassLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row) @@ -133,6 +126,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1); this.Offset = metadataOffset + rowOffset; this.classLayout = new ClassLayout(ptr + rowOffset, metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4); + this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs b/ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs index 0493abd8f..3f9dc97c8 100644 --- a/ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs @@ -87,13 +87,12 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.Constant) + metadata.GetTableRowSize(TableIndex.Constant) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public ConstantTypeCode Type => constant.TypeCode; public string TypeTooltip => constant.TypeCode.ToString(); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(constant.Parent); public void OnParentClick() @@ -101,16 +100,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, constant.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - constant.Parent.WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, constant.Parent); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Value => MetadataTokens.GetHeapOffset(constant.Value); public string ValueTooltip { @@ -126,6 +119,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.constant = metadata.GetConstant(handle); + this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs b/ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs index 4070ad9be..30a6cf47f 100644 --- a/ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs @@ -87,8 +87,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.CustomAttribute) + metadata.GetTableRowSize(TableIndex.CustomAttribute) * (RID - 1); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(customAttr.Parent); public void OnParentClick() @@ -96,17 +95,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, customAttr.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - customAttr.Parent.WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, customAttr.Parent); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Constructor => MetadataTokens.GetToken(customAttr.Constructor); public void OnConstructorClick() @@ -114,16 +106,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, customAttr.Constructor, protocol: "metadata")); } - public string ConstructorTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - customAttr.Constructor.WriteTo(module, output, context); - return output.ToString(); - } - } + string constructorTooltip; + public string ConstructorTooltip => GenerateTooltip(ref constructorTooltip, module, customAttr.Constructor); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Value => MetadataTokens.GetHeapOffset(customAttr.Value); public string ValueTooltip { @@ -139,6 +125,8 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.customAttr = metadata.GetCustomAttribute(handle); + this.parentTooltip = null; + this.constructorTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs b/ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs index bcfb719ad..601b7a8b1 100644 --- a/ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs @@ -88,8 +88,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.DeclSecurity) + metadata.GetTableRowSize(TableIndex.DeclSecurity) * (RID - 1); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(declSecAttr.Parent); public void OnParentClick() @@ -97,16 +96,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, declSecAttr.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - declSecAttr.Parent.WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, declSecAttr.Parent); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public DeclarativeSecurityAction Action => declSecAttr.Action; public string ActionTooltip { @@ -115,7 +108,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int PermissionSet => MetadataTokens.GetHeapOffset(declSecAttr.PermissionSet); public string PermissionSetTooltip { @@ -131,6 +124,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.declSecAttr = metadata.GetDeclarativeSecurityAttribute(handle); + this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs b/ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs index d25738f72..ae0833708 100644 --- a/ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs @@ -98,8 +98,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(eventMap.Parent); public void OnParentClick() @@ -107,17 +106,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, eventMap.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)eventMap.Parent).WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, eventMap.Parent); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int EventList => MetadataTokens.GetToken(eventMap.EventList); public void OnEventListClick() @@ -125,14 +117,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, eventMap.EventList, protocol: "metadata")); } - public string EventListTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)eventMap.EventList).WriteTo(module, output, context); - return output.ToString(); - } - } + string eventListTooltip; + public string EventListTooltip => GenerateTooltip(ref eventListTooltip, module, eventMap.EventList); public EventMapEntry(PEFile module, byte* ptr, int metadataOffset, int row) { @@ -145,6 +131,8 @@ namespace ICSharpCode.ILSpy.Metadata int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; int eventDefSize = metadata.GetTableRowCount(TableIndex.Event) < ushort.MaxValue ? 2 : 4; this.eventMap = new EventMap(ptr + rowOffset, typeDefSize, eventDefSize); + this.parentTooltip = null; + this.eventListTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/EventTableTreeNode.cs b/ILSpy/Metadata/CorTables/EventTableTreeNode.cs index 4ed3b9a84..b24f093dc 100644 --- a/ILSpy/Metadata/CorTables/EventTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/EventTableTreeNode.cs @@ -90,7 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.Event) + metadata.GetTableRowSize(TableIndex.Event) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public EventAttributes Attributes => eventDef.Attributes; public object AttributesTooltip => new FlagsTooltip { @@ -103,8 +103,7 @@ namespace ICSharpCode.ILSpy.Metadata IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Type => MetadataTokens.GetToken(eventDef.Type); public void OnTypeClick() @@ -112,13 +111,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, eventDef.Type, protocol: "metadata")); } - public string TypeTooltip { - get { - ITextOutput output = new PlainTextOutput(); - eventDef.Type.WriteTo(module, output, default); - return output.ToString(); - } - } + string typeTooltip; + public string TypeTooltip => GenerateTooltip(ref typeTooltip, module, eventDef.Type); public EventDefEntry(PEFile module, EventDefinitionHandle handle) { @@ -127,6 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.eventDef = metadata.GetEventDefinition(handle); + this.typeTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs b/ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs index fee2aff10..b95a5a9e8 100644 --- a/ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs @@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.ExportedType) + metadata.GetTableRowSize(TableIndex.ExportedType) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public TypeAttributes Attributes => type.Attributes; const TypeAttributes otherFlagsMask = ~(TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.ClassSemanticsMask | TypeAttributes.StringFormatMask | TypeAttributes.CustomFormatMask); @@ -110,8 +110,7 @@ namespace ICSharpCode.ILSpy.Metadata public string TypeNamespace => metadata.GetString(type.Namespace); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Implementation => MetadataTokens.GetToken(type.Implementation); public void OnImplementationClick() @@ -119,16 +118,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, type.Implementation, protocol: "metadata")); } - public string ImplementationTooltip { - get { - if (type.Implementation.IsNil) - return null; - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - type.Implementation.WriteTo(module, output, context); - return output.ToString(); - } - } + string implementationTooltip; + public string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, module, type.Implementation); public ExportedTypeEntry(int metadataOffset, PEFile module, ExportedTypeHandle handle, ExportedType type) { @@ -137,6 +128,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.type = type; + this.implementationTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs index d959a49b6..8a80966b0 100644 --- a/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs @@ -98,8 +98,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Field => MetadataTokens.GetToken(fieldLayout.Field); public void OnFieldClick() @@ -107,16 +106,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, fieldLayout.Field, protocol: "metadata")); } - public string FieldTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)fieldLayout.Field).WriteTo(module, output, context); - return output.ToString(); - } - } + string fieldTooltip; + public string FieldTooltip => GenerateTooltip(ref fieldTooltip, module, fieldLayout.Field); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public int FieldOffset => fieldLayout.Offset; public FieldLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row) @@ -129,6 +122,7 @@ namespace ICSharpCode.ILSpy.Metadata this.Offset = metadataOffset + rowOffset; int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4; this.fieldLayout = new FieldLayout(ptr + rowOffset, fieldDefSize); + this.fieldTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs index a4d74b9bc..a9f26ff13 100644 --- a/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs @@ -98,8 +98,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(fieldMarshal.Parent); public void OnParentClick() @@ -107,16 +106,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, fieldMarshal.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)fieldMarshal.Parent).WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, fieldMarshal.Parent); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int NativeType => MetadataTokens.GetHeapOffset(fieldMarshal.NativeType); public FieldMarshalEntry(PEFile module, byte* ptr, int metadataOffset, int row) @@ -130,6 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata int hasFieldMarshalRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param); int blobHeapSize = metadata.GetHeapSize(HeapIndex.Blob) < ushort.MaxValue ? 2 : 4; this.fieldMarshal = new FieldMarshal(ptr + rowOffset, blobHeapSize, hasFieldMarshalRefSize); + this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs index c0d54a023..9317bb336 100644 --- a/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs @@ -90,7 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata { readonly PEFile module; readonly MetadataReader metadata; - readonly FieldRVA fieldLayout; + readonly FieldRVA fieldRVA; public int RID { get; } @@ -98,26 +98,19 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] - public int Field => MetadataTokens.GetToken(fieldLayout.Field); + [ColumnInfo("X8", Kind = ColumnKind.Token)] + public int Field => MetadataTokens.GetToken(fieldRVA.Field); public void OnFieldClick() { - MainWindow.Instance.JumpToReference(new EntityReference(module, fieldLayout.Field, protocol: "metadata")); + MainWindow.Instance.JumpToReference(new EntityReference(module, fieldRVA.Field, protocol: "metadata")); } - public string FieldTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)fieldLayout.Field).WriteTo(module, output, context); - return output.ToString(); - } - } + string fieldTooltip; + public string FieldTooltip => GenerateTooltip(ref fieldTooltip, module, fieldRVA.Field); - [StringFormat("X")] - public int FieldOffset => fieldLayout.Offset; + [ColumnInfo("X8", Kind = ColumnKind.Other)] + public int FieldOffset => fieldRVA.Offset; public FieldRVAEntry(PEFile module, byte* ptr, int metadataOffset, int row) { @@ -128,7 +121,8 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1); this.Offset = metadataOffset + rowOffset; int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4; - this.fieldLayout = new FieldRVA(ptr + rowOffset, fieldDefSize); + this.fieldRVA = new FieldRVA(ptr + rowOffset, fieldDefSize); + this.fieldTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs index bdc927b28..f03666168 100644 --- a/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs @@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.Field) + metadata.GetTableRowSize(TableIndex.Field) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public FieldAttributes Attributes => fieldDef.Attributes; const FieldAttributes otherFlagsMask = ~(FieldAttributes.FieldAccessMask); @@ -110,17 +110,11 @@ namespace ICSharpCode.ILSpy.Metadata IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(fieldDef.Signature); - public string SignatureTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)handle).WriteTo(module, output, context); - return output.ToString(); - } - } + string signatureTooltip; + public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public FieldDefEntry(PEFile module, FieldDefinitionHandle handle) { @@ -129,6 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.fieldDef = metadata.GetFieldDefinition(handle); + this.signatureTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/FileTableTreeNode.cs b/ILSpy/Metadata/CorTables/FileTableTreeNode.cs index c48b8890b..ddf0e5189 100644 --- a/ILSpy/Metadata/CorTables/FileTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FileTableTreeNode.cs @@ -85,7 +85,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.File) + metadata.GetTableRowSize(TableIndex.File) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public int Attributes => assemblyFile.ContainsMetadata ? 1 : 0; public string AttributesTooltip => assemblyFile.ContainsMetadata ? "ContainsMetaData" : "ContainsNoMetaData"; @@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(assemblyFile.Name):X} \"{Name}\""; - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int HashValue => MetadataTokens.GetHeapOffset(assemblyFile.HashValue); public string HashValueTooltip { diff --git a/ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs b/ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs index 760cb2df1..1f97fdce6 100644 --- a/ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs @@ -86,8 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.GenericParamConstraint) + metadata.GetTableRowSize(TableIndex.GenericParamConstraint) * (RID - 1); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Owner => MetadataTokens.GetToken(genericParamConstraint.Parameter); public void OnOwnerClick() @@ -111,8 +110,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Type => MetadataTokens.GetToken(genericParamConstraint.Type); public void OnTypeClick() @@ -120,13 +118,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, genericParamConstraint.Type, protocol: "metadata")); } - public string TypeTooltip { - get { - ITextOutput output = new PlainTextOutput(); - genericParamConstraint.Type.WriteTo(module, output, default); - return output.ToString(); - } - } + string typeTooltip; + public string TypeTooltip => GenerateTooltip(ref typeTooltip, module, genericParamConstraint.Type); public GenericParamConstraintEntry(PEFile module, GenericParameterConstraintHandle handle) { @@ -136,6 +129,7 @@ namespace ICSharpCode.ILSpy.Metadata this.handle = handle; this.genericParamConstraint = metadata.GetGenericParameterConstraint(handle); this.ownerTooltip = null; + this.typeTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs b/ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs index 5bb682d2b..789670a59 100644 --- a/ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs @@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Number => genericParam.Index; - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public GenericParameterAttributes Attributes => genericParam.Attributes; public object AttributesTooltip => new FlagsTooltip { @@ -96,22 +96,16 @@ namespace ICSharpCode.ILSpy.Metadata FlagGroup.CreateSingleChoiceGroup(typeof(GenericParameterAttributes), "Managed type: ", (int)GenericParameterAttributes.SpecialConstraintMask, (int)(genericParam.Attributes & GenericParameterAttributes.SpecialConstraintMask), new Flag("None (0000)", 0, false), includeAny: false), }; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Owner => MetadataTokens.GetToken(genericParam.Parent); - public void OnParentClick() + public void OnOwnerClick() { MainWindow.Instance.JumpToReference(new EntityReference(module, genericParam.Parent, protocol: "metadata")); } - public string OwnerTooltip { - get { - ITextOutput output = new PlainTextOutput(); - genericParam.Parent.WriteTo(module, output, default); - return output.ToString(); - } - } + string ownerTooltip; + public string OwnerTooltip => GenerateTooltip(ref ownerTooltip, module, genericParam.Parent); public string Name => metadata.GetString(genericParam.Name); @@ -124,6 +118,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.genericParam = metadata.GetGenericParameter(handle); + this.ownerTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs b/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs index ccfd7801b..c6c228ba6 100644 --- a/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs @@ -104,7 +104,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public PInvokeAttributes MappingFlags => implMap.MappingFlags; const PInvokeAttributes otherFlagsMask = ~(PInvokeAttributes.CallConvMask | PInvokeAttributes.CharSetMask); @@ -115,8 +115,7 @@ namespace ICSharpCode.ILSpy.Metadata FlagGroup.CreateMultipleChoiceGroup(typeof(PInvokeAttributes), "Flags:", (int)otherFlagsMask, (int)(implMap.MappingFlags & otherFlagsMask), includeAll: false), }; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int MemberForwarded => MetadataTokens.GetToken(implMap.MemberForwarded); public void OnMemberForwardedClick() @@ -124,17 +123,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, implMap.MemberForwarded, protocol: "metadata")); } - public string MemberForwardedTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)implMap.MemberForwarded).WriteTo(module, output, context); - return output.ToString(); - } - } + string memberForwardedTooltip; + public string MemberForwardedTooltip => GenerateTooltip(ref memberForwardedTooltip, module, implMap.MemberForwarded); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int ImportScope => MetadataTokens.GetToken(implMap.ImportScope); public void OnImportScopeClick() @@ -142,14 +134,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, implMap.ImportScope, protocol: "metadata")); } - public string ImportScopeTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)implMap.ImportScope).WriteTo(module, output, context); - return output.ToString(); - } - } + string importScopeTooltip; + public string ImportScopeTooltip => GenerateTooltip(ref importScopeTooltip, module, implMap.ImportScope); public string ImportName => metadata.GetString(implMap.ImportName); @@ -167,6 +153,8 @@ namespace ICSharpCode.ILSpy.Metadata int memberForwardedTagRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field); int stringHandleSize = metadata.GetHeapSize(HeapIndex.String) < ushort.MaxValue ? 2 : 4; this.implMap = new ImplMap(ptr + rowOffset, moduleRefSize, memberForwardedTagRefSize, stringHandleSize); + this.importScopeTooltip = null; + this.memberForwardedTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs b/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs index 6f5090032..35c66ab85 100644 --- a/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs @@ -98,8 +98,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Class => MetadataTokens.GetToken(interfaceImpl.Class); public void OnClassClick() @@ -107,17 +106,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, interfaceImpl.Class, protocol: "metadata")); } - public string ClassTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)interfaceImpl.Class).WriteTo(module, output, context); - return output.ToString(); - } - } + string classTooltip; + public string ClassTooltip => GenerateTooltip(ref classTooltip, module, interfaceImpl.Class); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Interface => MetadataTokens.GetToken(interfaceImpl.Interface); public void OnInterfaceClick() @@ -125,14 +117,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, interfaceImpl.Interface, protocol: "metadata")); } - public string InterfaceTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)interfaceImpl.Interface).WriteTo(module, output, context); - return output.ToString(); - } - } + string interfaceTooltip; + public string InterfaceTooltip => GenerateTooltip(ref interfaceTooltip, module, interfaceImpl.Interface); public InterfaceImplEntry(PEFile module, byte* ptr, int metadataOffset, int row) { @@ -143,6 +129,8 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableRowSize(TableIndex.InterfaceImpl) * (row - 1); this.Offset = metadataOffset + rowOffset; this.interfaceImpl = new InterfaceImpl(ptr + rowOffset, metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec)); + this.interfaceTooltip = null; + this.classTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs b/ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs index e720ee1c1..79fd5b76b 100644 --- a/ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs @@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.ManifestResource) + metadata.GetTableRowSize(TableIndex.ManifestResource) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public ManifestResourceAttributes Attributes => manifestResource.Attributes; public object AttributesTooltip => manifestResource.Attributes.ToString(); @@ -97,8 +97,7 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(manifestResource.Name):X} \"{Name}\""; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Implementation => MetadataTokens.GetToken(manifestResource.Implementation); public void OnImplementationClick() @@ -106,16 +105,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, manifestResource.Implementation, protocol: "metadata")); } - public string ImplementationTooltip { - get { - if (manifestResource.Implementation.IsNil) - return null; - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - manifestResource.Implementation.WriteTo(module, output, context); - return output.ToString(); - } - } + string implementationTooltip; + public string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, module, manifestResource.Implementation); public ManifestResourceEntry(PEFile module, ManifestResourceHandle handle) { @@ -124,6 +115,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.manifestResource = metadata.GetManifestResource(handle); + this.implementationTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs b/ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs index 5c4987846..01e7806dc 100644 --- a/ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs @@ -87,8 +87,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.MemberRef) + metadata.GetTableRowSize(TableIndex.MemberRef) * (RID - 1); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(memberRef.Parent); public void OnParentClick() @@ -96,29 +95,18 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, memberRef.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - memberRef.Parent.WriteTo(module, output, default); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, memberRef.Parent); public string Name => metadata.GetString(memberRef.Name); public string NameTooltip => $"{MetadataTokens.GetHeapOffset(memberRef.Name):X} \"{Name}\""; - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(memberRef.Signature); - public string SignatureTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)handle).WriteTo(module, output, context); - return output.ToString(); - } - } + string signatureTooltip; + public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public MemberRefEntry(PEFile module, MemberReferenceHandle handle) { @@ -127,6 +115,8 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.memberRef = metadata.GetMemberReference(handle); + this.signatureTooltip = null; + this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs b/ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs index bd7292df8..24b93afd0 100644 --- a/ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs @@ -86,8 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.MethodDef) + metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int MethodDeclaration => MetadataTokens.GetToken(methodImpl.MethodDeclaration); public void OnMethodDeclarationClick() @@ -95,16 +94,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, methodImpl.MethodDeclaration, protocol: "metadata")); } - public string MethodDeclarationTooltip { - get { - ITextOutput output = new PlainTextOutput(); - methodImpl.MethodDeclaration.WriteTo(module, output, default); - return output.ToString(); - } - } + string methodDeclarationTooltip; + public string MethodDeclarationTooltip => GenerateTooltip(ref methodDeclarationTooltip, module, methodImpl.MethodDeclaration); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int MethodBody => MetadataTokens.GetToken(methodImpl.MethodBody); public void OnMethodBodyClick() @@ -112,16 +105,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, methodImpl.MethodBody, protocol: "metadata")); } - public string MethodBodyTooltip { - get { - ITextOutput output = new PlainTextOutput(); - methodImpl.MethodBody.WriteTo(module, output, default); - return output.ToString(); - } - } + string methodBodyTooltip; + public string MethodBodyTooltip => GenerateTooltip(ref methodBodyTooltip, module, methodImpl.MethodBody); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Type => MetadataTokens.GetToken(methodImpl.Type); public void OnTypeClick() @@ -129,13 +116,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, methodImpl.Type, protocol: "metadata")); } - public string TypeTooltip { - get { - ITextOutput output = new PlainTextOutput(); - ((EntityHandle)methodImpl.Type).WriteTo(module, output, default); - return output.ToString(); - } - } + string typeTooltip; + public string TypeTooltip => GenerateTooltip(ref typeTooltip, module, methodImpl.Type); public MethodImplEntry(PEFile module, MethodImplementationHandle handle) { @@ -144,6 +126,9 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.methodImpl = metadata.GetMethodImplementation(handle); + this.typeTooltip = null; + this.methodBodyTooltip = null; + this.methodDeclarationTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs b/ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs index 73316effc..3f3ab38df 100644 --- a/ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs @@ -90,13 +90,12 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.MethodDef) + metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public MethodSemanticsAttributes Semantics => semantics; public string SemanticsTooltip => semantics.ToString(); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Method => MetadataTokens.GetToken(method); public void OnMethodClick() @@ -104,16 +103,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, method, protocol: "metadata")); } - public string MethodTooltip { - get { - ITextOutput output = new PlainTextOutput(); - ((EntityHandle)method).WriteTo(module, output, default); - return output.ToString(); - } - } + string methodTooltip; + public string MethodTooltip => GenerateTooltip(ref methodTooltip, module, method); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Association => MetadataTokens.GetToken(association); public void OnAssociationClick() @@ -121,13 +114,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, association, protocol: "metadata")); } - public string AssociationTooltip { - get { - ITextOutput output = new PlainTextOutput(); - association.WriteTo(module, output, default); - return output.ToString(); - } - } + string associationTooltip; + public string AssociationTooltip => GenerateTooltip(ref associationTooltip, module, association); public MethodSemanticsEntry(PEFile module, Handle handle, MethodSemanticsAttributes semantics, MethodDefinitionHandle method, EntityHandle association) { @@ -138,6 +126,8 @@ namespace ICSharpCode.ILSpy.Metadata this.semantics = semantics; this.method = method; this.association = association; + this.methodTooltip = null; + this.associationTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs b/ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs index 702f66594..c050dbc58 100644 --- a/ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs @@ -87,8 +87,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.MethodSpec) + metadata.GetTableRowSize(TableIndex.MethodSpec) * (RID - 1); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Method => MetadataTokens.GetToken(methodSpec.Method); public void OnMethodClick() @@ -96,15 +95,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, methodSpec.Method, protocol: "metadata")); } - public string MethodTooltip { - get { - ITextOutput output = new PlainTextOutput(); - methodSpec.Method.WriteTo(module, output, default); - return output.ToString(); - } - } + string methodTooltip; + public string MethodTooltip => GenerateTooltip(ref methodTooltip, module, methodSpec.Method); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(methodSpec.Signature); public string SignatureTooltip { @@ -131,6 +125,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.methodSpec = metadata.GetMethodSpecification(handle); + this.methodTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs b/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs index c1b1160f2..46f81cde4 100644 --- a/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs @@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.MethodDef) + metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public MethodAttributes Attributes => methodDef.Attributes; const MethodAttributes otherFlagsMask = ~(MethodAttributes.MemberAccessMask | MethodAttributes.VtableLayoutMask); @@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.Metadata FlagGroup.CreateMultipleChoiceGroup(typeof(MethodAttributes), "Flags:", (int)otherFlagsMask, (int)(methodDef.Attributes & otherFlagsMask), includeAll: false), }; - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public MethodImplAttributes ImplAttributes => methodDef.ImplAttributes; public object ImplAttributesTooltip => new FlagsTooltip { @@ -117,23 +117,12 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(methodDef.Name):X} \"{Name}\""; - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(methodDef.Signature); string signatureTooltip; - public string SignatureTooltip { - get { - if (signatureTooltip == null) - { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)handle).WriteTo(module, output, context); - signatureTooltip = output.ToString(); - } - return signatureTooltip; - } - } + public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); diff --git a/ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs b/ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs index b86387ecd..ba6509426 100644 --- a/ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs @@ -82,17 +82,17 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(moduleDef.Name):X} \"{Name}\""; - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Mvid => MetadataTokens.GetHeapOffset(moduleDef.Mvid); public string MvidTooltip => metadata.GetGuid(moduleDef.Mvid).ToString(); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int GenerationId => MetadataTokens.GetHeapOffset(moduleDef.GenerationId); public string GenerationIdTooltip => moduleDef.GenerationId.IsNil ? null : metadata.GetGuid(moduleDef.GenerationId).ToString(); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int BaseGenerationId => MetadataTokens.GetHeapOffset(moduleDef.BaseGenerationId); public string BaseGenerationIdTooltip => moduleDef.BaseGenerationId.IsNil ? null : metadata.GetGuid(moduleDef.BaseGenerationId).ToString(); diff --git a/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs b/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs index d9560ab7e..de347fd33 100644 --- a/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs @@ -98,8 +98,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int NestedClass => MetadataTokens.GetToken(nestedClass.Nested); public void OnNestedClassClick() @@ -107,17 +106,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, nestedClass.Nested, protocol: "metadata")); } - public string NestedClassTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)nestedClass.Nested).WriteTo(module, output, context); - return output.ToString(); - } - } + string nestedClassTooltip; + public string NestedClassTooltip => GenerateTooltip(ref nestedClassTooltip, module, nestedClass.Nested); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int EnclosingClass => MetadataTokens.GetToken(nestedClass.Enclosing); public void OnEnclosingClassClick() @@ -125,14 +117,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, nestedClass.Enclosing, protocol: "metadata")); } - public string EnclosingClassTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)nestedClass.Enclosing).WriteTo(module, output, context); - return output.ToString(); - } - } + string enclosingClassTooltip; + public string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, module, nestedClass.Enclosing); public unsafe NestedClassEntry(PEFile module, byte* ptr, int metadataOffset, int row) { @@ -144,6 +130,8 @@ namespace ICSharpCode.ILSpy.Metadata this.Offset = metadataOffset + rowOffset; int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; this.nestedClass = new NestedClass(ptr + rowOffset, typeDefSize); + this.nestedClassTooltip = null; + this.enclosingClassTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/ParamTableTreeNode.cs b/ILSpy/Metadata/CorTables/ParamTableTreeNode.cs index 5aea6118d..5fee320ee 100644 --- a/ILSpy/Metadata/CorTables/ParamTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/ParamTableTreeNode.cs @@ -85,7 +85,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.Param) + metadata.GetTableRowSize(TableIndex.Param) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public ParameterAttributes Attributes => param.Attributes; public object AttributesTooltip => new FlagsTooltip { diff --git a/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs b/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs index c4291171f..64d9bb19a 100644 --- a/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs @@ -98,8 +98,7 @@ namespace ICSharpCode.ILSpy.Metadata public int Offset { get; } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(propertyMap.Parent); public void OnParentClick() @@ -107,17 +106,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, propertyMap.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)propertyMap.Parent).WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, propertyMap.Parent); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int PropertyList => MetadataTokens.GetToken(propertyMap.PropertyList); public void OnPropertyListClick() @@ -125,14 +117,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, propertyMap.PropertyList, protocol: "metadata")); } - public string PropertyListTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)propertyMap.PropertyList).WriteTo(module, output, context); - return output.ToString(); - } - } + string propertyListTooltip; + public string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, module, propertyMap.PropertyList); public PropertyMapEntry(PEFile module, byte* ptr, int metadataOffset, int row) { @@ -145,6 +131,8 @@ namespace ICSharpCode.ILSpy.Metadata int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4; int propertyDefSize = metadata.GetTableRowCount(TableIndex.Property) < ushort.MaxValue ? 2 : 4; this.propertyMap = new PropertyMap(ptr + rowOffset, typeDefSize, propertyDefSize); + this.propertyListTooltip = null; + this.parentTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs b/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs index 39c380806..8240c2ac5 100644 --- a/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs @@ -90,7 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.Property) + metadata.GetTableRowSize(TableIndex.Property) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public PropertyAttributes Attributes => propertyDef.Attributes; public object AttributesTooltip => new FlagsTooltip { @@ -103,16 +103,11 @@ namespace ICSharpCode.ILSpy.Metadata IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(propertyDef.Signature); - public string SignatureTooltip { - get { - ITextOutput output = new PlainTextOutput(); - ((EntityHandle)handle).WriteTo(module, output, default); - return output.ToString(); - } - } + string signatureTooltip; + public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public PropertyDefEntry(PEFile module, PropertyDefinitionHandle handle) { @@ -121,6 +116,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.propertyDef = metadata.GetPropertyDefinition(handle); + this.signatureTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs b/ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs index ff6fbfb76..0e618aad2 100644 --- a/ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs @@ -86,17 +86,11 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.StandAloneSig) + metadata.GetTableRowSize(TableIndex.StandAloneSig) * (RID - 1); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(standaloneSig.Signature); - public string SignatureTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)handle).WriteTo(module, output, context); - return output.ToString(); - } - } + string signatureTooltip; + public string SignatureTooltip => GenerateTooltip(ref signatureTooltip, module, handle); public StandAloneSigEntry(PEFile module, StandaloneSignatureHandle handle) { @@ -105,6 +99,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.standaloneSig = metadata.GetStandaloneSignature(handle); + this.signatureTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs b/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs index 078d8afb0..3388a244a 100644 --- a/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs @@ -91,7 +91,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.TypeDef) + metadata.GetTableRowSize(TableIndex.TypeDef) * (RID - 1); - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public TypeAttributes Attributes => typeDef.Attributes; const TypeAttributes otherFlagsMask = ~(TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.ClassSemanticsMask | TypeAttributes.StringFormatMask | TypeAttributes.CustomFormatMask); @@ -113,8 +113,7 @@ namespace ICSharpCode.ILSpy.Metadata public string Namespace => metadata.GetString(typeDef.Namespace); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int BaseType => MetadataTokens.GetToken(typeDef.BaseType); public void OnBaseTypeClick() @@ -145,8 +144,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int FieldList => MetadataTokens.GetToken(typeDef.GetFields().FirstOrDefault()); public void OnFieldListClick() @@ -154,20 +152,17 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, typeDef.GetFields().FirstOrDefault(), protocol: "metadata")); } + string fieldListTooltip; public string FieldListTooltip { get { var field = typeDef.GetFields().FirstOrDefault(); if (field.IsNil) return null; - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)field).WriteTo(module, output, context); - return output.ToString(); + return GenerateTooltip(ref fieldListTooltip, module, field); } } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int MethodList => MetadataTokens.GetToken(typeDef.GetMethods().FirstOrDefault()); public void OnMethodListClick() @@ -175,15 +170,13 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, typeDef.GetMethods().FirstOrDefault(), protocol: "metadata")); } + string methodListTooltip; public string MethodListTooltip { get { var method = typeDef.GetMethods().FirstOrDefault(); if (method.IsNil) return null; - ITextOutput output = new PlainTextOutput(); - var context = new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)method).WriteTo(module, output, context); - return output.ToString(); + return GenerateTooltip(ref methodListTooltip, module, method); } } @@ -196,6 +189,8 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.typeDef = metadata.GetTypeDefinition(handle); + this.methodListTooltip = null; + this.fieldListTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs b/ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs index 24db219f9..f0a773dc3 100644 --- a/ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs @@ -86,8 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.TypeRef) + metadata.GetTableRowSize(TableIndex.TypeRef) * (RID - 1); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int ResolutionScope => MetadataTokens.GetToken(typeRef.ResolutionScope); public void OnResolutionScopeClick() @@ -95,31 +94,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, typeRef.ResolutionScope, protocol: "metadata")); } - public string ResolutionScopeTooltip { - get { - if (typeRef.ResolutionScope.IsNil) - return null; - var output = new PlainTextOutput(); - switch (typeRef.ResolutionScope.Kind) - { - case HandleKind.ModuleDefinition: - output.Write(metadata.GetString(metadata.GetModuleDefinition().Name)); - break; - case HandleKind.ModuleReference: - ModuleReference moduleReference = metadata.GetModuleReference((ModuleReferenceHandle)typeRef.ResolutionScope); - output.Write(metadata.GetString(moduleReference.Name)); - break; - case HandleKind.AssemblyReference: - var asmRef = new Decompiler.Metadata.AssemblyReference(module, (AssemblyReferenceHandle)typeRef.ResolutionScope); - output.Write(asmRef.ToString()); - break; - default: - typeRef.ResolutionScope.WriteTo(module, output, default); - break; - } - return output.ToString(); - } - } + string resolutionScopeTooltip; + public string ResolutionScopeTooltip => GenerateTooltip(ref resolutionScopeTooltip, module, typeRef.ResolutionScope); public string NameTooltip => $"{MetadataTokens.GetHeapOffset(typeRef.Name):X} \"{Name}\""; @@ -136,6 +112,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = module.Metadata; this.handle = handle; this.typeRef = metadata.GetTypeReference(handle); + this.resolutionScopeTooltip = null; } } diff --git a/ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs b/ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs index 1d19874e5..5b87adaa1 100644 --- a/ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs @@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy.Metadata + metadata.GetTableMetadataOffset(TableIndex.TypeSpec) + metadata.GetTableRowSize(TableIndex.TypeSpec) * (RID - 1); - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(typeSpec.Signature); public string SignatureTooltip { diff --git a/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs b/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs index f3e191de6..9e9d46c61 100644 --- a/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs @@ -120,6 +120,7 @@ namespace ICSharpCode.ILSpy.Metadata DefaultNamespaces, EditAndContinueLocalSlotMap, EditAndContinueLambdaAndClosureMap, + EncStateMachineStateMap, EmbeddedSource, SourceLink, MethodSteppingInformation, @@ -154,6 +155,10 @@ namespace ICSharpCode.ILSpy.Metadata { return CustomDebugInformationKind.EditAndContinueLambdaAndClosureMap; } + if (KnownGuids.EncStateMachineStateMap == guid) + { + return CustomDebugInformationKind.EncStateMachineStateMap; + } if (KnownGuids.EmbeddedSource == guid) { return CustomDebugInformationKind.EmbeddedSource; @@ -192,8 +197,7 @@ namespace ICSharpCode.ILSpy.Metadata public object Offset => offset == null ? "n/a" : (object)offset; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(debugInfo.Parent); public void OnParentClick() @@ -201,17 +205,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, debugInfo.Parent, protocol: "metadata")); } - public string ParentTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - debugInfo.Parent.WriteTo(module, output, context); - return output.ToString(); - } - } + string parentTooltip; + public string ParentTooltip => GenerateTooltip(ref parentTooltip, module, debugInfo.Parent); string kindString; - public string Kind { get { if (kindString != null) @@ -226,57 +223,28 @@ namespace ICSharpCode.ILSpy.Metadata { guid = Guid.Empty; } - switch (kind) - { - case CustomDebugInformationKind.None: - kindString = ""; - break; - case CustomDebugInformationKind.StateMachineHoistedLocalScopes: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - State Machine Hoisted Local Scopes (C# / VB) [{guid}]"; - break; - case CustomDebugInformationKind.DynamicLocalVariables: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Dynamic Local Variables (C#) [{guid}]"; - break; - case CustomDebugInformationKind.DefaultNamespaces: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Default Namespaces (VB) [{guid}]"; - break; - case CustomDebugInformationKind.EditAndContinueLocalSlotMap: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Local Slot Map (C# / VB) [{guid}]"; - break; - case CustomDebugInformationKind.EditAndContinueLambdaAndClosureMap: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Lambda And Closure Map (C# / VB) [{guid}]"; - break; - case CustomDebugInformationKind.EmbeddedSource: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Embedded Source (C# / VB) [{guid}]"; - break; - case CustomDebugInformationKind.SourceLink: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Source Link (C# / VB) [{guid}]"; - break; - case CustomDebugInformationKind.MethodSteppingInformation: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Method Stepping Information (C# / VB) [{guid}]"; - break; - case CustomDebugInformationKind.CompilationOptions: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Options (C# / VB) [{ guid}]"; - break; - case CustomDebugInformationKind.CompilationMetadataReferences: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Metadata References (C# / VB) [{ guid}]"; - break; - case CustomDebugInformationKind.TupleElementNames: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Tuple Element Names (C#) [{ guid}]"; - break; - case CustomDebugInformationKind.TypeDefinitionDocuments: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Type Definition Documents (C# / VB) [{ guid}]"; - break; - default: - kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Unknown [{guid}]"; - break; - } - + kindString = kind switch { + CustomDebugInformationKind.None => "", + CustomDebugInformationKind.StateMachineHoistedLocalScopes => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - State Machine Hoisted Local Scopes (C# / VB) [{guid}]", + CustomDebugInformationKind.DynamicLocalVariables => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Dynamic Local Variables (C#) [{guid}]", + CustomDebugInformationKind.DefaultNamespaces => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Default Namespaces (VB) [{guid}]", + CustomDebugInformationKind.EditAndContinueLocalSlotMap => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Local Slot Map (C# / VB) [{guid}]", + CustomDebugInformationKind.EditAndContinueLambdaAndClosureMap => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Lambda And Closure Map (C# / VB) [{guid}]", + CustomDebugInformationKind.EncStateMachineStateMap => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue State Machine State Map (C# / VB) [{guid}]", + CustomDebugInformationKind.EmbeddedSource => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Embedded Source (C# / VB) [{guid}]", + CustomDebugInformationKind.SourceLink => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Source Link (C# / VB) [{guid}]", + CustomDebugInformationKind.MethodSteppingInformation => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Method Stepping Information (C# / VB) [{guid}]", + CustomDebugInformationKind.CompilationOptions => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Options (C# / VB) [{guid}]", + CustomDebugInformationKind.CompilationMetadataReferences => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Metadata References (C# / VB) [{guid}]", + CustomDebugInformationKind.TupleElementNames => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Tuple Element Names (C#) [{guid}]", + CustomDebugInformationKind.TypeDefinitionDocuments => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Type Definition Documents (C# / VB) [{guid}]", + _ => $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Unknown [{guid}]", + }; return kindString; } } - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Value => MetadataTokens.GetHeapOffset(debugInfo.Value); public string ValueTooltip { diff --git a/ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs b/ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs index c3cef36da..2a7fdb8e4 100644 --- a/ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs @@ -90,7 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(document.Name):X} \"{Name}\""; - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int HashAlgorithm => MetadataTokens.GetHeapOffset(document.HashAlgorithm); public string HashAlgorithmTooltip { @@ -106,7 +106,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Hash => MetadataTokens.GetHeapOffset(document.Hash); public string HashTooltip { @@ -118,7 +118,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Language => MetadataTokens.GetHeapOffset(document.Language); public string LanguageTooltip { diff --git a/ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs b/ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs index e7841965d..0e6ee99d0 100644 --- a/ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs @@ -90,8 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata public object Offset => offset == null ? "n/a" : (object)offset; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Parent => MetadataTokens.GetToken(localScope.Parent); public void OnParentClick() @@ -99,7 +98,7 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.Parent, protocol: "metadata")); } - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Imports => MetadataTokens.GetHeapOffset(localScope.ImportsBlob); public ImportScopeEntry(PEFile module, MetadataReader metadata, bool isEmbedded, ImportScopeHandle handle) diff --git a/ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs b/ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs index 2a095fee4..9eaf8be2a 100644 --- a/ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs @@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(localConst.Name):X} \"{Name}\""; - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(localConst.Signature); public LocalConstantEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalConstantHandle handle) diff --git a/ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs b/ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs index 546e5c395..8b8ac8b1a 100644 --- a/ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs @@ -90,8 +90,7 @@ namespace ICSharpCode.ILSpy.Metadata public object Offset => offset == null ? "n/a" : (object)offset; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Method => MetadataTokens.GetToken(localScope.Method); public void OnMethodClick() @@ -99,16 +98,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.Method, protocol: "metadata")); } - public string MethodTooltip { - get { - ITextOutput output = new PlainTextOutput(); - ((EntityHandle)localScope.Method).WriteTo(module, output, default); - return output.ToString(); - } - } + string methodTooltip; + public string MethodTooltip => GenerateTooltip(ref methodTooltip, module, localScope.Method); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int ImportScope => MetadataTokens.GetToken(localScope.ImportScope); public void OnImportScopeClick() @@ -116,8 +109,7 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.ImportScope, protocol: "metadata")); } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int VariableList => MetadataTokens.GetToken(localScope.GetLocalVariables().FirstOrDefault()); public void OnVariableListClick() @@ -125,8 +117,7 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, localScope.GetLocalVariables().FirstOrDefault(), protocol: "metadata")); } - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int ConstantList => MetadataTokens.GetToken(localScope.GetLocalConstants().FirstOrDefault()); public void OnConstantListClick() @@ -146,6 +137,7 @@ namespace ICSharpCode.ILSpy.Metadata this.metadata = metadata; this.handle = handle; this.localScope = metadata.GetLocalScope(handle); + this.methodTooltip = null; } } diff --git a/ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs b/ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs index ed8744e2e..9913e1a6b 100644 --- a/ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs @@ -84,7 +84,7 @@ namespace ICSharpCode.ILSpy.Metadata public object Offset => offset == null ? "n/a" : (object)offset; - [StringFormat("X8")] + [ColumnInfo("X8", Kind = ColumnKind.Other)] public LocalVariableAttributes Attributes => localVar.Attributes; public object AttributesTooltip => new FlagsTooltip() { diff --git a/ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs b/ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs index 46dc93885..d439308e4 100644 --- a/ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs @@ -88,8 +88,7 @@ namespace ICSharpCode.ILSpy.Metadata public object Offset => offset == null ? "n/a" : (object)offset; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int Document => MetadataTokens.GetToken(debugInfo.Document); public void OnDocumentClick() @@ -106,7 +105,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - [StringFormat("X")] + [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int SequencePoints => MetadataTokens.GetHeapOffset(debugInfo.SequencePointsBlob); public string SequencePointsTooltip { @@ -122,8 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - [StringFormat("X")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int LocalSignature => MetadataTokens.GetToken(debugInfo.LocalSignature); public void OnLocalSignatureClick() diff --git a/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs b/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs index 5e30b145f..e93c0c3d9 100644 --- a/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs +++ b/ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs @@ -92,8 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata public object Offset => offset == null ? "n/a" : (object)offset; - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int MoveNextMethod => MetadataTokens.GetToken(moveNextMethod); public void OnMoveNextMethodClick() @@ -101,17 +100,10 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, moveNextMethod, protocol: "metadata")); } - public string MoveNextMethodTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)moveNextMethod).WriteTo(module, output, context); - return output.ToString(); - } - } + string moveNextMethodTooltip; + public string MoveNextMethodTooltip => GenerateTooltip(ref moveNextMethodTooltip, module, moveNextMethod); - [StringFormat("X8")] - [LinkToTable] + [ColumnInfo("X8", Kind = ColumnKind.Token)] public int KickoffMethod => MetadataTokens.GetToken(kickoffMethod); public void OnKickofMethodClick() @@ -119,14 +111,8 @@ namespace ICSharpCode.ILSpy.Metadata MainWindow.Instance.JumpToReference(new EntityReference(module, kickoffMethod, protocol: "metadata")); } - public string KickoffMethodTooltip { - get { - ITextOutput output = new PlainTextOutput(); - var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); - ((EntityHandle)kickoffMethod).WriteTo(module, output, context); - return output.ToString(); - } - } + string kickoffMethodTooltip; + public string KickoffMethodTooltip => GenerateTooltip(ref kickoffMethodTooltip, module, kickoffMethod); public StateMachineMethodEntry(PEFile module, ref BlobReader reader, bool isEmbedded, int row) { @@ -140,6 +126,8 @@ namespace ICSharpCode.ILSpy.Metadata int methodDefSize = metadata.GetTableRowCount(TableIndex.MethodDef) < ushort.MaxValue ? 2 : 4; this.moveNextMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32()); this.kickoffMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32()); + this.kickoffMethodTooltip = null; + this.moveNextMethodTooltip = null; } } diff --git a/ILSpy/Metadata/GoToTokenCommand.cs b/ILSpy/Metadata/GoToTokenCommand.cs index b35db7d08..d8963ce60 100644 --- a/ILSpy/Metadata/GoToTokenCommand.cs +++ b/ILSpy/Metadata/GoToTokenCommand.cs @@ -60,7 +60,7 @@ namespace ICSharpCode.ILSpy.Commands Type type = cell.Item.GetType(); var property = type.GetProperty(cell.Column.Header.ToString()); var moduleField = type.GetField("module", BindingFlags.NonPublic | BindingFlags.Instance); - if (property == null || property.PropertyType != typeof(int) || !property.GetCustomAttributes(false).Any(a => a is StringFormatAttribute sf && sf.Format == "X8")) + if (property == null || property.PropertyType != typeof(int) || !property.GetCustomAttributes(false).Any(a => a is ColumnInfoAttribute { Kind: ColumnKind.Token } c)) return null; module = (PEFile)moduleField.GetValue(cell.Item); return (int)property.GetValue(cell.Item); diff --git a/ILSpy/Metadata/Helpers.cs b/ILSpy/Metadata/Helpers.cs index cd6558a17..da418b554 100644 --- a/ILSpy/Metadata/Helpers.cs +++ b/ILSpy/Metadata/Helpers.cs @@ -143,7 +143,7 @@ namespace ICSharpCode.ILSpy.Metadata var descriptor = (PropertyDescriptor)e.PropertyDescriptor; - if (descriptor.Attributes.OfType().Any()) + if (descriptor.Attributes.OfType().Any(c => c.Kind == ColumnKind.Token || c.LinkToTable)) { return new DataGridTemplateColumn() { Header = e.PropertyName, @@ -200,12 +200,12 @@ namespace ICSharpCode.ILSpy.Metadata string key = descriptor.PropertyType.Name + "Filter"; column.SetTemplate((ControlTemplate)MetadataTableViews.Instance[key]); } - var stringFormat = descriptor.Attributes.OfType().FirstOrDefault(); - if (stringFormat != null) + var columnInfo = descriptor.Attributes.OfType().FirstOrDefault(); + if (columnInfo != null) { - binding.StringFormat = stringFormat.Format; + binding.StringFormat = columnInfo.Format; if (!descriptor.PropertyType.IsEnum - && stringFormat.Format.StartsWith("X", StringComparison.OrdinalIgnoreCase)) + && columnInfo.Format.StartsWith("X", StringComparison.OrdinalIgnoreCase)) { column.SetTemplate((ControlTemplate)MetadataTableViews.Instance["HexFilter"]); } @@ -297,20 +297,28 @@ namespace ICSharpCode.ILSpy.Metadata } } - class StringFormatAttribute : Attribute + enum ColumnKind + { + HeapOffset, + Token, + Other + } + + [AttributeUsage(AttributeTargets.Property)] + class ColumnInfoAttribute : Attribute { public string Format { get; } - public StringFormatAttribute(string format) + public ColumnKind Kind { get; set; } + + public bool LinkToTable { get; set; } + + public ColumnInfoAttribute(string format) { this.Format = format; } } - class LinkToTableAttribute : Attribute - { - } - [Flags] internal enum TableMask : ulong { diff --git a/ILSpy/Metadata/MetadataTableTreeNode.cs b/ILSpy/Metadata/MetadataTableTreeNode.cs index dbd8a424c..204270dc3 100644 --- a/ILSpy/Metadata/MetadataTableTreeNode.cs +++ b/ILSpy/Metadata/MetadataTableTreeNode.cs @@ -22,11 +22,10 @@ using System.Reflection.Metadata.Ecma335; using System.Windows.Controls; using System.Windows.Threading; +using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Metadata; -using ICSharpCode.ILSpy.TextView; +using ICSharpCode.Decompiler.IL; using ICSharpCode.ILSpy.TreeNodes; -using ICSharpCode.ILSpy.ViewModels; -using ICSharpCode.TreeView; namespace ICSharpCode.ILSpy.Metadata { @@ -62,6 +61,73 @@ namespace ICSharpCode.ILSpy.Metadata view.Loaded -= View_Loaded; this.scrollTarget = default; } + + protected static string GenerateTooltip(ref string tooltip, PEFile module, EntityHandle handle) + { + if (tooltip == null) + { + if (handle.IsNil) + { + return null; + } + ITextOutput output = new PlainTextOutput(); + var context = new MetadataGenericContext(default(TypeDefinitionHandle), module); + var metadata = module.Metadata; + switch (handle.Kind) + { + case HandleKind.ModuleDefinition: + output.Write(metadata.GetString(metadata.GetModuleDefinition().Name)); + output.Write(" (this module)"); + break; + case HandleKind.ModuleReference: + ModuleReference moduleReference = metadata.GetModuleReference((ModuleReferenceHandle)handle); + output.Write(metadata.GetString(moduleReference.Name)); + break; + case HandleKind.AssemblyReference: + var asmRef = new Decompiler.Metadata.AssemblyReference(module, (AssemblyReferenceHandle)handle); + output.Write(asmRef.ToString()); + break; + case HandleKind.Parameter: + var param = metadata.GetParameter((ParameterHandle)handle); + output.Write(param.SequenceNumber + " - " + metadata.GetString(param.Name)); + break; + case HandleKind.EventDefinition: + var @event = metadata.GetEventDefinition((EventDefinitionHandle)handle); + output.Write(metadata.GetString(@event.Name)); + break; + case HandleKind.PropertyDefinition: + var prop = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle); + output.Write(metadata.GetString(prop.Name)); + break; + case HandleKind.AssemblyDefinition: + var ad = metadata.GetAssemblyDefinition(); + output.Write(metadata.GetString(ad.Name)); + output.Write(" (this assembly)"); + break; + case HandleKind.AssemblyFile: + var af = metadata.GetAssemblyFile((AssemblyFileHandle)handle); + output.Write(metadata.GetString(af.Name)); + break; + case HandleKind.GenericParameter: + var gp = metadata.GetGenericParameter((GenericParameterHandle)handle); + output.Write(metadata.GetString(gp.Name)); + break; + case HandleKind.ManifestResource: + var mfr = metadata.GetManifestResource((ManifestResourceHandle)handle); + output.Write(metadata.GetString(mfr.Name)); + break; + case HandleKind.Document: + var doc = metadata.GetDocument((DocumentHandle)handle); + output.Write(metadata.GetString(doc.Name)); + break; + default: + handle.WriteTo(module, output, context); + break; + } + tooltip = "(" + handle.Kind + ") " + output.ToString(); + } + return tooltip; + } } internal abstract class DebugMetadataTableTreeNode : MetadataTableTreeNode