9972 Commits
Author SHA1 Message Date
Christoph Wille 7efd079adc Guard same-value SetActiveDockable in the dock factory
Dock's ActiveDockable setter re-runs InitActiveDockable, and with it
SetFocusedDockable, even when the value does not change, so activating
the already-active document moved the active-pane highlight to the
documents dock. Two callers guarded against that individually; the
factory override does it for every caller, and ActivateAndFocus keeps
its explicit SetFocusedDockable for the callers that do want the focus.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-06 08:24:20 +02:00
Christoph Wille 95576cb9e1 Focus a programmatically selected tree row only if the tree owns focus
The tree selection binder focused the selected row on every model-driven
change, so Back/Forward, search-result jumps, go-to-definition, tab
activation and omnibar picks all pulled the keyboard focus into the
assembly tree. WPF's SelectNodes only scrolled the row into view; the
row took the focus when the pane itself was activated. The binder now
checks where the keyboard focus sits when the selection changes and
leaves it alone unless the tree already holds it. The Analyzer pane
keeps focusing its row, as its WPF counterpart did on every selection
change, so an Analyze request still lands the user in the pane.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-06 08:24:20 +02:00
Christoph Wille 0231a96f12 Let Ctrl+R in the Analyzer pane analyze the pane's own selection
The only Ctrl+R binding sat on the window and always analyzed the
assembly tree's selection, so pressing it on a result row in the
Analyzer pane promoted the wrong entity, or nothing. WPF ILSpy bound the
key on the pane as well. Avalonia walks KeyBindings from the focused
element up to the window, so a pane-level binding takes precedence while
the focus is in the pane and falls through when it has nothing to
analyze. The command takes the selection as its parameter so both
bindings share one implementation.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-06 07:55:18 +02:00
Christoph Wille bd5544bbbb Share context-menu targeting between the assembly and Analyzer trees
The assembly tree had Thunderbird-style context targeting (right-click a
row outside the selection without moving the selection, highlight the
target, re-focus the row after a keyboard-invoked menu); the Analyzer
pane only rebuilt the menu from its selection, so a right-click on
another row opened the menu for the previous selection. Hosting the
behaviour in one controller keyed on SharpTreeView gives both panes the
same gestures and keeps the assembly pane down to its middle-click
open-in-new-tab handler.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-06 07:52:15 +02:00
Christoph Wille 4dc9784c0d Judge Analyze's IsEnabled on the same node shape as IsVisible
IsVisible required every selected node to be a member node while
IsEnabled filtered to the member subset first, so a mixed selection
reported itself enabled-but-hidden. Hidden won, so nothing was visible
to the user, but the two predicates disagreed about the same selection.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-06 07:45:18 +02:00
Siegfried Pammer ef0b4668cc Return symbols for method-group resolve results
Dynamic and token-writer reference paths can receive method-group resolve results directly. Returning the first method keeps ResolveResult.GetSymbol aligned with the existing method-group handling used by AST annotations.

Assisted-by: OpenAI:openai/gpt-5.5:OpenCode
2026-10-06 07:44:01 +02:00
Christoph Wille 85b85e0ea2 Look up the Analyzer "Remove" header through the resource key
Every other context-menu entry names its header by resource key so the
menu builder can localise it; this one shipped the raw string, which
WPF ILSpy did as well. The "Remove" string already exists in the resx.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-06 07:43:19 +02:00
Christoph Wille 15c8cea75d Let Tab move the focus out of the decompiled text view
AvaloniaEdit marks Tab handled while AcceptsTab is on, so the keyboard
focus could never leave the read-only editor. WPF ILSpy removed the
TabForward/TabBackward editing commands for the same reason.

#4042

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-06 07:41:55 +02:00
Siegfried Pammer 8f66608d82 Improve dynamic reference tooltips
Dynamic member tooltips should describe the visible static target, while punctuation should stay reserved for useful call targets such as constructors. This keeps dynamic object creation tooltips on the constructor parentheses but avoids noisy synthetic member references on dynamic invocation parentheses.

Assisted-by: OpenAI:openai/gpt-5.5:OpenCode
2026-10-06 07:35:36 +02:00
Siegfried Pammer c993befc4b Merge pull request #4206 from icsharpcode/christophwille/fix-startup-binding-errors
Fix startup binding errors and background load sweep failure
2026-10-05 17:01:12 +02:00
Christoph Wille fabd0de38e Keep the background load sweep going past unloadable assemblies
One assembly that failed to load faulted the whole sweep, which skipped
the command requery at its end. 'Remove assemblies with load errors' was
therefore not re-evaluated in the one case it exists for.
ShowAssemblyList(AssemblyList) is internal so the test can show a list
whose load it controls.

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-05 15:37:53 +02:00
Christoph Wille 772085f264 Let tree rows inherit ShowLines instead of binding to an ancestor
The ancestor binding logged 'Ancestor not found' whenever a row's content
was evaluated outside a SharpTreeView. An inherited property needs no
lookup, and leaves the lines on where there is no tree view at all.

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-05 15:37:46 +02:00
Christoph Wille a27a6ed9a8 Host the update banner through a content template
With a DataContext binding of its own the panel first inherited the main
window's view model, and each of its compiled bindings failed the cast to
UpdatePanelViewModel and logged an error at startup. The new test boots the
window with a capturing log sink and fails on any binding error.

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-05 15:37:40 +02:00
Christoph Wille 4b64849e84 Give docks capability overrides so Dock's chrome bindings resolve
Dock's theme binds DockCapabilityOverrides.CanDrag/CanDrop on the tool and
document docks themselves, not only on the panes inside them, and logged a
binding error per property at startup. Filling them in from InitLayout
covers layouts restored from disk, which never pass through CreateLayout.

Assisted-by: Claude:claude-fable-5-1:Claude Code
2026-10-05 15:37:32 +02:00
Christoph Wille 0445108b7e Merge pull request #4205 from icsharpcode/christophwille/nuup10
Clean up package restore (Diasymreader)
2026-10-05 09:19:30 +02:00
Christoph Wille 2ec4ee851d Go back to Sbom 4.1.5 bc of build warnings eg "Unhandled exception caught when trying to open "D:\\a\\ILSpy\\ILSpy\\ICSharpCode.ILSpyX\\bin\\Release\\ICSharpCode.ILSpyX.11.1.0.9858.c05ed6db.temp\\_manifest\\spdx_2.2\\manifest.spdx.json"" 2026-10-05 08:42:34 +02:00
Christoph Wille c2d51a80b9 Remove DiasymReader from restore entirely (update other NuGet packages as well) 2026-10-05 08:01:59 +02:00
Christoph Wille 1c7e0efef0 Generate SBOM only on integration build 2026-10-05 07:37:41 +02:00
Siegfried Pammer 6a0e6ccf56 Merge pull request #4197 from icsharpcode/feature/dump-pdb
Add cross-platform PDB dumping to ilspycmd
2026-10-05 07:32:09 +02:00
Siegfried Pammer e61128fe30 Fix PDB dump review findings
Use the PDB table row width for StateMachineMethod external MethodDef references, and include method-level custom debug information in decoded PDB output. Also report a missing Portable PDB explicitly when a debug metadata table is requested from an assembly without one.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-04 19:11:01 +02:00
Siegfried Pammer c826612308 Merge pull request #4204 from icsharpcode/fix/package-entry-selection-decompile
Keep package entry selections decompilable
2026-10-04 16:33:58 +02:00
Siegfried Pammer 4d465bead3 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
2026-10-04 15:51:26 +02:00
Siegfried Pammer eec881e113 Honor bundle entries when dumping PDBs
The PDB dumper opened the outer package path directly, so --bundle-entry was ignored while dumping debug information. Load package inputs through the shared entry resolver and pass Cecil the selected assembly image while keeping ordinary files on the path-based code path for adjacent PDB discovery.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-04 09:07:45 +02:00
Christoph Wille 77528d649d Merge pull request #4190 from icsharpcode/dependabot/github_actions/github/codeql-action-4.38.2
Bump github/codeql-action from 4.38.1 to 4.38.2
2026-10-04 08:27:47 +02:00
Siegfried Pammer 98b010ebe3 Merge pull request #4202 from icsharpcode/fix/1374-mixed-array-initializer
Fix mixed array initializers
2026-10-04 07:09:17 +02:00
Siegfried Pammer 2a204533ca Handle mixed array initializers
Roslyn can lower mostly constant arrays with a static data blob and leave non-constant elements as explicit stores. Merge those trailing stores into the decoded initializer so the decompiler keeps a single array initializer instead of splitting the expression.

Assisted-by: OpenCode:openai/gpt-5.5:opencode
2026-10-03 21:36:55 +02:00
Siegfried Pammer f642bfc795 Merge pull request #4201 from icsharpcode/vb-withevents-winforms
Rewrite VB WithEvents WinForms initialization
2026-10-03 16:18:20 +02:00
Siegfried Pammer 7d3a330f68 Move raw metadata helpers out of MetadataExtensions
Raw metadata table readers compensate for SRM APIs that do not expose every table shape directly, so keeping them separate from general metadata helpers makes that boundary explicit.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-03 15:35:09 +02:00
Siegfried Pammer ddcac25c2b Repair private virtual member output
Metadata can contain private virtual members that C# cannot declare directly. Adjusting the emitted accessibility in the decompiler keeps such members compilable without pushing the policy into the general AST builder.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-03 14:52:35 +02:00
Siegfried Pammer e528a358ed Preserve VB WithEvents backing fields
AccessedThroughProperty-backed controls need to remain addressable as fields so WinForms initialization can use compiler-generated backing storage without hiding the setter that maintains WithEvents subscriptions.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-03 14:52:07 +02:00
Siegfried Pammer e444168cad Accept Debug and Release PDB local names
Debug and Release builds preserve different local names in the test assembly PDB. The dump tests only need to prove that named locals are emitted, so allow either stable name observed in CI instead of binding the assertion to one configuration.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-03 14:10:26 +02:00
Siegfried Pammer 54f8bdd32f Merge pull request #4200 from icsharpcode/fix-4152-variable-name-types
Reserve captured local names in declaring scope
2026-10-03 13:58:48 +02:00
Siegfried Pammer 3c608b7699 Reserve captured local names in declaring scope
Captured locals can first be named while visiting a nested local function even though their declaring ILFunction is the parent. Reserving such generated names only in the nested scope lets sibling captured locals reuse the same name and later collide when declarations are hoisted.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-03 11:24:48 +02:00
Siegfried Pammer 171f3dc354 Make PDB dump tests robust in Release builds
Release builds may optimize away an otherwise unused local even when the PDB still carries local-variable information for active test methods. Assert on a local that survives the Release test assembly so the dump coverage is not tied to optimizer behavior.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-02 08:08:26 +02:00
Siegfried Pammer d1fc5eaaa5 Cover the native PDB path with a Windows-only fixture
PdbDumper reads both Portable and Windows PDBs, but only the Portable path
had tests: Mono.Cecil's native PDB writer is COM-only, so the format cannot
be produced off Windows. The fixture is compiled here by the in-box C#
compiler, which still emits it, and the test asserts the PDB really is the
native format before reading anything out of it - otherwise the suite would
silently re-cover the Portable path.

Assisted-by: Claude:claude-opus-5[1m]:Claude Code
2026-10-02 07:44:55 +02:00
Siegfried Pammer 30dbce447e Add --dump-pdb, a cross-platform replacement for Pdb2Xml
The Pdb2Xml command that just left the app was the only way to see a PDB's
contents, and it was Windows-only. Mono.Cecil's symbol readers cover the
Portable and the Windows (native MSF) format in managed code and pick the
right one themselves, so a single dump path serves both on every OS.

Cecil's object model, rather than raw metadata, is what makes this work for
Windows PDBs at all: they have no metadata tables for --dump-table to read.
That also settles the split between the two options - --dump-table stays the
raw row view of a Portable PDB, --dump-pdb is the decoded one.

Neither symbol reader exposes the document list, so the documents are
collected from the sequence points that reference them.

Assisted-by: Claude:claude-opus-5:Claude Code
2026-10-02 07:44:55 +02:00
Siegfried Pammer 58be31306e Dump the Portable PDB debug tables with --dump-table
The metadata-table dumper only knew the Cor tables, so the debug metadata a
Portable PDB carries had no command-line view at all; the GUI has shown those
eight tables for years. Moving the dumper into ILSpyX puts it next to the PDB
providers it now needs and makes it available to any host, not just ilspycmd.

Two things a user would otherwise trip over: a standalone .pdb is accepted as
an input file, and asking an assembly for a debug table resolves the embedded
or adjacent PDB instead of reporting an empty table. Reading a debug table
without either would silently print nothing at all.

The GUI's StateMachineMethod reader moves to a shared extension. Its own copy
read the MethodDef column with ReadInt16 and switched to the wide form at
ushort.MaxValue rather than 1 << 16, so a large enough method table would have
produced negative RIDs.

Assisted-by: Claude:claude-opus-5:Claude Code
2026-10-02 07:44:55 +02:00
Siegfried Pammer 1332609cb5 Remove the DEBUG-only Pdb2Xml command and its DiaSymReader packages
Microsoft.DiaSymReader.Converter.Xml was the only reason the app referenced
the DiaSymReader chain, and it dragged the NETStandard.Library 1.6.1 shim set
with it: 77 packages in ILSpy's lock file, several of them needing security
overrides to keep NuGet audit quiet. The command itself only ever ran on
Windows, because the converter reaches into native COM.

Nothing is lost that the tooling cannot do without it. ilspycmd prints the
metadata tables, and Mono.Cecil's symbol readers - already a dependency, and
already what DebugInfoUtils falls back to for a Windows PDB - read both PDB
formats in managed code on every OS.

Assisted-by: Claude:claude-opus-5:Claude Code
2026-10-02 07:44:55 +02:00
Siegfried Pammer 7236fd3495 Avoid invalid extension call in null propagation
Null propagation must not render an extension-method conditional access when normal member lookup would bind to a non-method member, because that produces invalid C# for ambiguous Count-style cases.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-02 07:24:33 +02:00
Siegfried Pammer a1afe694ff Merge pull request #4194 from icsharpcode/fix/utf8-literals-4193
Fix UTF-8 literal span initializers
2026-10-01 18:52:31 +02:00
Siegfried Pammer a48f52f075 Merge pull request #4195 from icsharpcode/fix/show-line-numbers-emsize-4189
Fix live line number margin toggle
2026-10-01 18:51:45 +02:00
Siegfried Pammer 5d6481f59e Fix live line number margin toggle
AvaloniaEdit inserts the line number margin before ILSpy's bookmark gutter and can render it before its cached font size is initialized. Keep the gutter order stable after live toggles and prepare the margin before the first render.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-01 07:55:33 +02:00
Siegfried Pammer a055f4219b Merge pull request #4192 from icsharpcode/fix/analyze-shortcut-uses-command
Route Analyze shortcut through context menu command
2026-10-01 07:38:23 +02:00
Siegfried Pammer 8b8af1e4f6 Fix UTF-8 literal span initializers
Recognize Roslyn's null-terminated backing-store shape for u8 literals so escaped control bytes decompile back to UTF-8 string literal syntax, fix LdStrUtf8 to infer ReadOnlySpan<byte> in both the template and generated code, and cover overload-resolution cases where the explicit span conversion must be preserved.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-01 07:35:23 +02:00
Siegfried Pammer 97e5e50218 Move Analyze shortcut to window command
Match the WPF shortcut model by binding Ctrl+R at the window level while keeping the context menu as a separate surface over the same analyze logic.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-01 06:41:20 +02:00
Siegfried Pammer 2e296e7186 Merge pull request #4164 from icsharpcode/perf/coalesce-command-requery
Coalesce the global command re-query
2026-09-30 06:59:09 +02:00
Siegfried Pammer a3f3d0675b Merge pull request #4157 from icsharpcode/perf/tree-selection-fanout
Coalesce the assembly tree's selection and removal fan-out
2026-09-29 09:53:05 +02:00
Siegfried Pammer 359d40ba68 Ignore stale tree selections after removal
Batched selection fan-out can briefly replay a selection for nodes whose assemblies were already removed. Ignore those stale selections and version decompiler-tab updates so late spinner or output continuations cannot overwrite an explicit clear.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-09-29 08:52:49 +02:00
Siegfried Pammer b66fc20038 Coalesce the assembly tree's selection fan-out
A selection change reaches a full application-wide command re-query, a
session-settings write, a message-bus broadcast and a decompile of the
new selection. The model already had a flag to hold that off during a
bulk edit, but only its own SelectNodes ever set it: the binder that
mirrors the tree's selection into the model added and removed one node at
a time, so selecting every row cost one fan-out per row.

The flag becomes a scope any bulk edit can enter, and the binder uses it.
Membership now comes from a set rather than a scan of the model selection
per node, which was quadratic once a large part of the tree was selected.

DockWorkspace subscribed to both the selection collection and the
SelectedItem property, so it showed the selection twice per change and
once per node during a bulk edit; the property already fires when the
selection settles, so the collection subscription goes.

Assisted-by: Claude:claude-opus-5[1m]:Claude Code
Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-09-29 07:45:59 +02:00
Siegfried Pammer d814f4a47e Remove a set of assemblies from the list in one step
Deleting assemblies one at a time is not equivalent to deleting them
together: each removal raises its own collection change, and the
listeners of the assembly list react to one of those by pruning
navigation history, restarting a running search, re-querying every bound
command and re-decompiling whatever is still selected. Selecting an
expanded list and pressing Delete therefore paid for all of that once per
assembly, and froze the UI.

Emptying the list still reports a Remove rather than the Reset that
Clear() raises, because consumers read Reset as "re-read everything" and
several short-circuit their per-removal cleanup on it, which would leave
tabs and navigation history pointing at unloaded assemblies.

The tree's removal is reordered for the same reason: it detached and
announced one node at a time, so a listener reacting to the first
notification still found the rest of the same removal attached and took
them for a selection the user had made.

Assisted-by: Claude:claude-opus-5[1m]:Claude Code
Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-09-29 07:45:59 +02:00