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
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
SessionSettings gains an ActiveTreeViewPath (string array) saved every
time AssemblyTreeModel.SelectedItem changes and consulted on the next
launch when the assembly list root is built. To make the path stable
across language switches, each tree node overrides ToString to return a
language-independent identifier — file path for assemblies, ITypeDefinition.
ReflectionName for types, and IL-formatted entity strings for members,
matching the WPF host's scheme.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Adds the Language abstraction so tree-node labels render through the
active output language instead of raw metadata names.
Assisted-by: Claude:claude-opus-4-7:Claude Code
New SessionSettings (ObservableObject + ISettingsSection) saved under
<SessionSettings> in ILSpy.xml: ActiveAssemblyList, WindowState, and
WindowBounds (Left/Top/Width/Height attributes).
Assisted-by: Claude:claude-opus-4-7:Claude Code
- Hold AssemblyListManager on AssemblyTreeModel and mirror its
AssemblyLists collection so the toolbar combo can bind to it.
- New ActiveListName ([ObservableProperty]); OnActiveListNameChanged
loads the named list via the manager and rebuilds Root.
- The "seed initial assemblies if empty" fallback now only triggers
for the (Default) list, so switching to an empty user list doesn't
auto-populate it.
- MainToolBar AssemblyListComboBox bound to AssemblyLists /
ActiveListName (TwoWay).
Assisted-by: Claude:claude-opus-4-7:Claude Code
Replaces the temporary 3-column Grid placeholder in MainWindow with a
Dock.Avalonia DockControl driven by an ILSpyDockFactory and orchestrated
by a [Shared] DockWorkspace exported via MEF.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Adds the assembly tree pane (DataGrid-based, ProDataGrid hierarchical
rows), the SharpTreeNode-derived node type skeletons it consumes, the
empty MainToolBar placeholder, the ILSpySettings file-path provider
wiring in App.axaml.cs, and the AssemblyTreeModel.Initialize() hook in
the MainWindow code-behind.
Assisted-by: Claude:claude-opus-4-7:Claude Code
Strip the WPF ILSpy/, ILSpy.Tests/, and ILSpy.BamlDecompiler/ projects
and their solution entries so this commit can serve as the base for
replaying the rewritten Avalonia history on top. The BAML plugin needed
UseWpf + AvalonEdit and had a ProjectReference to ILSpy/ILSpy.csproj;
once both are gone it cannot build and would block bisect for every
intermediate commit. The Avalonia main app will absorb its three exports
(factory, file handler, entry node) in the later "BAML to XAML
decompiler integration" commit.
Decompiler.Tests targeted net11.0-windows only because
Microsoft.DiaSymReader.Native is Win-only and Tester.cs hardcoded ilasm.exe
/ ildasm.exe filenames. Both are narrow problems: gate the Native package
to Windows, replace the ".exe" suffix with an OS-aware helper, and drop
the -windows TFM. The Microsoft.NETCore.IL{,D}Asm metapackages' RID graph
already ships ilasm/ildasm for linux + osx via per-RID runtime sub-packages
when RuntimeIdentifier resolves dynamically, so the tool just lands in the
test output dir with the right suffix on every host.
Windows-only test fixtures (RoundtripAssembly + the RunWithTestRunner,
SignAssembly, FindMSBuild call sites) gate via Assert.Ignore +
[Platform("Win")] so they skip on non-Windows instead of failing. CA1416
joins NoWarn -- the analyzer can't see the runtime guards, and the test
inputs (Console.CapsLock, Registry access) are decompilation targets, not
infrastructure.
BuildTools/pre-commit learns to find dotnet-format on non-Windows (XDG
basedir + no .exe suffix) so the hook can run wherever the build now does.
Assisted-by: Claude:claude-opus-4-7:Claude Code
* .NET 11 RC2 minimal changes
* Heuristic for transport feed Roslyn selection
* Microsoft.CodeAnalysis.NetAnalyzers from main NuGet feed
* Use the VS2026 image
* Switch all test projects to net11
* Extract constants
* Include vsix with plain nuget.config files
* Use releaseTag with fallback to downloadUrl in updates.xml
* Add tests
* Prevent arbitrary downloadUrl - must start with BaseUrl as well
* Remove custom domain ilspy.net in end-user visible places