mirror of https://github.com/icsharpcode/ILSpy.git
Branch:
fix/lambda-parameter-syntax
christophwille/closedhierarchies
christophwille/membench
compound-assignment-operators
fix/1982-params-attribute-args
fix/2040-invalid-xml-characters
fix/2093-navigateto-reference-assembly
fix/2362-xalz-references
fix/2372-address-taken-by
fix/3282-indexer-optional-arguments
fix/3568-record-member-order
fix/4059-deconstruct-out-slots
fix/lambda-parameter-syntax
fix/scroll-children-on-expand
gh-pages
ldmembertoken
master
natural-type-lambdas-methods
null-coalescing-assignment
release/10.1
release/6.2
release/7.1
release/7.2
release/8.1
substring-optimizations
tests/829-async-method-builder-override
tests/829-collection-expressions
tests/829-compound-assignment-operators
tests/829-coverage-audit
tests/829-expression-tree-named-optional-args
tests/829-expression-variables-in-initializers
tests/829-extended-property-patterns
tests/829-extension-members
tests/829-extension-operators
tests/829-file-local-types
tests/829-improved-definite-assignment
tests/829-improved-overload-candidates
tests/829-inline-arrays
tests/829-interpolated-string-improvements
tests/829-lambda-param-modifiers
tests/829-list-patterns
tests/829-lock-object
tests/829-mixed-deconstruction
tests/829-null-coalescing-assignment
tests/829-null-conditional-assignment
tests/829-object-initializer-indexer
tests/829-overload-resolution-priority
tests/829-params-collections
tests/829-pattern-matching-improvements
tests/829-primary-constructors
tests/829-ref-unsafe-in-iterators-async
tests/829-sealed-record-tostring
tests/829-target-typed-conditional
tests/829-tuple-comparison
win-a11y-textsize
1.0-Beta
1.0-M1
1.0-M2
1.0-M3
1.0.0
2.0.0
2.1
2.2
2.3
2.3.1
3.0-Preview1
3.0-Preview2
3.0.2
v10.0
v10.0-preview1
v10.0-preview2
v10.0-preview3
v10.0.1
v10.1
v10.1.1
v11.0
v11.0-preview1
v11.0-rc
v2.3.2
v2.4
v3.0
v3.0-beta1
v3.0-beta2
v3.0-beta2a
v3.0-beta3
v3.0-beta4
v3.0.1
v3.1-beta1
v3.1-final
v3.1-rc
v3.2-beta
v3.2-rc
v3.2.0
v4.0
v4.0-alpha1
v4.0-beta1
v4.0-beta2
v4.0-beta3
v4.0-rc1
v4.0-rc2
v4.0.1
v5.0
v5.0-preview1
v5.0-preview2
v5.0-preview3
v5.0-preview4
v5.0-rc1
v5.0.1
v5.0.2
v6.0
v6.0-preview1
v6.0-preview2
v6.0-preview3
v6.0-preview4
v6.0-rc1
v6.1
v6.2
v6.2-preview1
v6.2-preview2
v6.2.1
v7.0
v7.0-preview1
v7.0-preview2
v7.0-preview3
v7.0-rc1
v7.0-rc2
v7.1
v7.2
v7.2-preview1
v7.2-preview2
v7.2-preview3
v7.2-preview4
v7.2-rc
v7.2.1
v8.0
v8.0-preview1
v8.0-preview2
v8.0-preview3
v8.0-preview4
v8.0-rc1
v8.1
v8.1.1
v8.2
v9.0
v9.0-preview1
v9.0-preview2
v9.0-preview3
v9.0-rc
v9.1
${ item.name }
${ noResults }
1 Commits (fix/lambda-parameter-syntax)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
640b968b59 |
Rebuild the assembly-tree namespaces eagerly, as the WPF host did
With "Use nested namespace structure" enabled, most namespaces never appeared in the tree, and the first expand of a large assembly lagged. Both come from the same regression: the Avalonia assembly-tree nodes were written from scratch as lazy scaffolding, not ported from the WPF design, and lost the single eager build the WPF host used. A NamespaceTreeNode filters as Recurse/MatchAndRecurse, so the filter cascade computes its IsHidden as "all children hidden" -- vacuously true for an empty child set. The lazy build attached each namespace node while it was still empty, latching intermediate namespaces (those that hold only sub-namespaces, e.g. System.Collections) hidden and stranding everything beneath them. The cascade also force-loads every namespace node's children anyway, so the per-node laziness avoided no work: it rescanned the whole TypeDefinitions table once per namespace node. Restore release/10.1's structure: AssemblyTreeNode builds the entire namespace band in one pass over the module's top-level types, populates each node before attaching it, and keeps two indexes -- full namespace name -> node and type handle -> node -- so FindNamespaceNode/FindTypeNode are O(1) and correct at any nesting depth. TreeNodeLocator.FindTypeNode (hyperlink clicks, search activation, JumpToType) delegates to that index instead of walking children by display name, which never matched in nested mode. NamespaceTreeNode goes back to a dumb label holder and re-escapes its display label via ILAmbience.EscapeName. The band is built from the module's type system, like 10.1's, not from raw metadata: each TypeTreeNode holds the resolved ITypeDefinition it renders from, so painting a cell no longer re-enters the settings-keyed type-system cache the way master's lazy node did on every Text/Icon/ Filter read -- each of which rebuilt an effective-settings object and took its lock. Ordering the pass by full ReflectionName is also what interleaves a namespace's types and its sub-namespaces into one alphabetical run (a sub-namespace attaches when its first descendant type is reached, landing at its own alphabetical slot among the sibling types); grouping all types ahead of all namespaces was a visible departure from the WPF order. Two deliberate departures from a literal 10.1 copy: keep the global- namespace "-" node, and keep the cached IsPublicAPI getter. Both index dictionaries are cleared on rebuild so a nested/flat toggle leaves no stale entries. Holding resolved entities means the tree has to be rebuilt when a setting changes the type system. Only one compilation is cached per module, keyed on the effective decompiler settings, so a language- version or decompiler-option change drops it and would otherwise leave every node pointing at a discarded compilation -- stale labels, icons and filters, and the C# 14 extension-block nodes shown against the wrong version. AssemblyTreeModel reloads the loaded assemblies when the computed TypeSystemOptions actually change (Display-only settings never do, and cost nothing), then restores the selected node from its path -- which re-expands its ancestors on the way to revealing it -- the way Refresh does. The WPF host got this for free: its modal Options dialog rebuilt the tree on close, where the Avalonia page applies live. Assisted-by: Claude:claude-opus-4-8:Claude Code |
2 months ago |