Fix the "Use nested namespace structure" option#3879
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes missing namespace nodes when “Use nested namespace structure” is enabled by changing how the nested namespace tree is constructed so that intermediate namespace nodes don’t get incorrectly marked hidden during the filter cascade.
Changes:
- Reworked nested namespace construction from a recursive top-down approach to an iterative bottom-up approach.
- Ensured child namespace nodes are attached before their parent is inserted into the next level up, preventing transient “no children” states that could set
IsHidden = true.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var metadata = module.Metadata; | ||
| var types = metadata.TypeDefinitions | ||
| .Where(t => { | ||
| var td = metadata.GetTypeDefinition(t); | ||
| return td.GetDeclaringType().IsNil | ||
| && metadata.GetString(td.Namespace) == fullName; | ||
| }) | ||
| .OrderBy(t => metadata.GetString(metadata.GetTypeDefinition(t).Name), NaturalStringComparer.Instance); | ||
|
|
||
| foreach (var t in types) | ||
| Children.Add(new TypeTreeNode(t, module)); | ||
| var newChildren = new List<(string, ILSpyTreeNode)>(); | ||
| var childNamespaces = new HashSet<string>(StringComparer.Ordinal); | ||
| var useNestedNamespaceNodes = TryGetUseNestedNamespaceNodes(); | ||
| foreach (var t in metadata.TypeDefinitions) |
There was a problem hiding this comment.
@ds5678 I think this is a valid concern... if I remember correctly, the old WPF code handled the namespaces once in AssemblyTreeNode and cached them. Maybe we could get a lazy+cached behavior by moving the logic to AssemblyTreeNode?
|
The display fix looks correct: top-level nodes plus lazy per-node sub-namespace discovery avoids the transient empty-children → One issue that isn't in this diff but that this change surfaces: type and namespace navigation is broken in nested mode.
Repro: with nested mode on, click a hyperlink to Not necessarily a blocker for the display fix itself, but worth a decision: fix navigation here so nested mode is fully functional, or track it as an explicit follow-up? (Review written by an agent on Siegfried's behalf.) |
|
Thoughts on my latest commit? It functionally changes whether or not namespaces get hidden, which is why I'm not sure if it's okay or if we need to solve the problem a different way. |
I strongly care about navigation and want to help fix it. |
@ds5678 sorry for my AI generated comment above, didn't want to be disrespectful. Yes, please, if you could contribute this it would be very nice. Unfortunately, there are still divergencies between 10.1 and master no matter how many times I go over it/or let Claude cross check... IIRC the old behavior was to eagerly construct the namespaces on load... |
Is this still desirable? Without 0df02ac, I get a significant lag the first time I expand the tree view. |
|
Presumably because the current method of populating namespace node children takes N^2 time, where N is the number of types in the module. Note: my module has roughly 17 thousand types. |
Is the performance in 10.1 better? |
Yes, I do not notice any lag in 10.1 |
|
I was referring to 10.1 as the "old behavior". So, if we were going to copy the exact source code in 10.1, would all your problems be solved or did you find more bugs? I guess, AssemblyTreeNode.LoadChildren is not too inefficient on 10.1? |
|
Hey ... I hope you don't mind, that I will restore the structure of the WPF version (release/10.1) where the main handling code is in AssemblyTreeNode and then apply your additional fixes on top of that. So, I'd rebase your PR later... Also, thank you very much for finding and investigating this performance regression. Very much appreciated! |
|
I don't mind at all. Thank you for helping with this. |
In nested-namespace mode a NamespaceTreeNode's display label is only its
last segment ("Generic"), while the full dotted path
("System.Collections.Generic") is what identifies the namespace in
metadata and to the docs site. Three call sites read the label where they
need the full path, so in nested mode each targets the wrong namespace:
decompiling a namespace node queries an empty one and titles the output
after the last segment; the MSDN URL points at the wrong page; and
scope-search-to-namespace scopes to the wrong name.
These are ds5678's fixes from icsharpcode#3879, reintegrated on top of the eager
namespace rebuild. icsharpcode#3879's other Name -> FullName corrections, in
AssemblyTreeNode.FindNamespaceNode and TreeNodeLocator, are already
covered here by the full-namespace-name and type-handle indexes, so only
the Decompile and search-entry cases carry over.
Assisted-by: Claude:claude-opus-4-8:Claude Code
89684d6 to
217fc00
Compare
|
Is there anything you need from me? |
No, thank you for reporting this and drafting a fix! |


Problem
Not all the namespaces are showing when "Use nested namespace structure" is enabled. I think the problem started around the time that the UI was shifted to Avalonia, but I'm not really sure.
Solution
Previously,
IsHiddenwas being calculated astruebecause a namespace node momentarily had no children.This change reverses the order of adding to the tree from Top-Down to Bottom-Up.Follow-up issue
I'm investigating why the namespaces are misordered, or more specifically the best way to fix the ordering.