diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 6d41b8b59..d1ec22e33 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -212,9 +212,28 @@ + + Code + MSBuild:Compile + + + Code + MSBuild:Compile + + + Code + MSBuild:Compile + + + Code + MSBuild:Compile + + + + diff --git a/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs b/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs new file mode 100644 index 000000000..8fc5a3734 --- /dev/null +++ b/ILSpy/Metadata/DebugMetadataTablesTreeNode.cs @@ -0,0 +1,84 @@ +// Copyright (c) 2021 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; +using ICSharpCode.ILSpy.Options; +using ICSharpCode.ILSpy.TreeNodes; +using ICSharpCode.ILSpy.ViewModels; + +namespace ICSharpCode.ILSpy.Metadata +{ + class DebugMetadataTablesTreeNode : ILSpyTreeNode + { + private PEFile module; + private bool isEmbedded; + private MetadataReader provider; + + public DebugMetadataTablesTreeNode(PEFile module, bool isEmbedded, MetadataReader provider) + { + this.module = module; + this.isEmbedded = isEmbedded; + this.provider = provider; + this.LazyLoading = true; + } + + public override object Text => "Tables"; + + public override object Icon => Images.Literal; + + protected override void LoadChildren() + { + if (ShowTable(TableIndex.Document)) + this.Children.Add(new DocumentTableTreeNode(this.module, this.provider, isEmbedded)); + if (ShowTable(TableIndex.MethodDebugInformation)) + this.Children.Add(new MethodDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); + if (ShowTable(TableIndex.LocalScope)) + this.Children.Add(new LocalScopeTableTreeNode(this.module, this.provider, isEmbedded)); + if (ShowTable(TableIndex.LocalVariable)) + this.Children.Add(new LocalVariableTableTreeNode(this.module, this.provider, isEmbedded)); + if (ShowTable(TableIndex.LocalConstant)) + this.Children.Add(new LocalConstantTableTreeNode(this.module, this.provider, isEmbedded)); + if (ShowTable(TableIndex.ImportScope)) + this.Children.Add(new ImportScopeTableTreeNode(this.module, this.provider, isEmbedded)); + if (ShowTable(TableIndex.StateMachineMethod)) + this.Children.Add(new StateMachineMethodTableTreeNode(this.module, this.provider, isEmbedded)); + if (ShowTable(TableIndex.CustomDebugInformation)) + this.Children.Add(new CustomDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); + + bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || this.provider.GetTableRowCount(table) > 0; + } + + 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, "Metadata Tables"); + } + } +} diff --git a/ILSpy/Metadata/DebugMetadataTreeNode.cs b/ILSpy/Metadata/DebugMetadataTreeNode.cs index d14556511..c0edc0d02 100644 --- a/ILSpy/Metadata/DebugMetadataTreeNode.cs +++ b/ILSpy/Metadata/DebugMetadataTreeNode.cs @@ -64,24 +64,11 @@ namespace ICSharpCode.ILSpy.Metadata protected override void LoadChildren() { - if (ShowTable(TableIndex.Document)) - this.Children.Add(new DocumentTableTreeNode(this.module, this.provider, isEmbedded)); - if (ShowTable(TableIndex.MethodDebugInformation)) - this.Children.Add(new MethodDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); - if (ShowTable(TableIndex.LocalScope)) - this.Children.Add(new LocalScopeTableTreeNode(this.module, this.provider, isEmbedded)); - if (ShowTable(TableIndex.LocalVariable)) - this.Children.Add(new LocalVariableTableTreeNode(this.module, this.provider, isEmbedded)); - if (ShowTable(TableIndex.LocalConstant)) - this.Children.Add(new LocalConstantTableTreeNode(this.module, this.provider, isEmbedded)); - if (ShowTable(TableIndex.ImportScope)) - this.Children.Add(new ImportScopeTableTreeNode(this.module, this.provider, isEmbedded)); - if (ShowTable(TableIndex.StateMachineMethod)) - this.Children.Add(new StateMachineMethodTableTreeNode(this.module, this.provider, isEmbedded)); - if (ShowTable(TableIndex.CustomDebugInformation)) - this.Children.Add(new CustomDebugInformationTableTreeNode(this.module, this.provider, isEmbedded)); - - bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || this.provider.GetTableRowCount(table) > 0; + this.Children.Add(new DebugMetadataTablesTreeNode(module, this.isEmbedded, this.provider)); + this.Children.Add(new StringHeapTreeNode(module, this.provider)); + this.Children.Add(new UserStringHeapTreeNode(module, this.provider)); + this.Children.Add(new GuidHeapTreeNode(module, this.provider)); + this.Children.Add(new BlobHeapTreeNode(module, this.provider)); } public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind) diff --git a/ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs b/ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs new file mode 100644 index 000000000..f439e9acd --- /dev/null +++ b/ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs @@ -0,0 +1,97 @@ +// 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; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; + +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 BlobHeapTreeNode : MetadataHeapTreeNode + { + readonly List list; + + public BlobHeapTreeNode(PEFile module, MetadataReader metadata) + : base(HandleKind.Blob, module, metadata) + { + list = new List(); + + BlobHandle handle = MetadataTokens.BlobHandle(0); + do + { + BlobHeapEntry entry = new BlobHeapEntry(metadata, handle); + list.Add(entry); + handle = metadata.GetNextHandle(handle); + } while (!handle.IsNil); + } + + public override object Text => $"Blob Heap ({list.Count})"; + + 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); + + view.ItemsSource = list; + + tabPage.Content = view; + + return true; + } + + class BlobHeapEntry + { + readonly MetadataReader metadata; + readonly BlobHandle handle; + + public int Offset => metadata.GetHeapOffset(handle); + + public int Length => metadata.GetBlobReader(handle).Length; + + public string Value => metadata.GetBlobReader(handle).ToHexString(); + + public BlobHeapEntry(MetadataReader metadata, BlobHandle handle) + { + this.metadata = metadata; + this.handle = handle; + } + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.WriteCommentLine(output, "Blob Heap"); + } + } +} \ No newline at end of file diff --git a/ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs b/ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs new file mode 100644 index 000000000..f3f742619 --- /dev/null +++ b/ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs @@ -0,0 +1,86 @@ +// Copyright (c) 2021 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.Metadata; +using System.Reflection.Metadata.Ecma335; + +using ICSharpCode.Decompiler; +using ICSharpCode.Decompiler.Metadata; + +namespace ICSharpCode.ILSpy.Metadata +{ + internal class GuidHeapTreeNode : MetadataHeapTreeNode + { + readonly List list; + + public GuidHeapTreeNode(PEFile module, MetadataReader metadata) + : base(HandleKind.Guid, module, metadata) + { + list = new List(); + int count = metadata.GetHeapSize(HeapIndex.Guid) >> 4; + for (int i = 1; i <= count; i++) + { + GuidHeapEntry entry = new GuidHeapEntry(metadata, MetadataTokens.GuidHandle(i)); + list.Add(entry); + } + } + + public override object Text => $"Guid Heap ({list.Count})"; + + 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); + + view.ItemsSource = list; + + tabPage.Content = view; + + return true; + } + + class GuidHeapEntry + { + readonly MetadataReader metadata; + readonly GuidHandle handle; + + public int Index => metadata.GetHeapOffset(handle); + + public int Length => 16; + + public string Value => metadata.GetGuid(handle).ToString(); + + public GuidHeapEntry(MetadataReader metadata, GuidHandle handle) + { + this.metadata = metadata; + this.handle = handle; + } + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.WriteCommentLine(output, "Guid Heap"); + } + } +} \ No newline at end of file diff --git a/ILSpy/Metadata/Heaps/StringHeapTreeNode.cs b/ILSpy/Metadata/Heaps/StringHeapTreeNode.cs new file mode 100644 index 000000000..2e2ca4370 --- /dev/null +++ b/ILSpy/Metadata/Heaps/StringHeapTreeNode.cs @@ -0,0 +1,96 @@ +// 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; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; + +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 StringHeapTreeNode : MetadataHeapTreeNode + { + readonly List list; + + public StringHeapTreeNode(PEFile module, MetadataReader metadata) + : base(HandleKind.String, module, metadata) + { + list = new List(); + StringHandle handle = MetadataTokens.StringHandle(0); + do + { + StringHeapEntry entry = new StringHeapEntry(metadata, handle); + list.Add(entry); + handle = metadata.GetNextHandle(handle); + } while (!handle.IsNil); + } + + public override object Text => $"String Heap ({list.Count})"; + + 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); + + view.ItemsSource = list; + + tabPage.Content = view; + + return true; + } + + class StringHeapEntry + { + readonly MetadataReader metadata; + readonly StringHandle handle; + + public int Offset => metadata.GetHeapOffset(handle); + + public int Length => metadata.GetString(handle).Length; + + public string Value => metadata.GetString(handle); + + public StringHeapEntry(MetadataReader metadata, StringHandle handle) + { + this.metadata = metadata; + this.handle = handle; + } + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.WriteCommentLine(output, "String Heap"); + } + } +} \ No newline at end of file diff --git a/ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs b/ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs new file mode 100644 index 000000000..882a1c3a6 --- /dev/null +++ b/ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs @@ -0,0 +1,97 @@ +// 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; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; + +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 UserStringHeapTreeNode : MetadataHeapTreeNode + { + readonly List list; + + public UserStringHeapTreeNode(PEFile module, MetadataReader metadata) + : base(HandleKind.UserString, module, metadata) + { + list = new List(); + + UserStringHandle handle = MetadataTokens.UserStringHandle(0); + do + { + UserStringHeapEntry entry = new UserStringHeapEntry(metadata, handle); + list.Add(entry); + handle = metadata.GetNextHandle(handle); + } while (!handle.IsNil); + } + + public override object Text => $"UserString Heap ({list.Count})"; + + 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); + + view.ItemsSource = list; + + tabPage.Content = view; + + return true; + } + + class UserStringHeapEntry + { + readonly MetadataReader metadata; + readonly UserStringHandle handle; + + public int Offset => metadata.GetHeapOffset(handle); + + public int Length => metadata.GetUserString(handle).Length; + + public string Value => metadata.GetUserString(handle); + + public UserStringHeapEntry(MetadataReader metadata, UserStringHandle handle) + { + this.metadata = metadata; + this.handle = handle; + } + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.WriteCommentLine(output, "UserString Heap"); + } + } +} \ No newline at end of file diff --git a/ILSpy/Metadata/MetadataHeapTreeNode.cs b/ILSpy/Metadata/MetadataHeapTreeNode.cs new file mode 100644 index 000000000..3be811d3d --- /dev/null +++ b/ILSpy/Metadata/MetadataHeapTreeNode.cs @@ -0,0 +1,68 @@ +// 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.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Windows.Controls; +using System.Windows.Threading; + +using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.ILSpy.TextView; +using ICSharpCode.ILSpy.TreeNodes; +using ICSharpCode.ILSpy.ViewModels; +using ICSharpCode.TreeView; + +namespace ICSharpCode.ILSpy.Metadata +{ + internal abstract class MetadataHeapTreeNode : ILSpyTreeNode + { + protected PEFile module; + protected MetadataReader metadata; + protected int scrollTarget; + + public HandleKind Kind { get; } + + public MetadataHeapTreeNode(HandleKind kind, PEFile module, MetadataReader metadata) + { + this.module = module; + this.Kind = kind; + this.metadata = metadata; + } + + internal void ScrollTo(Handle handle) + { + //this.scrollTarget = MetadataTokens.GetHeapOffset((EntityHandle)handle); + } + + protected void ScrollItemIntoView(DataGrid view, object item) + { + view.Loaded += View_Loaded; + view.Dispatcher.BeginInvoke((Action)(() => view.SelectItem(item)), DispatcherPriority.Background); + } + + private void View_Loaded(object sender, System.Windows.RoutedEventArgs e) + { + DataGrid view = (DataGrid)sender; + var sv = view.FindVisualChild(); + sv.ScrollToVerticalOffset(scrollTarget - 1); + view.Loaded -= View_Loaded; + this.scrollTarget = default; + } + } +} \ No newline at end of file diff --git a/ILSpy/Metadata/MetadataProtocolHandler.cs b/ILSpy/Metadata/MetadataProtocolHandler.cs index ced6a7497..3fb5219d9 100644 --- a/ILSpy/Metadata/MetadataProtocolHandler.cs +++ b/ILSpy/Metadata/MetadataProtocolHandler.cs @@ -1,10 +1,24 @@ -using System; -using System.Collections.Generic; +// 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.ComponentModel.Composition; using System.Linq; using System.Reflection.Metadata; -using System.Text; -using System.Threading.Tasks; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy.TreeNodes; diff --git a/ILSpy/Metadata/MetadataTableTreeNode.cs b/ILSpy/Metadata/MetadataTableTreeNode.cs index a2644484b..dbd8a424c 100644 --- a/ILSpy/Metadata/MetadataTableTreeNode.cs +++ b/ILSpy/Metadata/MetadataTableTreeNode.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy.Metadata internal void ScrollTo(Handle handle) { - this.scrollTarget = MetadataTokens.GetRowNumber((EntityHandle)handle); + this.scrollTarget = module.Metadata.GetRowNumber((EntityHandle)handle); } protected void ScrollItemIntoView(DataGrid view, object item) diff --git a/ILSpy/Metadata/MetadataTablesTreeNode.cs b/ILSpy/Metadata/MetadataTablesTreeNode.cs new file mode 100644 index 000000000..6d264792d --- /dev/null +++ b/ILSpy/Metadata/MetadataTablesTreeNode.cs @@ -0,0 +1,132 @@ +// Copyright (c) 2021 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.Ecma335; + +using ICSharpCode.Decompiler; +using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.ILSpy.Options; +using ICSharpCode.ILSpy.TreeNodes; +using ICSharpCode.ILSpy.ViewModels; + +namespace ICSharpCode.ILSpy.Metadata +{ + class MetadataTablesTreeNode : ILSpyTreeNode + { + private PEFile module; + + public MetadataTablesTreeNode(PEFile module) + { + this.module = module; + this.LazyLoading = true; + } + + public override object Text => "Tables"; + + public override object Icon => Images.Literal; + + protected override void LoadChildren() + { + if (ShowTable(TableIndex.Module)) + this.Children.Add(new ModuleTableTreeNode(module)); + if (ShowTable(TableIndex.TypeRef)) + this.Children.Add(new TypeRefTableTreeNode(module)); + if (ShowTable(TableIndex.TypeDef)) + this.Children.Add(new TypeDefTableTreeNode(module)); + if (ShowTable(TableIndex.Field)) + this.Children.Add(new FieldTableTreeNode(module)); + if (ShowTable(TableIndex.MethodDef)) + this.Children.Add(new MethodTableTreeNode(module)); + if (ShowTable(TableIndex.Param)) + this.Children.Add(new ParamTableTreeNode(module)); + if (ShowTable(TableIndex.InterfaceImpl)) + this.Children.Add(new InterfaceImplTableTreeNode(module)); + if (ShowTable(TableIndex.MemberRef)) + this.Children.Add(new MemberRefTableTreeNode(module)); + if (ShowTable(TableIndex.Constant)) + this.Children.Add(new ConstantTableTreeNode(module)); + if (ShowTable(TableIndex.CustomAttribute)) + this.Children.Add(new CustomAttributeTableTreeNode(module)); + if (ShowTable(TableIndex.FieldMarshal)) + this.Children.Add(new FieldMarshalTableTreeNode(module)); + if (ShowTable(TableIndex.DeclSecurity)) + this.Children.Add(new DeclSecurityTableTreeNode(module)); + if (ShowTable(TableIndex.ClassLayout)) + this.Children.Add(new ClassLayoutTableTreeNode(module)); + if (ShowTable(TableIndex.FieldLayout)) + this.Children.Add(new FieldLayoutTableTreeNode(module)); + if (ShowTable(TableIndex.StandAloneSig)) + this.Children.Add(new StandAloneSigTableTreeNode(module)); + if (ShowTable(TableIndex.EventMap)) + this.Children.Add(new EventMapTableTreeNode(module)); + if (ShowTable(TableIndex.Event)) + this.Children.Add(new EventTableTreeNode(module)); + if (ShowTable(TableIndex.PropertyMap)) + this.Children.Add(new PropertyMapTableTreeNode(module)); + if (ShowTable(TableIndex.Property)) + this.Children.Add(new PropertyTableTreeNode(module)); + if (ShowTable(TableIndex.MethodSemantics)) + this.Children.Add(new MethodSemanticsTableTreeNode(module)); + if (ShowTable(TableIndex.MethodImpl)) + this.Children.Add(new MethodImplTableTreeNode(module)); + if (ShowTable(TableIndex.ModuleRef)) + this.Children.Add(new ModuleRefTableTreeNode(module)); + if (ShowTable(TableIndex.TypeSpec)) + this.Children.Add(new TypeSpecTableTreeNode(module)); + if (ShowTable(TableIndex.ImplMap)) + this.Children.Add(new ImplMapTableTreeNode(module)); + if (ShowTable(TableIndex.FieldRva)) + this.Children.Add(new FieldRVATableTreeNode(module)); + if (ShowTable(TableIndex.Assembly)) + this.Children.Add(new AssemblyTableTreeNode(module)); + if (ShowTable(TableIndex.AssemblyRef)) + this.Children.Add(new AssemblyRefTableTreeNode(module)); + if (ShowTable(TableIndex.File)) + this.Children.Add(new FileTableTreeNode(module)); + if (ShowTable(TableIndex.ExportedType)) + this.Children.Add(new ExportedTypeTableTreeNode(module)); + if (ShowTable(TableIndex.ManifestResource)) + this.Children.Add(new ManifestResourceTableTreeNode(module)); + if (ShowTable(TableIndex.NestedClass)) + this.Children.Add(new NestedClassTableTreeNode(module)); + if (ShowTable(TableIndex.GenericParam)) + this.Children.Add(new GenericParamTableTreeNode(module)); + if (ShowTable(TableIndex.MethodSpec)) + this.Children.Add(new MethodSpecTableTreeNode(module)); + if (ShowTable(TableIndex.GenericParamConstraint)) + this.Children.Add(new GenericParamConstraintTableTreeNode(module)); + + bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || module.Metadata.GetTableRowCount(table) > 0; + + } + + 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, "Metadata Tables"); + } + } +} diff --git a/ILSpy/Metadata/MetadataTreeNode.cs b/ILSpy/Metadata/MetadataTreeNode.cs index ebd96a069..03b98bf6a 100644 --- a/ILSpy/Metadata/MetadataTreeNode.cs +++ b/ILSpy/Metadata/MetadataTreeNode.cs @@ -17,20 +17,13 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; -using System.Reflection.PortableExecutable; -using System.Text; -using System.Threading.Tasks; -using System.Windows; using System.Windows.Data; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Metadata; -using ICSharpCode.ILSpy.Options; using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.ViewModels; @@ -72,81 +65,17 @@ namespace ICSharpCode.ILSpy.Metadata this.Children.Add(new OptionalHeaderTreeNode(module)); this.Children.Add(new DataDirectoriesTreeNode(module)); this.Children.Add(new DebugDirectoryTreeNode(module)); - if (ShowTable(TableIndex.Module)) - this.Children.Add(new ModuleTableTreeNode(module)); - if (ShowTable(TableIndex.TypeRef)) - this.Children.Add(new TypeRefTableTreeNode(module)); - if (ShowTable(TableIndex.TypeDef)) - this.Children.Add(new TypeDefTableTreeNode(module)); - if (ShowTable(TableIndex.Field)) - this.Children.Add(new FieldTableTreeNode(module)); - if (ShowTable(TableIndex.MethodDef)) - this.Children.Add(new MethodTableTreeNode(module)); - if (ShowTable(TableIndex.Param)) - this.Children.Add(new ParamTableTreeNode(module)); - if (ShowTable(TableIndex.InterfaceImpl)) - this.Children.Add(new InterfaceImplTableTreeNode(module)); - if (ShowTable(TableIndex.MemberRef)) - this.Children.Add(new MemberRefTableTreeNode(module)); - if (ShowTable(TableIndex.Constant)) - this.Children.Add(new ConstantTableTreeNode(module)); - if (ShowTable(TableIndex.CustomAttribute)) - this.Children.Add(new CustomAttributeTableTreeNode(module)); - if (ShowTable(TableIndex.FieldMarshal)) - this.Children.Add(new FieldMarshalTableTreeNode(module)); - if (ShowTable(TableIndex.DeclSecurity)) - this.Children.Add(new DeclSecurityTableTreeNode(module)); - if (ShowTable(TableIndex.ClassLayout)) - this.Children.Add(new ClassLayoutTableTreeNode(module)); - if (ShowTable(TableIndex.FieldLayout)) - this.Children.Add(new FieldLayoutTableTreeNode(module)); - if (ShowTable(TableIndex.StandAloneSig)) - this.Children.Add(new StandAloneSigTableTreeNode(module)); - if (ShowTable(TableIndex.EventMap)) - this.Children.Add(new EventMapTableTreeNode(module)); - if (ShowTable(TableIndex.Event)) - this.Children.Add(new EventTableTreeNode(module)); - if (ShowTable(TableIndex.PropertyMap)) - this.Children.Add(new PropertyMapTableTreeNode(module)); - if (ShowTable(TableIndex.Property)) - this.Children.Add(new PropertyTableTreeNode(module)); - if (ShowTable(TableIndex.MethodSemantics)) - this.Children.Add(new MethodSemanticsTableTreeNode(module)); - if (ShowTable(TableIndex.MethodImpl)) - this.Children.Add(new MethodImplTableTreeNode(module)); - if (ShowTable(TableIndex.ModuleRef)) - this.Children.Add(new ModuleRefTableTreeNode(module)); - if (ShowTable(TableIndex.TypeSpec)) - this.Children.Add(new TypeSpecTableTreeNode(module)); - if (ShowTable(TableIndex.ImplMap)) - this.Children.Add(new ImplMapTableTreeNode(module)); - if (ShowTable(TableIndex.FieldRva)) - this.Children.Add(new FieldRVATableTreeNode(module)); - if (ShowTable(TableIndex.Assembly)) - this.Children.Add(new AssemblyTableTreeNode(module)); - if (ShowTable(TableIndex.AssemblyRef)) - this.Children.Add(new AssemblyRefTableTreeNode(module)); - if (ShowTable(TableIndex.File)) - this.Children.Add(new FileTableTreeNode(module)); - if (ShowTable(TableIndex.ExportedType)) - this.Children.Add(new ExportedTypeTableTreeNode(module)); - if (ShowTable(TableIndex.ManifestResource)) - this.Children.Add(new ManifestResourceTableTreeNode(module)); - if (ShowTable(TableIndex.NestedClass)) - this.Children.Add(new NestedClassTableTreeNode(module)); - if (ShowTable(TableIndex.GenericParam)) - this.Children.Add(new GenericParamTableTreeNode(module)); - if (ShowTable(TableIndex.MethodSpec)) - this.Children.Add(new MethodSpecTableTreeNode(module)); - if (ShowTable(TableIndex.GenericParamConstraint)) - this.Children.Add(new GenericParamConstraintTableTreeNode(module)); - - bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || module.Metadata.GetTableRowCount(table) > 0; + this.Children.Add(new MetadataTablesTreeNode(module)); + this.Children.Add(new StringHeapTreeNode(module, module.Metadata)); + this.Children.Add(new UserStringHeapTreeNode(module, module.Metadata)); + this.Children.Add(new GuidHeapTreeNode(module, module.Metadata)); + this.Children.Add(new BlobHeapTreeNode(module, module.Metadata)); } public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind) { - return this.Children.OfType().SingleOrDefault(x => x.Kind == kind); + return this.Children.OfType().Single() + .Children.OfType().SingleOrDefault(x => x.Kind == kind); } }