From 4b0b31f3c470e2787293c055084f5f0850a5509c Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 4 Jun 2026 18:21:07 +0200 Subject: [PATCH] Apply the Display expand-folding options to decompilation The Display-options "Expand using declarations / member definitions after decompilation" checkboxes had no effect: the live decompile cloned DecompilerSettings and baked in the language version but never copied these two flags from DisplaySettings. TextTokenWriter reads settings.ExpandUsingDeclarations / ExpandMemberDefinitions to decide each fold's DefaultClosed, so without the bridge both defaulted false and every using / member fold came back collapsed regardless of the setting. --- ILSpy.Tests/Editor/DecompilerViewTests.cs | 35 +++++++++++++++++++++++ ILSpy/TextView/DecompilerTabPageModel.cs | 10 ++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/ILSpy.Tests/Editor/DecompilerViewTests.cs b/ILSpy.Tests/Editor/DecompilerViewTests.cs index 7009fe83e..70e146ef5 100644 --- a/ILSpy.Tests/Editor/DecompilerViewTests.cs +++ b/ILSpy.Tests/Editor/DecompilerViewTests.cs @@ -476,6 +476,41 @@ public class DecompilerViewTests fm!.AllFoldings.Should().NotBeEmpty("multi-line XML elements should produce fold ranges"); } + [AvaloniaTest] + public async Task Expand_Display_Settings_Reach_The_Decompiler_Foldings() + { + // The Display-options "Expand using declarations / member definitions after decompilation" + // flags only take effect by riding DecompilerSettings into the decompile: TextTokenWriter + // sets each fold's DefaultClosed from settings.ExpandUsingDeclarations / + // ExpandMemberDefinitions. So the live decompile must bridge them in from DisplaySettings; + // without the bridge they default false and every fold comes back collapsed. + var (_, vm) = await TestHarness.BootAsync(3); + + var settings = AppComposition.Current.GetExport(); + settings.DisplaySettings.ExpandMemberDefinitions = true; + settings.DisplaySettings.ExpandUsingDeclarations = true; + + var typeNode = vm.AssemblyTreeModel.FindNode( + TreeNavigation.CoreLibName, "System", "System.Version"); + vm.AssemblyTreeModel.SelectNode(typeNode); + var tab = await vm.DockWorkspace.WaitForDecompiledTextAsync(); + + tab.Foldings.Should().NotBeNull(); + var foldings = tab.Foldings!; + foldings.Should().NotBeEmpty("decompiling a type must produce foldings"); + + var memberFolds = foldings.Where(f => f.IsDefinition).ToList(); + memberFolds.Should().NotBeEmpty("a type with members must produce member-definition foldings"); + memberFolds.Should().OnlyContain(f => !f.DefaultClosed, + "ExpandMemberDefinitions=true must leave member-definition foldings expanded (DefaultClosed=false)"); + + // The top-most fold is the using-declarations block (offset 0, not a member definition). + var usingFold = foldings.OrderBy(f => f.StartOffset).First(); + usingFold.IsDefinition.Should().BeFalse("the top-most fold is the using block, not a member"); + usingFold.DefaultClosed.Should().BeFalse( + "ExpandUsingDeclarations=true must leave the using block expanded"); + } + #if DEBUG [AvaloniaTest] public async Task Switching_Language_With_Selected_Method_Does_Not_Throw_Folding_Out_Of_Bounds() diff --git a/ILSpy/TextView/DecompilerTabPageModel.cs b/ILSpy/TextView/DecompilerTabPageModel.cs index 49112f203..cf181d49c 100644 --- a/ILSpy/TextView/DecompilerTabPageModel.cs +++ b/ILSpy/TextView/DecompilerTabPageModel.cs @@ -569,7 +569,15 @@ namespace ILSpy.TextView { try { - var settings = AppEnv.AppComposition.Current.GetExport().DecompilerSettings.Clone(); + var settingsService = AppEnv.AppComposition.Current.GetExport(); + var settings = settingsService.DecompilerSettings.Clone(); + // Bridge the Display-options fold-expansion flags into the decompiler settings: + // TextTokenWriter reads settings.ExpandUsingDeclarations / ExpandMemberDefinitions + // to set each fold's DefaultClosed. Without this the "Expand using declarations / + // member definitions after decompilation" options would have no effect. + var display = settingsService.DisplaySettings; + settings.ExpandUsingDeclarations = display.ExpandUsingDeclarations; + settings.ExpandMemberDefinitions = display.ExpandMemberDefinitions; try { var version = AppEnv.AppComposition.Current.GetExport().CurrentVersion;