display stack frames
This commit is contained in:
@@ -151,13 +151,25 @@ public class DebuggingService
|
|||||||
var stackTrace = _debugProtocolHost.SendRequestSync(new StackTraceRequest { ThreadId = thread.Id });
|
var stackTrace = _debugProtocolHost.SendRequestSync(new StackTraceRequest { ThreadId = thread.Id });
|
||||||
var frame = stackTrace.StackFrames!.FirstOrDefault();
|
var frame = stackTrace.StackFrames!.FirstOrDefault();
|
||||||
if (frame == null) continue;
|
if (frame == null) continue;
|
||||||
|
// Infrastructure.dll!Infrastructure.DependencyInjection.AddInfrastructure(Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.Configuration.IConfiguration configuration) Line 23
|
||||||
|
var name = frame.Name;
|
||||||
|
if (name == "[External Code]") continue; // TODO: handle this case
|
||||||
|
// need to parse out the class name, method name, namespace, assembly name
|
||||||
|
var methodName = name.Split('!')[1].Split('(')[0];
|
||||||
|
var className = methodName.Split('.').Reverse().Skip(1).First();
|
||||||
|
var namespaceName = string.Join('.', methodName.Split('.').Reverse().Skip(2).Reverse());
|
||||||
|
var assemblyName = name.Split('!')[0];
|
||||||
var frameModel = new StackFrameModel
|
var frameModel = new StackFrameModel
|
||||||
{
|
{
|
||||||
Id = frame.Id,
|
Id = frame.Id,
|
||||||
Name = frame.Name,
|
Name = frame.Name,
|
||||||
Line = frame.Line,
|
Line = frame.Line,
|
||||||
Column = frame.Column,
|
Column = frame.Column,
|
||||||
Source = frame.Source?.Path
|
Source = frame.Source?.Path,
|
||||||
|
ClassName = className,
|
||||||
|
MethodName = methodName,
|
||||||
|
Namespace = namespaceName,
|
||||||
|
AssemblyName = assemblyName
|
||||||
};
|
};
|
||||||
threadModel.StackFrames.Add(frameModel);
|
threadModel.StackFrames.Add(frameModel);
|
||||||
var scopes = _debugProtocolHost.SendRequestSync(new ScopesRequest { FrameId = frame.Id });
|
var scopes = _debugProtocolHost.SendRequestSync(new ScopesRequest { FrameId = frame.Id });
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ public class ThreadModel
|
|||||||
|
|
||||||
public class StackFrameModel
|
public class StackFrameModel
|
||||||
{
|
{
|
||||||
|
public required string ClassName { get; set; }
|
||||||
|
public required string MethodName { get; set; }
|
||||||
|
public required string Namespace { get; set; }
|
||||||
|
public required string AssemblyName { get; set; }
|
||||||
|
|
||||||
public required int Id { get; set; }
|
public required int Id { get; set; }
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
public required int? Line { get; set; }
|
public required int? Line { get; set; }
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Ardalis.GuardClauses;
|
||||||
using Godot;
|
using Godot;
|
||||||
using SharpIDE.Application.Features.Debugging;
|
using SharpIDE.Application.Features.Debugging;
|
||||||
using SharpIDE.Application.Features.Events;
|
using SharpIDE.Application.Features.Events;
|
||||||
@@ -9,19 +10,24 @@ public partial class ThreadsVariablesSubTab : Control
|
|||||||
{
|
{
|
||||||
private PackedScene _threadListItemScene = GD.Load<PackedScene>("res://Features/Debug_/Tab/SubTabs/ThreadListItem.tscn");
|
private PackedScene _threadListItemScene = GD.Load<PackedScene>("res://Features/Debug_/Tab/SubTabs/ThreadListItem.tscn");
|
||||||
private VBoxContainer _threadsVboxContainer = null!;
|
private VBoxContainer _threadsVboxContainer = null!;
|
||||||
|
private VBoxContainer _stackFramesVboxContainer = null!;
|
||||||
|
private VBoxContainer _variablesVboxContainer = null!;
|
||||||
public SharpIdeProjectModel Project { get; set; } = null!;
|
public SharpIdeProjectModel Project { get; set; } = null!;
|
||||||
|
private ThreadModel? _selectedThread = null!; // null when not at a stop point
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_threadsVboxContainer = GetNode<VBoxContainer>("%ThreadsPanel/VBoxContainer");
|
_threadsVboxContainer = GetNode<VBoxContainer>("%ThreadsPanel/VBoxContainer");
|
||||||
|
_stackFramesVboxContainer = GetNode<VBoxContainer>("%StackFramesPanel/VBoxContainer");
|
||||||
|
_variablesVboxContainer = GetNode<VBoxContainer>("%VariablesPanel/VBoxContainer");
|
||||||
GlobalEvents.DebuggerExecutionStopped += OnDebuggerExecutionStopped;
|
GlobalEvents.DebuggerExecutionStopped += OnDebuggerExecutionStopped;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnDebuggerExecutionStopped(ExecutionStopInfo arg)
|
private async Task OnDebuggerExecutionStopped(ExecutionStopInfo stopInfo)
|
||||||
{
|
{
|
||||||
var result = await Singletons.RunService.GetInfoAtStopPoint();
|
var result = await Singletons.RunService.GetInfoAtStopPoint();
|
||||||
var scenes = result.Threads.Select(s =>
|
var threadScenes = result.Threads.Select(s =>
|
||||||
{
|
{
|
||||||
var threadListItem = _threadListItemScene.Instantiate<Control>();
|
var threadListItem = _threadListItemScene.Instantiate<Control>();
|
||||||
threadListItem.GetNode<Label>("Label").Text = $"{s.Id}: {s.Name}";
|
threadListItem.GetNode<Label>("Label").Text = $"{s.Id}: {s.Name}";
|
||||||
@@ -29,10 +35,28 @@ public partial class ThreadsVariablesSubTab : Control
|
|||||||
}).ToList();
|
}).ToList();
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
foreach (var scene in scenes)
|
foreach (var scene in threadScenes)
|
||||||
{
|
{
|
||||||
_threadsVboxContainer.AddChild(scene);
|
_threadsVboxContainer.AddChild(scene);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var stoppedThreadId = stopInfo.ThreadId;
|
||||||
|
var stoppedThread = result.Threads.SingleOrDefault(t => t.Id == stoppedThreadId);
|
||||||
|
Guard.Against.Null(stoppedThread, nameof(stoppedThread));
|
||||||
|
var stackFrameScenes = stoppedThread!.StackFrames.Select(s =>
|
||||||
|
{
|
||||||
|
var stackFrameItem = _threadListItemScene.Instantiate<Control>();
|
||||||
|
stackFrameItem.GetNode<Label>("Label").Text = $"{s.ClassName}.{s.MethodName}() in {s.Namespace}, {s.AssemblyName}";
|
||||||
|
return stackFrameItem;
|
||||||
|
}).ToList();
|
||||||
|
await this.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
foreach (var scene in stackFrameScenes)
|
||||||
|
{
|
||||||
|
_stackFramesVboxContainer.AddChild(scene);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,20 +40,22 @@ grow_vertical = 2
|
|||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="HSplitContainer/HSplitContainer/StackFramesPanel"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/HSplitContainer/StackFramesPanel"]
|
||||||
layout_mode = 0
|
layout_mode = 1
|
||||||
offset_left = 12.0
|
anchors_preset = 15
|
||||||
offset_right = 52.0
|
anchor_right = 1.0
|
||||||
offset_bottom = 23.0
|
anchor_bottom = 1.0
|
||||||
text = "B"
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
[node name="VariablesPanel" type="Panel" parent="HSplitContainer"]
|
[node name="VariablesPanel" type="Panel" parent="HSplitContainer"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="HSplitContainer/VariablesPanel"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/VariablesPanel"]
|
||||||
layout_mode = 0
|
layout_mode = 1
|
||||||
offset_left = 12.0
|
anchors_preset = 15
|
||||||
offset_right = 52.0
|
anchor_right = 1.0
|
||||||
offset_bottom = 23.0
|
anchor_bottom = 1.0
|
||||||
text = "C"
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|||||||
Reference in New Issue
Block a user