Browse Source

Show a hint instead of stale debug steps for languages without step support

When the current language is not an IDebugStepProvider (e.g. the IL
disassembler), the Debug Steps pane kept displaying the previous
language's step tree, and its commands still triggered re-decompiles
with a step limit the language ignores. Detaching now clears the tree
and the view shows a "not available" note until a step-providing
language is selected again.

Assisted-by: Claude:claude-fable-5:Claude Code
pull/3776/head
Siegfried Pammer 4 weeks ago committed by Siegfried Pammer
parent
commit
ef195d2703
  1. 24
      ILSpy.Tests/Views/DebugStepsTests.cs
  2. 12
      ILSpy/ViewModels/DebugStepsPaneModel.cs
  3. 8
      ILSpy/Views/DebugSteps.axaml

24
ILSpy.Tests/Views/DebugStepsTests.cs

@ -133,6 +133,30 @@ public class DebugStepsTests @@ -133,6 +133,30 @@ public class DebugStepsTests
languageService.Languages.Should().Contain(l => l.Name == "Typed IL");
return Task.CompletedTask;
}
[AvaloniaTest]
public Task Pane_Reports_Not_Available_For_Languages_Without_Debug_Steps()
{
// The step tree only makes sense for IDebugStepProvider languages (C#, ILAst, Typed IL).
// For the plain IL disassembler the pane must not keep showing the previous language's
// stale step tree (whose commands would trigger pointless re-decompiles); it reports
// unavailability so the view swaps in a "not available" message instead.
var languageService = AppComposition.Current.GetExport<LanguageService>();
var debugStepsVm = AppComposition.Current.GetExport<DebugStepsPaneModel>();
languageService.CurrentLanguage = languageService.Languages.OfType<CSharpLanguage>().First();
global::Avalonia.Threading.Dispatcher.UIThread.RunJobs();
debugStepsVm.IsAvailable.Should().BeTrue("C# provides debug steps");
// Simulate a populated tree from the C# run, then flip to the disassembler language.
debugStepsVm.Steps = new[] { new ICSharpCode.Decompiler.IL.Transforms.Stepper.Node("stale") };
languageService.CurrentLanguage = languageService.Languages.OfType<ILLanguage>().First(l => l.Name == "IL");
global::Avalonia.Threading.Dispatcher.UIThread.RunJobs();
debugStepsVm.IsAvailable.Should().BeFalse("the IL disassembler provides no debug steps");
debugStepsVm.Steps.Should().BeNull("the previous language's step tree must not linger");
return Task.CompletedTask;
}
[AvaloniaTest]
public async Task Window_Menu_Toggle_Surfaces_The_Default_Hidden_Debug_Steps_Pane()
{

12
ILSpy/ViewModels/DebugStepsPaneModel.cs

@ -92,6 +92,14 @@ namespace ILSpy.ViewModels @@ -92,6 +92,14 @@ namespace ILSpy.ViewModels
[ObservableProperty]
Stepper.Node? selectedStep;
/// <summary>
/// True while the current language is an <see cref="IDebugStepProvider"/>. When false,
/// the view replaces the step tree with a "not available" note instead of leaving the
/// previous language's stale tree (whose commands would trigger pointless re-decompiles).
/// </summary>
[ObservableProperty]
bool isAvailable;
public IRelayCommand ShowStateBeforeCommand { get; }
public IRelayCommand ShowStateAfterCommand { get; }
public IRelayCommand DebugStepCommand { get; }
@ -162,6 +170,7 @@ namespace ILSpy.ViewModels @@ -162,6 +170,7 @@ namespace ILSpy.ViewModels
// Same language instance — just refresh the steps in case a decompile happened
// while we were detached.
Steps = activeLanguage!.Stepper.Steps;
IsAvailable = true;
return;
}
DetachFromLanguage();
@ -169,10 +178,13 @@ namespace ILSpy.ViewModels @@ -169,10 +178,13 @@ namespace ILSpy.ViewModels
language.StepperUpdated += OnStepperUpdated;
Steps = language.Stepper.Steps;
Options = language.StepOptions;
IsAvailable = true;
}
void DetachFromLanguage()
{
IsAvailable = false;
Steps = null;
if (activeLanguage != null)
{
activeLanguage.StepperUpdated -= OnStepperUpdated;

8
ILSpy/Views/DebugSteps.axaml

@ -7,7 +7,12 @@ @@ -7,7 +7,12 @@
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="300"
x:Class="ILSpy.Views.DebugSteps"
x:DataType="vm:DebugStepsPaneModel">
<DockPanel>
<Panel>
<TextBlock IsVisible="{Binding !IsAvailable}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="8" TextWrapping="Wrap" Opacity="0.7"
Text="Debug steps are not available for the current language." />
<DockPanel IsVisible="{Binding IsAvailable}">
<!-- Options are contributed by the active step-provider language and selected by type:
ILAst renders its writing-options checkboxes; C# (null Options) renders nothing. -->
<ContentControl DockPanel.Dock="Top" Margin="2" Content="{Binding Options}">
@ -49,4 +54,5 @@ @@ -49,4 +54,5 @@
</TreeView.ContextMenu>
</TreeView>
</DockPanel>
</Panel>
</UserControl>

Loading…
Cancel
Save