mirror of
https://github.com/actions/runner.git
synced 2026-03-19 00:27:24 +08:00
Wire DapVariableProvider into DapDebugSession for scope inspection
Replace the stub HandleScopes/HandleVariables implementations that returned empty lists with real delegation to DapVariableProvider. Changes: - DapDebugSession now creates a DapVariableProvider on Initialize() - HandleScopes() resolves the execution context for the requested frame and delegates to the provider - HandleVariables() delegates to the provider for both top-level scope references and nested dynamic references - GetExecutionContextForFrame() maps frame IDs to contexts: frame 1 = current step, frames 1000+ = completed (no live context) - Provider is reset on each new step to invalidate stale nested refs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -19,12 +19,13 @@ namespace GitHub.Runner.Worker.Dap
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimal production DAP debug session.
|
||||
/// Production DAP debug session.
|
||||
/// Handles step-level breakpoints with next/continue flow control,
|
||||
/// client reconnection, and cancellation signal propagation.
|
||||
/// scope/variable inspection, client reconnection, and cancellation
|
||||
/// signal propagation.
|
||||
///
|
||||
/// Scope inspection, REPL, step manipulation, and time-travel debugging
|
||||
/// are intentionally deferred to future iterations.
|
||||
/// REPL, step manipulation, and time-travel debugging are intentionally
|
||||
/// deferred to future iterations.
|
||||
/// </summary>
|
||||
public sealed class DapDebugSession : RunnerService, IDapDebugSession
|
||||
{
|
||||
@@ -62,6 +63,9 @@ namespace GitHub.Runner.Worker.Dap
|
||||
// Client connection tracking for reconnection support
|
||||
private volatile bool _isClientConnected;
|
||||
|
||||
// Scope/variable inspection provider — reusable by future DAP features
|
||||
private DapVariableProvider _variableProvider;
|
||||
|
||||
public bool IsActive =>
|
||||
_state == DapSessionState.Ready ||
|
||||
_state == DapSessionState.Paused ||
|
||||
@@ -72,6 +76,7 @@ namespace GitHub.Runner.Worker.Dap
|
||||
public override void Initialize(IHostContext hostContext)
|
||||
{
|
||||
base.Initialize(hostContext);
|
||||
_variableProvider = new DapVariableProvider(hostContext);
|
||||
Trace.Info("DapDebugSession initialized");
|
||||
}
|
||||
|
||||
@@ -321,19 +326,43 @@ namespace GitHub.Runner.Worker.Dap
|
||||
|
||||
private Response HandleScopes(Request request)
|
||||
{
|
||||
// MVP: return empty scopes — scope inspection deferred
|
||||
var args = request.Arguments?.ToObject<ScopesArguments>();
|
||||
var frameId = args?.FrameId ?? CurrentFrameId;
|
||||
|
||||
var context = GetExecutionContextForFrame(frameId);
|
||||
if (context == null)
|
||||
{
|
||||
return CreateResponse(request, true, body: new ScopesResponseBody
|
||||
{
|
||||
Scopes = new List<Scope>()
|
||||
});
|
||||
}
|
||||
|
||||
var scopes = _variableProvider.GetScopes(context);
|
||||
return CreateResponse(request, true, body: new ScopesResponseBody
|
||||
{
|
||||
Scopes = new List<Scope>()
|
||||
Scopes = scopes
|
||||
});
|
||||
}
|
||||
|
||||
private Response HandleVariables(Request request)
|
||||
{
|
||||
// MVP: return empty variables — variable inspection deferred
|
||||
var args = request.Arguments?.ToObject<VariablesArguments>();
|
||||
var variablesRef = args?.VariablesReference ?? 0;
|
||||
|
||||
var context = _currentStep?.ExecutionContext ?? _jobContext;
|
||||
if (context == null)
|
||||
{
|
||||
return CreateResponse(request, true, body: new VariablesResponseBody
|
||||
{
|
||||
Variables = new List<Variable>()
|
||||
});
|
||||
}
|
||||
|
||||
var variables = _variableProvider.GetVariables(context, variablesRef);
|
||||
return CreateResponse(request, true, body: new VariablesResponseBody
|
||||
{
|
||||
Variables = new List<Variable>()
|
||||
Variables = variables
|
||||
});
|
||||
}
|
||||
|
||||
@@ -402,6 +431,10 @@ namespace GitHub.Runner.Worker.Dap
|
||||
_jobContext = jobContext;
|
||||
_currentStepIndex = _completedSteps.Count;
|
||||
|
||||
// Reset variable references so stale nested refs from the
|
||||
// previous step are not served to the client.
|
||||
_variableProvider?.Reset();
|
||||
|
||||
// Determine if we should pause
|
||||
bool shouldPause = isFirstStep || _pauseOnNextStep;
|
||||
|
||||
@@ -598,6 +631,23 @@ namespace GitHub.Runner.Worker.Dap
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the execution context for a given stack frame ID.
|
||||
/// Frame 1 = current step; frames 1000+ = completed steps (no
|
||||
/// context available — those steps have already finished).
|
||||
/// Falls back to the job-level context when no step is active.
|
||||
/// </summary>
|
||||
private IExecutionContext GetExecutionContextForFrame(int frameId)
|
||||
{
|
||||
if (frameId == CurrentFrameId)
|
||||
{
|
||||
return _currentStep?.ExecutionContext ?? _jobContext;
|
||||
}
|
||||
|
||||
// Completed-step frames don't carry a live execution context.
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a stopped event to the connected client.
|
||||
/// Silently no-ops if no client is connected.
|
||||
|
||||
Reference in New Issue
Block a user