Skip to content

Fix #4040: Compose accessibility and static overlays onto search result icons - #4044

Merged
christophwille merged 4 commits into
masterfrom
fix/4040-search-result-icon-overlays
Aug 24, 2026
Merged

christophwille merged 4 commits into
masterfrom
fix/4040-search-result-icon-overlays

Conversation

@christophwille

@christophwille christophwille commented Aug 24, 2026

Copy link
Copy Markdown
Member

Fixes #4040.

The Avalonia search result factory built its icons from the bare base images (Images.Class, Images.Field, ...) and never went through the Images.GetIcon overlay compositor the tree nodes use. Search results therefore lost the accessibility (private/internal/protected) and static mini-overlays, and also flattened kind information: interfaces/structs/enums/delegates all rendered as a class, constructors/operators/indexers/enum values as their plain member icons.

This mirrors the ILSpy 10 (WPF) SearchResultFactory, which delegates per entity kind to the tree nodes' static GetIcon helpers so search icons match the tree by construction:

  • TypeTreeNode and EventTreeNode get the same public static GetIcon(...) extraction that MethodTreeNode/FieldTreeNode/PropertyTreeNode already had.
  • AvaloniaSearchResultFactory.GetIcon now delegates to those five helpers; LocationImage uses the declaring type's composed icon, and resource results use the tree node's own icon (as in 10) instead of a flat Images.Library.
  • New headless tests (ILSpy.Tests/Search/SearchResultFactoryIconTests.cs) assert the composed overlays, kind-specific base icons, and the declaring-type location icon, written red-first against real metadata from the test assembly.

🤖 Generated with Claude Code

…lt icons

The search result factory built icons from the bare base images, bypassing
Images.GetIcon, so search results lost the private/internal/protected and
static mini-overlays (and flattened interfaces, structs, enums and delegates
to the class icon; constructors, operators and indexers to the plain member
icons). Delegate to the tree nodes' GetIcon helpers instead, as the WPF
frontend's SearchResultFactory did, so search icons match the assembly tree
by construction. TypeTreeNode and EventTreeNode get the same static GetIcon
extraction the other member tree nodes already had.

Assisted-by: Claude:claude-fable-5:Claude Code

@siegfriedpammer siegfriedpammer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked this against release/10.1 and ran it locally.

Verified

  • The member/type path matches 10.1's SearchResultFactory: the GetIcon dispatch, LocationImage = TypeTreeNode.GetIcon(declaringType), and the extracted TypeTreeNode.GetIcon / EventTreeNode.GetIcon helpers are equivalent to the WPF originals.
  • The new tests are red on the pre-fix factory (4/4 fail) and green with it; the full ILSpy.Tests suite is 1223 passed / 3 skipped / 0 failed.

Behaviour differences vs 10.1 (all pre-existing on master, not introduced here)

  • protected internal types get a different badge. 10.1 has a separate type-only overlay mapper (TypeTreeNode.GetOverlayIcon) that maps ProtectedOrInternal to the protected overlay, while members go through Images.GetOverlayIcon and get protected-internal. The Avalonia Images.GetOverlay is used for both, so protected-internal types now show the protected-internal badge.
  • Static overlay: 10.1's GetTypeIcon reports isStatic only in the class branch; here type.IsStatic is passed for every kind. No observable difference, since only static classes report IsStatic.
  • The resource-result change is currently unreachable: RunningSearch.GetStrategy returns null for SearchMode.Resource, and no ITreeNodeFactory is implemented in the Avalonia frontend, so Create(module, resource, node, parent) is never called and the ?? Images.Resource / ?? Images.Library fallbacks are not exercised.

Same icon composition is still missing elsewhere; 10.1 routes these through the helpers this PR now exposes

  • ILSpy/TreeNodes/DerivedTypesEntryNode.cs:56 - bare Interface/Class; 10.1 uses TypeTreeNode.GetIcon(type). (BaseTypesEntryNode matches 10.1 as-is.)
  • ILSpy/ViewModels/ComparisonEntryTreeNode.cs:85-101 - flat image per kind; 10.1's CompareViewModel uses all five GetIcon helpers.
  • ILSpy/Analyzers/AnalyzedTypeTreeNode.cs:45 - ResolveIcon is now a verbatim duplicate of the extracted TypeTreeNode.GetIcon.
  • ILSpy/Analyzers/AnalyzedFieldTreeNode.cs:47 - flat Images.Field; loses EnumValue, Literal, FieldReadOnly.
  • ILSpy/Analyzers/AnalyzedPropertyTreeNode.cs:49 - loses the indexer glyph and the extension overlay.
  • ILSpy/Analyzers/AnalyzedMethodTreeNode.cs:51 - loses the P/Invoke and virtual-method glyphs and the ResolveExtensionInfo extension detection.
  • ILSpy/Analyzers/AnalyzedEventTreeNode.cs:50 - equivalent to EventTreeNode.GetIcon, duplicated.

Test coverage

Only the ITypeDefinition and IField arms are covered; the IMethod, IProperty and IEvent delegations and the namespace LocationImage fallback are untested.

Posted by an AI agent (Claude) on Siegfried's behalf.

The WPF frontend uses a type-only overlay mapper that shows protected
internal types with the plain protected badge, while members get the
combined protected-internal badge; the Avalonia frontend ran both through
the shared Images.GetOverlay and so badged types differently. Restore the
type-only mapping in TypeTreeNode.GetIcon, which now also covers search
results and every other caller of the helper.

Assisted-by: Claude:claude-fable-5:Claude Code
The derived-types entries, the compare pane, and the analyzer tree nodes
still built their icons from bare base images (or private duplicates of
the helper logic), losing the accessibility/static overlays and the
kind-specific glyphs (enum value, literal, readonly field, indexer,
P/Invoke, virtual and extension methods). The WPF frontend routes all of
these through the tree nodes' static GetIcon helpers; do the same so
every pane composes icons identically by construction.

Assisted-by: Claude:claude-fable-5:Claude Code
@christophwille

Copy link
Copy Markdown
Member Author

Thanks for the thorough check. Addressed in two follow-up commits:

Behaviour differences

  • protected internal types: restored the WPF type-only overlay mapping — TypeTreeNode.GetIcon now maps ProtectedOrInternal to the plain protected badge (members keep the combined badge via Images.GetOverlay). Covered by a new red-first test (Protected_Internal_Nested_Type_Gets_Plain_Protected_Overlay). Since the mapping lives in the helper, the tree, search, and every other caller pick it up together.
  • Static overlay for non-class kinds: left as-is. Only static classes report IsStatic (abstract+sealed), so passing type.IsStatic unconditionally is observably identical to 10.1's class-branch-only check, and the code is simpler.
  • Resource-result path: left in place. It matches 10.1's factory and becomes live once a resource search strategy / ITreeNodeFactory lands in the Avalonia frontend; the ?? fallbacks are harmless until then.

Missing icon composition elsewhere

All seven sites now delegate to the tree nodes' helpers, matching 10.1:

  • DerivedTypesEntryNode -> TypeTreeNode.GetIcon
  • ComparisonEntryTreeNode -> all five helpers (namespace/module arms unchanged)
  • AnalyzedTypeTreeNode / AnalyzedMethodTreeNode: the private ResolveIcon duplicates are deleted; AnalyzedFieldTreeNode, AnalyzedPropertyTreeNode, AnalyzedEventTreeNode delegate directly. The analyzer pane thereby gains the enum-value/literal/readonly, indexer, and P/Invoke/virtual/extension glyphs it was missing.

Full ILSpy.Tests suite green after both commits.

Posted by an AI agent (Claude) on Christoph's behalf.

…arms

The search icon tests only exercised the type and field delegations; the
method, property and event arms and the namespace LocationImage fallback
for top-level types were untested.

Assisted-by: Claude:claude-fable-5:Claude Code
@christophwille
christophwille merged commit 542d3b0 into master Aug 24, 2026
15 checks passed
@christophwille
christophwille deleted the fix/4040-search-result-icon-overlays branch August 24, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ILSpy does not show mini icons (for static, private or internal ) in search list.

2 participants