mirror of https://github.com/icsharpcode/ILSpy.git
17 changed files with 1242 additions and 23 deletions
@ -0,0 +1,25 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.DebugInfo |
||||||
|
{ |
||||||
|
public static class KnownGuids |
||||||
|
{ |
||||||
|
public static readonly Guid CSharpLanguageGuid = new Guid("3f5162f8-07c6-11d3-9053-00c04fa302a1"); |
||||||
|
public static readonly Guid VBLanguageGuid = new Guid("3a12d0b8-c26c-11d0-b442-00a0244a1dd2"); |
||||||
|
public static readonly Guid FSharpLanguageGuid = new Guid("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3"); |
||||||
|
|
||||||
|
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 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"); |
||||||
|
|
||||||
|
public static readonly Guid HashAlgorithmSHA1 = new Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460"); |
||||||
|
public static readonly Guid HashAlgorithmSHA256 = new Guid("8829d00f-11b8-4213-878b-770e8597ac16"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System.Linq; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
using ICSharpCode.ILSpy.ViewModels; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
class DebugMetadataTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
private MetadataReader provider; |
||||||
|
private AssemblyTreeNode assemblyTreeNode; |
||||||
|
private bool isEmbedded; |
||||||
|
|
||||||
|
public DebugMetadataTreeNode(PEFile module, bool isEmbedded, MetadataReader provider, AssemblyTreeNode assemblyTreeNode) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
this.provider = provider; |
||||||
|
this.assemblyTreeNode = assemblyTreeNode; |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
this.Text = "Debug Metadata (" + (isEmbedded ? "Embedded" : "From portable PDB") + ")"; |
||||||
|
this.LazyLoading = true; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text { get; } |
||||||
|
|
||||||
|
public override object Icon => Images.Library; |
||||||
|
|
||||||
|
public override bool View(TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Debug Metadata"); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void LoadChildren() |
||||||
|
{ |
||||||
|
this.Children.Add(new DocumentTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
this.Children.Add(new MethodDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
this.Children.Add(new LocalScopeTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
this.Children.Add(new LocalVariableTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
this.Children.Add(new LocalConstantTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
this.Children.Add(new ImportScopeTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
this.Children.Add(new StateMachineMethodTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
this.Children.Add(new CustomDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); |
||||||
|
} |
||||||
|
|
||||||
|
public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind) |
||||||
|
{ |
||||||
|
return this.Children.OfType<MetadataTableTreeNode>().SingleOrDefault(x => x.Kind == kind); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.DebugInfo; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.IL; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class CustomDebugInformationTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
private readonly bool isEmbedded; |
||||||
|
|
||||||
|
public CustomDebugInformationTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base(HandleKind.CustomDebugInformation, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"37 CustomDebugInformation ({metadata.GetTableRowCount(TableIndex.CustomDebugInformation)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<CustomDebugInformationEntry>(); |
||||||
|
CustomDebugInformationEntry scrollTargetEntry = default; |
||||||
|
|
||||||
|
foreach (var row in metadata.CustomDebugInformation) { |
||||||
|
CustomDebugInformationEntry entry = new CustomDebugInformationEntry(module, metadata, isEmbedded, row); |
||||||
|
if (entry.RID == scrollTarget) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct CustomDebugInformationEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly CustomDebugInformationHandle handle; |
||||||
|
readonly CustomDebugInformation debugInfo; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int Parent => MetadataTokens.GetToken(debugInfo.Parent); |
||||||
|
|
||||||
|
public string ParentTooltip { |
||||||
|
get { |
||||||
|
ITextOutput output = new PlainTextOutput(); |
||||||
|
var context = new GenericContext(default(TypeDefinitionHandle), module); |
||||||
|
debugInfo.Parent.WriteTo(module, output, context); |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int Kind => MetadataTokens.GetHeapOffset(debugInfo.Kind); |
||||||
|
|
||||||
|
public string KindTooltip { |
||||||
|
get { |
||||||
|
if (debugInfo.Kind.IsNil) |
||||||
|
return null; |
||||||
|
var guid = metadata.GetGuid(debugInfo.Kind); |
||||||
|
if (KnownGuids.StateMachineHoistedLocalScopes == guid) { |
||||||
|
return "State Machine Hoisted Local Scopes (C# / VB) [" + guid + "]"; |
||||||
|
} |
||||||
|
if (KnownGuids.DynamicLocalVariables == guid) { |
||||||
|
return "Dynamic Local Variables (C#) [" + guid + "]"; |
||||||
|
} |
||||||
|
if (KnownGuids.DefaultNamespaces == guid) { |
||||||
|
return "Default Namespaces (VB) [" + guid + "]"; |
||||||
|
} |
||||||
|
if (KnownGuids.EditAndContinueLocalSlotMap == guid) { |
||||||
|
return "Edit And Continue Local Slot Map (C# / VB) [" + guid + "]"; |
||||||
|
} |
||||||
|
if (KnownGuids.EditAndContinueLambdaAndClosureMap == guid) { |
||||||
|
return "Edit And Continue Lambda And Closure Map (C# / VB) [" + guid + "]"; |
||||||
|
} |
||||||
|
if (KnownGuids.EmbeddedSource == guid) { |
||||||
|
return "State Machine Hoisted Local Scopes (C# / VB) [" + guid + "]"; |
||||||
|
} |
||||||
|
if (KnownGuids.SourceLink == guid) { |
||||||
|
return "Source Link (C# / VB) [" + guid + "]"; |
||||||
|
} |
||||||
|
if (KnownGuids.MethodSteppingInformation == guid) { |
||||||
|
return "Method Stepping Information (C# / VB) [" + guid + "]"; |
||||||
|
} |
||||||
|
|
||||||
|
return $"Unknown [" + guid + "]"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int Value => MetadataTokens.GetHeapOffset(debugInfo.Value); |
||||||
|
|
||||||
|
public string ValueTooltip { |
||||||
|
get { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public CustomDebugInformationEntry(PEFile module, MetadataReader metadata, bool isEmbedded, CustomDebugInformationHandle handle) |
||||||
|
{ |
||||||
|
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.CustomDebugInformation) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.CustomDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1); |
||||||
|
this.module = module; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.debugInfo = metadata.GetCustomDebugInformation(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "CustomDebugInformation"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,149 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
|
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.DebugInfo; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class DocumentTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
private readonly bool isEmbedded; |
||||||
|
|
||||||
|
public DocumentTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base(HandleKind.Document, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"30 Document ({metadata.GetTableRowCount(TableIndex.Document)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<DocumentEntry>(); |
||||||
|
DocumentEntry scrollTargetEntry = default; |
||||||
|
|
||||||
|
foreach (var row in metadata.Documents) { |
||||||
|
DocumentEntry entry = new DocumentEntry(metadata, isEmbedded, row); |
||||||
|
if (entry.RID == scrollTarget) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct DocumentEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly DocumentHandle handle; |
||||||
|
readonly Document document; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
public string Name => metadata.GetString(document.Name); |
||||||
|
|
||||||
|
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(document.Name):X} \"{Name}\""; |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int HashAlgorithm => MetadataTokens.GetHeapOffset(document.HashAlgorithm); |
||||||
|
|
||||||
|
public string HashAlgorithmTooltip { |
||||||
|
get { |
||||||
|
if (document.HashAlgorithm.IsNil) |
||||||
|
return null; |
||||||
|
Guid guid = metadata.GetGuid(document.HashAlgorithm); |
||||||
|
if (guid == KnownGuids.HashAlgorithmSHA1) |
||||||
|
return "SHA1 [ff1816ec-aa5e-4d10-87f7-6f4963833460]"; |
||||||
|
if (guid == KnownGuids.HashAlgorithmSHA256) |
||||||
|
return "SHA256 [8829d00f-11b8-4213-878b-770e8597ac16]"; |
||||||
|
return $"Unknown [" + guid + "]"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int Hash => MetadataTokens.GetHeapOffset(document.Hash); |
||||||
|
|
||||||
|
public string HashTooltip { |
||||||
|
get { |
||||||
|
if (document.Hash.IsNil) |
||||||
|
return null; |
||||||
|
System.Collections.Immutable.ImmutableArray<byte> token = metadata.GetBlobContent(document.Hash); |
||||||
|
return token.ToHexString(token.Length); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int Language => MetadataTokens.GetHeapOffset(document.Language); |
||||||
|
|
||||||
|
public string LanguageTooltip { |
||||||
|
get { |
||||||
|
if (document.Language.IsNil) |
||||||
|
return null; |
||||||
|
Guid guid = metadata.GetGuid(document.Language); |
||||||
|
if (guid == KnownGuids.CSharpLanguageGuid) |
||||||
|
return "Visual C# [3f5162f8-07c6-11d3-9053-00c04fa302a1]"; |
||||||
|
if (guid == KnownGuids.VBLanguageGuid) |
||||||
|
return "Visual Basic [3a12d0b8-c26c-11d0-b442-00a0244a1dd2]"; |
||||||
|
if (guid == KnownGuids.FSharpLanguageGuid) |
||||||
|
return "Visual F# [ab4f38c9-b6e6-43ba-be3b-58080b2ccce3]"; |
||||||
|
return $"Unknown [" + guid + "]"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public DocumentEntry(MetadataReader metadata, bool isEmbedded, DocumentHandle handle) |
||||||
|
{ |
||||||
|
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.Document) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.Document) * (MetadataTokens.GetRowNumber(handle) - 1); |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.document = metadata.GetDocument(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Document"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,109 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.IL; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using System.Linq; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class ImportScopeTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
private readonly bool isEmbedded; |
||||||
|
|
||||||
|
public ImportScopeTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base(HandleKind.ImportScope, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"35 ImportScope ({metadata.GetTableRowCount(TableIndex.ImportScope)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<ImportScopeEntry>(); |
||||||
|
ImportScopeEntry scrollTargetEntry = default; |
||||||
|
|
||||||
|
foreach (var row in metadata.ImportScopes) { |
||||||
|
ImportScopeEntry entry = new ImportScopeEntry(module, metadata, isEmbedded, row); |
||||||
|
if (entry.RID == scrollTarget) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct ImportScopeEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly ImportScopeHandle handle; |
||||||
|
readonly ImportScope localScope; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int Parent => MetadataTokens.GetToken(localScope.Parent); |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int Imports => MetadataTokens.GetHeapOffset(localScope.ImportsBlob); |
||||||
|
|
||||||
|
public ImportScopeEntry(PEFile module, MetadataReader metadata, bool isEmbedded, ImportScopeHandle handle) |
||||||
|
{ |
||||||
|
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.ImportScope) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.ImportScope) * (MetadataTokens.GetRowNumber(handle) - 1); |
||||||
|
this.module = module; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.localScope = metadata.GetImportScope(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "ImportScope"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,108 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class LocalConstantTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
private readonly bool isEmbedded; |
||||||
|
|
||||||
|
public LocalConstantTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base(HandleKind.LocalConstant, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"34 LocalConstant ({metadata.GetTableRowCount(TableIndex.LocalConstant)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<LocalConstantEntry>(); |
||||||
|
LocalConstantEntry scrollTargetEntry = default; |
||||||
|
|
||||||
|
foreach (var row in metadata.LocalConstants) { |
||||||
|
LocalConstantEntry entry = new LocalConstantEntry(module, metadata, isEmbedded, row); |
||||||
|
if (entry.RID == scrollTarget) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct LocalConstantEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly LocalConstantHandle handle; |
||||||
|
readonly LocalConstant localConst; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
public string Name => metadata.GetString(localConst.Name); |
||||||
|
|
||||||
|
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(localConst.Name):X} \"{Name}\""; |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int Signature => MetadataTokens.GetToken(localConst.Signature); |
||||||
|
|
||||||
|
public LocalConstantEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalConstantHandle handle) |
||||||
|
{ |
||||||
|
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.LocalConstant) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.LocalConstant) * (MetadataTokens.GetRowNumber(handle) - 1); |
||||||
|
this.module = module; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.localConst = metadata.GetLocalConstant(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Document"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,129 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.IL; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using System.Linq; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class LocalScopeTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
private readonly bool isEmbedded; |
||||||
|
|
||||||
|
public LocalScopeTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base(HandleKind.LocalScope, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"32 LocalScope ({metadata.GetTableRowCount(TableIndex.LocalScope)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<LocalScopeEntry>(); |
||||||
|
LocalScopeEntry scrollTargetEntry = default; |
||||||
|
|
||||||
|
foreach (var row in metadata.LocalScopes) { |
||||||
|
LocalScopeEntry entry = new LocalScopeEntry(module, metadata, isEmbedded, row); |
||||||
|
if (entry.RID == scrollTarget) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct LocalScopeEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly LocalScopeHandle handle; |
||||||
|
readonly LocalScope localScope; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int Method => MetadataTokens.GetToken(localScope.Method); |
||||||
|
|
||||||
|
public string MethodTooltip { |
||||||
|
get { |
||||||
|
ITextOutput output = new PlainTextOutput(); |
||||||
|
((EntityHandle)localScope.Method).WriteTo(module, output, Decompiler.Metadata.GenericContext.Empty); |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int ImportScope => MetadataTokens.GetToken(localScope.ImportScope); |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int VariableList => MetadataTokens.GetToken(localScope.GetLocalVariables().FirstOrDefault()); |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int ConstantList => MetadataTokens.GetToken(localScope.GetLocalConstants().FirstOrDefault()); |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int StartOffset => localScope.StartOffset; |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int Length => localScope.Length; |
||||||
|
|
||||||
|
public LocalScopeEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalScopeHandle handle) |
||||||
|
{ |
||||||
|
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.LocalScope) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.LocalScope) * (MetadataTokens.GetRowNumber(handle) - 1); |
||||||
|
this.module = module; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.localScope = metadata.GetLocalScope(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "LocalScope"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class LocalVariableTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
private readonly bool isEmbedded; |
||||||
|
|
||||||
|
public LocalVariableTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base(HandleKind.LocalVariable, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"33 LocalVariable ({metadata.GetTableRowCount(TableIndex.LocalVariable)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<LocalVariableEntry>(); |
||||||
|
LocalVariableEntry scrollTargetEntry = default; |
||||||
|
|
||||||
|
foreach (var row in metadata.LocalVariables) { |
||||||
|
LocalVariableEntry entry = new LocalVariableEntry(module, metadata, isEmbedded, row); |
||||||
|
if (entry.RID == scrollTarget) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct LocalVariableEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly LocalVariableHandle handle; |
||||||
|
readonly LocalVariable localVar; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public LocalVariableAttributes Attributes => localVar.Attributes; |
||||||
|
|
||||||
|
public object AttributesTooltip => new FlagsTooltip() { |
||||||
|
FlagGroup.CreateMultipleChoiceGroup(typeof(LocalVariableAttributes)), |
||||||
|
}; |
||||||
|
|
||||||
|
public int Index => localVar.Index; |
||||||
|
|
||||||
|
public string Name => metadata.GetString(localVar.Name); |
||||||
|
|
||||||
|
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(localVar.Name):X} \"{Name}\""; |
||||||
|
|
||||||
|
public LocalVariableEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalVariableHandle handle) |
||||||
|
{ |
||||||
|
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.LocalVariable) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.LocalVariable) * (MetadataTokens.GetRowNumber(handle) - 1); |
||||||
|
this.module = module; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.localVar = metadata.GetLocalVariable(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Document"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,150 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class MethodDebugInformationTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
private readonly bool isEmbedded; |
||||||
|
|
||||||
|
public MethodDebugInformationTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base(HandleKind.MethodDebugInformation, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"31 MethodDebugInformation ({metadata.GetTableRowCount(TableIndex.MethodDebugInformation)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<MethodDebugInformationEntry>(); |
||||||
|
MethodDebugInformationEntry scrollTargetEntry = default; |
||||||
|
|
||||||
|
foreach (var row in metadata.MethodDebugInformation) { |
||||||
|
MethodDebugInformationEntry entry = new MethodDebugInformationEntry(module, metadata, isEmbedded, row); |
||||||
|
if (entry.RID == scrollTarget) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct MethodDebugInformationEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly MethodDebugInformationHandle handle; |
||||||
|
readonly MethodDebugInformation debugInfo; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int Document => MetadataTokens.GetToken(debugInfo.Document); |
||||||
|
|
||||||
|
public string DocumentTooltip { |
||||||
|
get { |
||||||
|
if (debugInfo.Document.IsNil) |
||||||
|
return null; |
||||||
|
var document = metadata.GetDocument(debugInfo.Document); |
||||||
|
return $"{MetadataTokens.GetHeapOffset(document.Name):X} \"{metadata.GetString(document.Name)}\""; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int SequencePoints => MetadataTokens.GetHeapOffset(debugInfo.SequencePointsBlob); |
||||||
|
|
||||||
|
public string SequencePointsTooltip { |
||||||
|
get { |
||||||
|
if (debugInfo.SequencePointsBlob.IsNil) |
||||||
|
return null; |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
foreach (var p in debugInfo.GetSequencePoints()) { |
||||||
|
sb.AppendLine($"document='{MetadataTokens.GetToken(p.Document):X8}', offset={p.Offset}, start={p.StartLine};{p.StartColumn}, end={p.EndLine};{p.EndColumn}, hidden={p.IsHidden}"); |
||||||
|
} |
||||||
|
return sb.ToString().TrimEnd(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X")] |
||||||
|
public int LocalSignature => MetadataTokens.GetToken(debugInfo.LocalSignature); |
||||||
|
|
||||||
|
public string LocalSignatureTooltip { |
||||||
|
get { |
||||||
|
if (debugInfo.LocalSignature.IsNil) |
||||||
|
return null; |
||||||
|
ITextOutput output = new PlainTextOutput(); |
||||||
|
var context = new Decompiler.Metadata.GenericContext(default(TypeDefinitionHandle), metadata); |
||||||
|
StandaloneSignature localSignature = module.Metadata.GetStandaloneSignature(debugInfo.LocalSignature); |
||||||
|
var signatureDecoder = new DisassemblerSignatureTypeProvider(module, output); |
||||||
|
int index = 0; |
||||||
|
foreach (var item in localSignature.DecodeLocalSignature(signatureDecoder, context)) { |
||||||
|
if (index > 0) output.WriteLine(); |
||||||
|
output.Write("[{0}] ", index); |
||||||
|
item(ILNameSyntax.Signature); |
||||||
|
index++; |
||||||
|
} |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public MethodDebugInformationEntry(PEFile module, MetadataReader metadata, bool isEmbedded, MethodDebugInformationHandle handle) |
||||||
|
{ |
||||||
|
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.MethodDebugInformation) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.MethodDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1); |
||||||
|
this.module = module; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.debugInfo = metadata.GetMethodDebugInformation(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "MethodDebugInformation"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,141 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.IL; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class StateMachineMethodTableTreeNode : DebugMetadataTableTreeNode |
||||||
|
{ |
||||||
|
readonly bool isEmbedded; |
||||||
|
|
||||||
|
public StateMachineMethodTableTreeNode(PEFile module, MetadataReader metadata, bool isEmbedded) |
||||||
|
: base((HandleKind)0x36, module, metadata) |
||||||
|
{ |
||||||
|
this.isEmbedded = isEmbedded; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"36 StateMachineMethod ({metadata.GetTableRowCount(TableIndex.StateMachineMethod)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public unsafe override bool View(ViewModels.TabPageModel tabPage) |
||||||
|
{ |
||||||
|
tabPage.Title = Text.ToString(); |
||||||
|
tabPage.SupportsLanguageSwitching = false; |
||||||
|
|
||||||
|
var view = Helpers.PrepareDataGrid(tabPage, this); |
||||||
|
var list = new List<StateMachineMethodEntry>(); |
||||||
|
StateMachineMethodEntry scrollTargetEntry = default; |
||||||
|
var length = metadata.GetTableRowCount(TableIndex.StateMachineMethod); |
||||||
|
byte* ptr = metadata.MetadataPointer; |
||||||
|
|
||||||
|
for (int rid = 1; rid <= length; rid++) { |
||||||
|
StateMachineMethodEntry entry = new StateMachineMethodEntry(module, ptr, isEmbedded, rid); |
||||||
|
if (scrollTarget == rid) { |
||||||
|
scrollTargetEntry = entry; |
||||||
|
} |
||||||
|
list.Add(entry); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
tabPage.Content = view; |
||||||
|
|
||||||
|
if (scrollTargetEntry.RID > 1) { |
||||||
|
ScrollItemIntoView(view, scrollTargetEntry); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
readonly struct StateMachineMethod |
||||||
|
{ |
||||||
|
public readonly MethodDefinitionHandle MoveNextMethod; |
||||||
|
public readonly MethodDefinitionHandle KickoffMethod; |
||||||
|
|
||||||
|
public unsafe StateMachineMethod(byte* ptr, int methodDefSize) |
||||||
|
{ |
||||||
|
MoveNextMethod = MetadataTokens.MethodDefinitionHandle(Helpers.GetValue(ptr, methodDefSize)); |
||||||
|
KickoffMethod = MetadataTokens.MethodDefinitionHandle(Helpers.GetValue(ptr + methodDefSize, methodDefSize)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
unsafe struct StateMachineMethodEntry |
||||||
|
{ |
||||||
|
readonly int? offset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly StateMachineMethod stateMachineMethod; |
||||||
|
|
||||||
|
public int RID { get; } |
||||||
|
|
||||||
|
public object Offset => offset == null ? "n/a" : (object)offset; |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int MoveNextMethod => MetadataTokens.GetToken(stateMachineMethod.MoveNextMethod); |
||||||
|
|
||||||
|
public string MoveNextMethodTooltip { |
||||||
|
get { |
||||||
|
ITextOutput output = new PlainTextOutput(); |
||||||
|
var context = new GenericContext(default(TypeDefinitionHandle), module); |
||||||
|
((EntityHandle)stateMachineMethod.MoveNextMethod).WriteTo(module, output, context); |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[StringFormat("X8")] |
||||||
|
public int KickoffMethod => MetadataTokens.GetToken(stateMachineMethod.KickoffMethod); |
||||||
|
|
||||||
|
public string KickoffMethodTooltip { |
||||||
|
get { |
||||||
|
ITextOutput output = new PlainTextOutput(); |
||||||
|
var context = new GenericContext(default(TypeDefinitionHandle), module); |
||||||
|
((EntityHandle)stateMachineMethod.KickoffMethod).WriteTo(module, output, context); |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public StateMachineMethodEntry(PEFile module, byte* ptr, bool isEmbedded, int row) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
this.metadata = module.Metadata; |
||||||
|
this.RID = row; |
||||||
|
int rowOffset = metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.StateMachineMethod) * (row - 1); |
||||||
|
this.offset = isEmbedded ? null : (int?)rowOffset; |
||||||
|
this.stateMachineMethod = new StateMachineMethod(ptr + rowOffset, metadata.GetTableRowCount(TableIndex.MethodDef) < ushort.MaxValue ? 2 : 4); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "StateMachineMethod"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue