mirror of https://github.com/icsharpcode/ILSpy.git
Browse Source
Adds the assembly tree pane (DataGrid-based, ProDataGrid hierarchical rows), the SharpTreeNode-derived node type skeletons it consumes, the empty MainToolBar placeholder, the ILSpySettings file-path provider wiring in App.axaml.cs, and the AssemblyTreeModel.Initialize() hook in the MainWindow code-behind. Assisted-by: Claude:claude-opus-4-7:Claude Codepull/3755/head
13 changed files with 582 additions and 4 deletions
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using Avalonia.Headless.NUnit; |
||||
|
||||
using AwesomeAssertions; |
||||
|
||||
using ILSpy.AppEnv; |
||||
using ILSpy.AssemblyTree; |
||||
|
||||
using NUnit.Framework; |
||||
|
||||
namespace ICSharpCode.ILSpy.Tests.AssemblyTree; |
||||
|
||||
// AssemblyTreeModel is the MEF-shared root of the assembly tree. Initialize() loads
|
||||
// (or creates) the default assembly list from settings, optionally bootstraps it with
|
||||
// the three .NET runtime assemblies, and wires Root to an AssemblyListTreeNode. If
|
||||
// either AssemblyList or Root stays null, the entire pane below is blank — which is
|
||||
// hard to debug from a UI snapshot, so we catch it at the model layer here.
|
||||
[TestFixture] |
||||
public class AssemblyTreeModelTests |
||||
{ |
||||
[AvaloniaTest] |
||||
public void Initialize_populates_AssemblyList_and_Root() |
||||
{ |
||||
var model = AppComposition.Current.GetExport<AssemblyTreeModel>(); |
||||
model.Should().NotBeNull("AssemblyTreeModel is [Export][Shared] in ILSpy.AssemblyTree."); |
||||
|
||||
model.Initialize(); |
||||
|
||||
model.AssemblyList.Should().NotBeNull("Initialize loads or creates the default AssemblyList."); |
||||
model.Root.Should().NotBeNull("Initialize wires Root to an AssemblyListTreeNode of the loaded list."); |
||||
} |
||||
} |
||||
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||
xmlns:tree="using:ILSpy.AssemblyTree" |
||||
mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="450" |
||||
x:Class="ILSpy.AssemblyTree.AssemblyListPane" |
||||
x:DataType="tree:AssemblyTreeModel"> |
||||
|
||||
<DataGrid Name="TreeGrid" |
||||
HeadersVisibility="None" |
||||
HierarchicalRowsEnabled="True" |
||||
GridLinesVisibility="None" |
||||
IsReadOnly="True" |
||||
CanUserResizeColumns="False" |
||||
SelectionMode="Single"> |
||||
<DataGrid.Columns> |
||||
<DataGridTemplateColumn Header="Name" Width="*"> |
||||
<DataGridTemplateColumn.CellTemplate> |
||||
<DataTemplate> |
||||
<TextBlock Text="{ReflectionBinding Item.Text}" |
||||
VerticalAlignment="Center" Margin="4,0" /> |
||||
</DataTemplate> |
||||
</DataGridTemplateColumn.CellTemplate> |
||||
</DataGridTemplateColumn> |
||||
</DataGrid.Columns> |
||||
</DataGrid> |
||||
</UserControl> |
||||
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections; |
||||
using System.ComponentModel; |
||||
|
||||
using Avalonia.Controls; |
||||
using Avalonia.Controls.DataGridHierarchical; |
||||
|
||||
using ICSharpCode.ILSpyX.TreeView; |
||||
|
||||
namespace ILSpy.AssemblyTree |
||||
{ |
||||
public partial class AssemblyListPane : UserControl |
||||
{ |
||||
public AssemblyListPane() |
||||
{ |
||||
InitializeComponent(); |
||||
} |
||||
|
||||
protected override void OnDataContextChanged(System.EventArgs e) |
||||
{ |
||||
base.OnDataContextChanged(e); |
||||
|
||||
if (DataContext is AssemblyTreeModel model) |
||||
{ |
||||
model.PropertyChanged += Model_PropertyChanged; |
||||
if (model.Root != null) |
||||
BindTree(model.Root); |
||||
} |
||||
} |
||||
|
||||
void Model_PropertyChanged(object? sender, PropertyChangedEventArgs e) |
||||
{ |
||||
if (e.PropertyName == nameof(AssemblyTreeModel.Root) && sender is AssemblyTreeModel model && model.Root != null) |
||||
BindTree(model.Root); |
||||
} |
||||
|
||||
void BindTree(SharpTreeNode root) |
||||
{ |
||||
var options = new HierarchicalOptions<SharpTreeNode> { |
||||
ChildrenSelector = node => node.Children, |
||||
IsLeafSelector = node => !node.ShowExpander, |
||||
IsExpandedSelector = node => node.IsExpanded, |
||||
IsExpandedSetter = (node, val) => node.IsExpanded = val, |
||||
AutoExpandRoot = true, |
||||
}; |
||||
|
||||
var hierarchicalModel = new HierarchicalModel<SharpTreeNode>(options); |
||||
hierarchicalModel.SetRoots((IEnumerable)root.Children); |
||||
|
||||
TreeGrid.HierarchicalModel = hierarchicalModel; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Composition; |
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel; |
||||
|
||||
using ICSharpCode.ILSpyX; |
||||
using ICSharpCode.ILSpyX.Settings; |
||||
using ICSharpCode.ILSpyX.TreeView; |
||||
|
||||
using ILSpy.TreeNodes; |
||||
|
||||
namespace ILSpy.AssemblyTree |
||||
{ |
||||
[Export] |
||||
[Shared] |
||||
public partial class AssemblyTreeModel : ObservableObject |
||||
{ |
||||
[ObservableProperty] |
||||
private SharpTreeNode? root; |
||||
|
||||
[ObservableProperty] |
||||
private SharpTreeNode? selectedItem; |
||||
|
||||
public AssemblyList? AssemblyList { get; private set; } |
||||
|
||||
public void Initialize() |
||||
{ |
||||
var settings = ILSpySettings.Load(); |
||||
var listManager = new AssemblyListManager(settings); |
||||
listManager.CreateDefaultAssemblyLists(); |
||||
|
||||
AssemblyList = listManager.LoadList(AssemblyListManager.DefaultListName); |
||||
|
||||
if (AssemblyList.GetAssemblies().Length == 0) |
||||
LoadInitialAssemblies(AssemblyList); |
||||
|
||||
var rootNode = new AssemblyListTreeNode(AssemblyList); |
||||
rootNode.IsExpanded = true; |
||||
Root = rootNode; |
||||
} |
||||
|
||||
static void LoadInitialAssemblies(AssemblyList assemblyList) |
||||
{ |
||||
System.Reflection.Assembly[] initialAssemblies = { |
||||
typeof(object).Assembly, |
||||
typeof(Uri).Assembly, |
||||
typeof(System.Linq.Enumerable).Assembly, |
||||
}; |
||||
foreach (var asm in initialAssemblies) |
||||
{ |
||||
if (!string.IsNullOrEmpty(asm.Location)) |
||||
assemblyList.OpenAssembly(asm.Location); |
||||
} |
||||
} |
||||
|
||||
public void OpenAssembly(string path) |
||||
{ |
||||
AssemblyList?.Open(path); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Collections.Specialized; |
||||
using System.Linq; |
||||
|
||||
using ICSharpCode.ILSpyX; |
||||
|
||||
namespace ILSpy.TreeNodes |
||||
{ |
||||
sealed class AssemblyListTreeNode : ILSpyTreeNode |
||||
{ |
||||
readonly AssemblyList assemblyList; |
||||
|
||||
public AssemblyList AssemblyList => assemblyList; |
||||
|
||||
public AssemblyListTreeNode(AssemblyList assemblyList) |
||||
{ |
||||
ArgumentNullException.ThrowIfNull(assemblyList); |
||||
this.assemblyList = assemblyList; |
||||
|
||||
Children.AddRange(assemblyList.GetAssemblies().Select(a => new AssemblyTreeNode(a))); |
||||
|
||||
assemblyList.CollectionChanged += (_, e) => { |
||||
switch (e.Action) |
||||
{ |
||||
case NotifyCollectionChangedAction.Add: |
||||
Children.InsertRange(e.NewStartingIndex, e.NewItems!.Cast<LoadedAssembly>().Select(a => new AssemblyTreeNode(a))); |
||||
break; |
||||
case NotifyCollectionChangedAction.Remove: |
||||
Children.RemoveRange(e.OldStartingIndex, e.OldItems!.Count); |
||||
break; |
||||
case NotifyCollectionChangedAction.Reset: |
||||
Children.Clear(); |
||||
Children.AddRange(assemblyList.GetAssemblies().Select(a => new AssemblyTreeNode(a))); |
||||
break; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
public override object Text => assemblyList.ListName; |
||||
} |
||||
} |
||||
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Linq; |
||||
|
||||
using ICSharpCode.Decompiler.Metadata; |
||||
using ICSharpCode.ILSpyX; |
||||
|
||||
namespace ILSpy.TreeNodes |
||||
{ |
||||
sealed class AssemblyTreeNode : ILSpyTreeNode |
||||
{ |
||||
readonly LoadedAssembly assembly; |
||||
|
||||
public LoadedAssembly LoadedAssembly => assembly; |
||||
|
||||
public AssemblyTreeNode(LoadedAssembly assembly) |
||||
{ |
||||
ArgumentNullException.ThrowIfNull(assembly); |
||||
this.assembly = assembly; |
||||
LazyLoading = true; |
||||
} |
||||
|
||||
public override object Text => assembly.ShortName; |
||||
|
||||
protected override void LoadChildren() |
||||
{ |
||||
var result = assembly.GetMetadataFileOrNullAsync().Result; |
||||
if (result is not MetadataFile module) |
||||
return; |
||||
|
||||
var metadata = module.Metadata; |
||||
var namespaces = metadata.TypeDefinitions |
||||
.Where(t => metadata.GetTypeDefinition(t).GetDeclaringType().IsNil) |
||||
.Select(t => metadata.GetString(metadata.GetTypeDefinition(t).Namespace)) |
||||
.Where(ns => !string.IsNullOrEmpty(ns)) |
||||
.Distinct() |
||||
.OrderBy(ns => ns); |
||||
|
||||
foreach (var ns in namespaces) |
||||
Children.Add(new NamespaceTreeNode(ns, module)); |
||||
|
||||
var globalTypes = metadata.TypeDefinitions |
||||
.Where(t => { |
||||
var td = metadata.GetTypeDefinition(t); |
||||
return td.GetDeclaringType().IsNil |
||||
&& string.IsNullOrEmpty(metadata.GetString(td.Namespace)); |
||||
}); |
||||
|
||||
foreach (var t in globalTypes) |
||||
Children.Add(new TypeTreeNode(t, module)); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using ICSharpCode.ILSpyX.TreeView; |
||||
|
||||
namespace ILSpy.TreeNodes |
||||
{ |
||||
public abstract class ILSpyTreeNode : SharpTreeNode |
||||
{ |
||||
} |
||||
} |
||||
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace ILSpy.TreeNodes |
||||
{ |
||||
sealed class MemberTreeNode : ILSpyTreeNode |
||||
{ |
||||
readonly string name; |
||||
|
||||
public MemberTreeNode(string name) |
||||
{ |
||||
this.name = name; |
||||
} |
||||
|
||||
public override object Text => name; |
||||
public override bool ShowExpander => false; |
||||
} |
||||
} |
||||
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Linq; |
||||
using System.Reflection.Metadata; |
||||
|
||||
using ICSharpCode.Decompiler.Metadata; |
||||
|
||||
namespace ILSpy.TreeNodes |
||||
{ |
||||
sealed class NamespaceTreeNode : ILSpyTreeNode |
||||
{ |
||||
readonly string name; |
||||
readonly MetadataFile module; |
||||
|
||||
public string Name => name; |
||||
|
||||
public NamespaceTreeNode(string name, MetadataFile module) |
||||
{ |
||||
this.name = name; |
||||
this.module = module; |
||||
LazyLoading = true; |
||||
} |
||||
|
||||
public override object Text => name; |
||||
|
||||
protected override void LoadChildren() |
||||
{ |
||||
var metadata = module.Metadata; |
||||
var types = metadata.TypeDefinitions |
||||
.Where(t => { |
||||
var td = metadata.GetTypeDefinition(t); |
||||
return td.GetDeclaringType().IsNil |
||||
&& metadata.GetString(td.Namespace) == name; |
||||
}) |
||||
.OrderBy(t => metadata.GetString(metadata.GetTypeDefinition(t).Name)); |
||||
|
||||
foreach (var t in types) |
||||
Children.Add(new TypeTreeNode(t, module)); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Linq; |
||||
using System.Reflection.Metadata; |
||||
|
||||
using ICSharpCode.Decompiler.Metadata; |
||||
|
||||
namespace ILSpy.TreeNodes |
||||
{ |
||||
sealed class TypeTreeNode : ILSpyTreeNode |
||||
{ |
||||
readonly TypeDefinitionHandle handle; |
||||
readonly MetadataFile module; |
||||
|
||||
public TypeDefinitionHandle Handle => handle; |
||||
public MetadataFile Module => module; |
||||
|
||||
public TypeTreeNode(TypeDefinitionHandle handle, MetadataFile module) |
||||
{ |
||||
this.handle = handle; |
||||
this.module = module; |
||||
LazyLoading = true; |
||||
} |
||||
|
||||
public override object Text { |
||||
get { |
||||
var td = module.Metadata.GetTypeDefinition(handle); |
||||
return module.Metadata.GetString(td.Name); |
||||
} |
||||
} |
||||
|
||||
protected override void LoadChildren() |
||||
{ |
||||
var td = module.Metadata.GetTypeDefinition(handle); |
||||
|
||||
foreach (var nestedType in td.GetNestedTypes()) |
||||
Children.Add(new TypeTreeNode(nestedType, module)); |
||||
|
||||
foreach (var method in td.GetMethods()) |
||||
{ |
||||
var md = module.Metadata.GetMethodDefinition(method); |
||||
Children.Add(new MemberTreeNode(module.Metadata.GetString(md.Name))); |
||||
} |
||||
|
||||
foreach (var field in td.GetFields()) |
||||
{ |
||||
var fd = module.Metadata.GetFieldDefinition(field); |
||||
Children.Add(new MemberTreeNode(module.Metadata.GetString(fd.Name))); |
||||
} |
||||
|
||||
foreach (var prop in td.GetProperties()) |
||||
{ |
||||
var pd = module.Metadata.GetPropertyDefinition(prop); |
||||
Children.Add(new MemberTreeNode(module.Metadata.GetString(pd.Name))); |
||||
} |
||||
|
||||
foreach (var evt in td.GetEvents()) |
||||
{ |
||||
var ed = module.Metadata.GetEventDefinition(evt); |
||||
Children.Add(new MemberTreeNode(module.Metadata.GetString(ed.Name))); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue