Replaces the special-cased OverlayImage (accessibility/static/extension)
and the two-layer PairOverlayImage (Reference/Export overlays) with one
N-layer LayeredImage that supports an optional base scale.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Existing assembly fixtures (BCL System.Linq, System.Net.Http, mscorlib)
do not have module references, so this slice is wired and exercised by
the existing References-folder tests but not directly asserted.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Added two new headless tests in MainWindowTests:
- Back_Navigation_Restores_Previously_Selected_Node — selects two methods on
Enumerable, executes DockWorkspace.NavigateBackCommand, asserts the original
node is reselected, decompiled text reverts, and the row is centred.
- Opening_Assembly_Adds_It_To_The_Tree — drives the production OpenCommand via
MainMenuCommandRegistry (matched by Resources._Open header), confirms the
new LoadedAssembly appears, the AssemblyTreeNode is reachable by short name,
and SharpTreeNode.IsSelected is set on the freshly opened node.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Restructure the Avalonia AssemblyTreeModel so its task layout matches the WPF
host, both for readability when cross-referencing the two trees during the
port and so future WPF changes can be ported mechanically. New surface (all
mirrored from ILSpy/AssemblyTree/AssemblyTreeModel.cs):
Assisted-by: Claude:claude-opus-4-7:Claude Code
CenterRowInView calls DataGrid.ScrollIntoView and then reads the row's bounds
to compute the offset that puts it on the viewport mid-line. ScrollIntoView
only updates ScrollViewer.Offset though; the new DataGridRow shows up on the
next layout pass. When the target row was outside the current viewport (e.g.
back-navigation across distant selections), the lookup ran before that pass
and returned null, so the centring step bailed and the offset stayed where it
was. Force the layout pass with TreeGrid.UpdateLayout() so the row is realised
synchronously.
Assisted-by: Claude:claude-opus-4-7:Claude Code
DecompileAsEnumerableTest exercises the full path: open mscorlib, navigate
to Enumerable.AsEnumerable, render the decompilation, verify text and
verify the row centred in the assembly tree. Writing it surfaced two
pre-existing bugs the manual smoke-test missed:
File / View / Window / Help built from MEF main-menu commands plus a static
View submenu (API visibility, Theme = Light/Dark via Application.RequestedThemeVariant,
UI Language) bound to LanguageSettings on SessionSettings. Window menu also lists
the existing tool-pane toggles. Commands without ported deps (Options, About,
Updates, GAC, manage lists, save/PDB) surface a "not yet ported" stub dialog.
Open uses Avalonia StorageProvider; CloseAllDocs/ResetLayout call into DockWorkspace.
InputGestureText on the export attribute is parsed into MenuItem.HotKey, giving
Open Ctrl+O / Save Ctrl+S / Reload F5 as window-scoped accelerators.
Assisted-by: Claude:claude-opus-4-7:Claude Code
The renamed Avalonia csproj was referencing the localized strings file
via a sibling-project relative path (..\ILSpy\Properties\Resources.resx)
that resolved into the WPF host's tree. The host is gone now, so the
reference is dangling.
Subscribes to AvaloniaEdit's PointerHoverEvent / PointerHoverStoppedEvent
on the inner TextView and resolves the segment under the live pointer at
hover-fire time. Same pattern WPF ILSpy uses on AvalonEdit's MouseHover.
Assisted-by: Claude:claude-opus-4-7:Claude Code
The decompiler ships a number of Debug.Assert calls that fire on real-world
but unusual IL (e.g. method-body shapes the constructor-initializer transform
doesn't expect). Without a custom listener those terminate the process via
the default trace listener's UI, making any non-trivial decompile crash the
Avalonia host.
Assisted-by: Claude:claude-opus-4-7:Claude Code
DockWorkspace now keeps a NavigationHistory<SharpTreeNode> and pushes the
selected tree node on each SelectedItem change (rapid <0.5s consecutive
selections collapse so tree refreshes don't pollute the back stack). Back/
Forward themselves suppress recording while they reassign SelectedItem.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Adds Language.GetRichTextTooltip and a CSharpLanguage override that
runs the entity through CSharpHighlightingTokenWriter to produce a
syntax-coloured signature, mirroring the WPF host. The decompiler view
now consumes Avalonia's built-in ToolTip system (PointerHover →
ToolTip.Tip), rendering RichText as Run inlines on a SelectableTextBlock.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Phase 2.2 of the references/tooltips work — clicking a local reference
(parameter, variable, label, ...) highlights every occurrence in the
current document with a colored background. Cross-document references
clear any existing marks before navigating.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Phase 2.1 of the references/tooltips work — click navigation only, no
hover tooltips and no local-reference highlighting yet.
Assisted-by: Claude:claude-opus-4-7:Claude Code
A cancelled decompile used to leave the tab title pointing at the new
node while the editor still showed the previous node's output. Move
Title and SyntaxExtension into the same UI-thread post that publishes
the rendered text, foldings, and highlighting model — so all five land
together when the decompile succeeds, and stay at the previous values
on cancel.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Cancellation flips activeCts.Cancel() but doesn't interrupt the
Task.Run — CSharpDecompiler must reach the next ThrowIfCancellationRequested
before the action returns. The previous finally-less version returned
early on cts.IsCancellationRequested, leaving IsDecompiling = true and
the adorner stuck forever.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Mirrors ILSpy/TextView/DecompilerTextView.xaml's wait-adorner shape: a
translucent overlay above the editor with a centred "Decompiling…"
title, an indeterminate ProgressBar, and a Cancel button. Visibility is
driven by a new IsDecompiling flag on DecompilerTabPageModel, set
around the Task.Run that runs the decompile. The Cancel button is
wired to a [RelayCommand] CancelDecompilation that triggers the
existing CancellationTokenSource.
Assisted-by: Claude:claude-opus-4-7:Claude Code
AvaloniaEditTextOutput now records MarkFoldStart/MarkFoldEnd ranges
into a NewFolding list (skipping single-line ones the way the WPF host
does), and DecompilerTextView installs an AvaloniaEdit FoldingManager
on the TextArea each time a fresh document is applied. Definitions
emit foldings unconditionally; users will get the all-braces flavour
once we expose DecompilerSettings.FoldBraces from the display options.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Wires up CSharpHighlightingTokenWriter so the decompiler view paints
keywords / types / members / parameters in distinct colours, identical
to the WPF host. Supporting changes:
Assisted-by: Claude:claude-opus-4-7:Claude Code
Mirrors the WPF host's light theme, which binds the text background to
SystemColors.InfoColorKey (~#FFFFE1) — the familiar pale-yellow tooltip
colour. Avalonia's SimpleTheme doesn't surface the same key, so set it
literally on the TextEditor.
Assisted-by: Claude:claude-opus-4-7:Claude Code