mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
Keep package entry selections decompilable
The stale-node guard compared selected nodes only against top-level assembly-list entries, so nodes owned by package entries looked removed even while their parent package was active. Walk the parent bundle chain before clearing the decompiler tab so restored or clicked package-entry selections still render. Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
This commit is contained in:
@@ -188,4 +188,24 @@ public class AssemblyTreeModelTests
|
||||
sibling.Children.Should().BeEmpty(
|
||||
"only the folders on the path down to the target get expanded.");
|
||||
}
|
||||
|
||||
[AvaloniaTest]
|
||||
public async Task Selecting_a_type_inside_a_package_entry_decompiles_it()
|
||||
{
|
||||
var (_, vm) = await TestHarness.BootAsync();
|
||||
await vm.OpenAssemblyAsync(CreatePackage());
|
||||
|
||||
var nested = (await vm.AssemblyTreeModel.AssemblyList!.GetAllAssemblies())
|
||||
.Single(a => a.FileName == "lib/net10.0/Nested.dll");
|
||||
var type = nested.GetTypeSystemOrNull()!.MainModule.TypeDefinitions
|
||||
.Single(t => t.Name == FixtureAssembly.TypeName);
|
||||
var node = vm.AssemblyTreeModel.FindTreeNode(type);
|
||||
((object?)node).Should().BeOfType<TypeTreeNode>();
|
||||
|
||||
vm.AssemblyTreeModel.SelectNode(node!);
|
||||
var tab = await vm.DockWorkspace.WaitForDecompiledTextAsync();
|
||||
|
||||
tab.Text.Should().Contain(FixtureAssembly.TypeName,
|
||||
"a live package-entry node must not be mistaken for a stale node from a removed assembly");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,7 +803,7 @@ namespace ICSharpCode.ILSpy.Docking
|
||||
assemblyTreeModel.AssemblyList?.GetAssemblies() ?? []);
|
||||
if (nodes.Any(n => n.AncestorsAndSelf()
|
||||
.OfType<AssemblyTreeNode>()
|
||||
.Any(a => !activeAssemblies.Contains(a.LoadedAssembly))))
|
||||
.Any(a => !IsActiveAssemblyOrPackageEntry(a.LoadedAssembly, activeAssemblies))))
|
||||
{
|
||||
lastShownNodes = null;
|
||||
ClearActiveDecompilerTab();
|
||||
@@ -879,6 +879,17 @@ namespace ICSharpCode.ILSpy.Docking
|
||||
ActivateMainTabIfNeeded(main);
|
||||
}
|
||||
|
||||
static bool IsActiveAssemblyOrPackageEntry(ICSharpCode.ILSpyX.LoadedAssembly assembly,
|
||||
HashSet<ICSharpCode.ILSpyX.LoadedAssembly> activeAssemblies)
|
||||
{
|
||||
for (var current = assembly; current != null; current = current.ParentBundle)
|
||||
{
|
||||
if (activeAssemblies.Contains(current))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// The "exactly one preview tab" rule: tree selections always route to the single preview
|
||||
// ("the One"), tracked by factory.MainTab. Reuse it wherever it sits -- even if a frozen
|
||||
// tab is currently active, ActivateMainTabIfNeeded brings it forward -- as long as it is
|
||||
|
||||
Reference in New Issue
Block a user