debugger: Rely on LocalDapCommand in more places (#34035)

- **debugger: Move cacheable property onto LocalDapCommand**
- **debugger/session: Relax method bounds to use LocalDapCommand**


Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2025-07-08 01:05:37 +02:00 committed by GitHub
parent 9b7632d5f6
commit c0dc758f24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 24 additions and 24 deletions

View file

@ -17,6 +17,8 @@ use util::ResultExt;
pub trait LocalDapCommand: 'static + Send + Sync + std::fmt::Debug { pub trait LocalDapCommand: 'static + Send + Sync + std::fmt::Debug {
type Response: 'static + Send + std::fmt::Debug; type Response: 'static + Send + std::fmt::Debug;
type DapRequest: 'static + Send + dap::requests::Request; type DapRequest: 'static + Send + dap::requests::Request;
/// Is this request idempotent? Is it safe to cache the response for as long as the execution environment is unchanged?
const CACHEABLE: bool = false;
fn is_supported(_capabilities: &Capabilities) -> bool { fn is_supported(_capabilities: &Capabilities) -> bool {
true true
@ -33,7 +35,6 @@ pub trait LocalDapCommand: 'static + Send + Sync + std::fmt::Debug {
pub trait DapCommand: LocalDapCommand { pub trait DapCommand: LocalDapCommand {
type ProtoRequest: 'static + Send; type ProtoRequest: 'static + Send;
type ProtoResponse: 'static + Send; type ProtoResponse: 'static + Send;
const CACHEABLE: bool = false;
#[allow(dead_code)] #[allow(dead_code)]
fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId; fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId;
@ -823,6 +824,7 @@ pub struct VariablesCommand {
impl LocalDapCommand for VariablesCommand { impl LocalDapCommand for VariablesCommand {
type Response = Vec<Variable>; type Response = Vec<Variable>;
type DapRequest = dap::requests::Variables; type DapRequest = dap::requests::Variables;
const CACHEABLE: bool = true;
fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments { fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments {
dap::VariablesArguments { dap::VariablesArguments {
@ -845,7 +847,6 @@ impl LocalDapCommand for VariablesCommand {
impl DapCommand for VariablesCommand { impl DapCommand for VariablesCommand {
type ProtoRequest = proto::VariablesRequest; type ProtoRequest = proto::VariablesRequest;
type ProtoResponse = proto::DapVariables; type ProtoResponse = proto::DapVariables;
const CACHEABLE: bool = true;
fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId {
SessionId::from_proto(request.client_id) SessionId::from_proto(request.client_id)
@ -1041,6 +1042,7 @@ pub(crate) struct ModulesCommand;
impl LocalDapCommand for ModulesCommand { impl LocalDapCommand for ModulesCommand {
type Response = Vec<dap::Module>; type Response = Vec<dap::Module>;
type DapRequest = dap::requests::Modules; type DapRequest = dap::requests::Modules;
const CACHEABLE: bool = true;
fn is_supported(capabilities: &Capabilities) -> bool { fn is_supported(capabilities: &Capabilities) -> bool {
capabilities.supports_modules_request.unwrap_or_default() capabilities.supports_modules_request.unwrap_or_default()
@ -1064,7 +1066,6 @@ impl LocalDapCommand for ModulesCommand {
impl DapCommand for ModulesCommand { impl DapCommand for ModulesCommand {
type ProtoRequest = proto::DapModulesRequest; type ProtoRequest = proto::DapModulesRequest;
type ProtoResponse = proto::DapModulesResponse; type ProtoResponse = proto::DapModulesResponse;
const CACHEABLE: bool = true;
fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId {
SessionId::from_proto(request.client_id) SessionId::from_proto(request.client_id)
@ -1113,6 +1114,7 @@ pub(crate) struct LoadedSourcesCommand;
impl LocalDapCommand for LoadedSourcesCommand { impl LocalDapCommand for LoadedSourcesCommand {
type Response = Vec<dap::Source>; type Response = Vec<dap::Source>;
type DapRequest = dap::requests::LoadedSources; type DapRequest = dap::requests::LoadedSources;
const CACHEABLE: bool = true;
fn is_supported(capabilities: &Capabilities) -> bool { fn is_supported(capabilities: &Capabilities) -> bool {
capabilities capabilities
@ -1134,7 +1136,6 @@ impl LocalDapCommand for LoadedSourcesCommand {
impl DapCommand for LoadedSourcesCommand { impl DapCommand for LoadedSourcesCommand {
type ProtoRequest = proto::DapLoadedSourcesRequest; type ProtoRequest = proto::DapLoadedSourcesRequest;
type ProtoResponse = proto::DapLoadedSourcesResponse; type ProtoResponse = proto::DapLoadedSourcesResponse;
const CACHEABLE: bool = true;
fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId {
SessionId::from_proto(request.client_id) SessionId::from_proto(request.client_id)
@ -1187,6 +1188,7 @@ pub(crate) struct StackTraceCommand {
impl LocalDapCommand for StackTraceCommand { impl LocalDapCommand for StackTraceCommand {
type Response = Vec<dap::StackFrame>; type Response = Vec<dap::StackFrame>;
type DapRequest = dap::requests::StackTrace; type DapRequest = dap::requests::StackTrace;
const CACHEABLE: bool = true;
fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments { fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments {
dap::StackTraceArguments { dap::StackTraceArguments {
@ -1208,7 +1210,6 @@ impl LocalDapCommand for StackTraceCommand {
impl DapCommand for StackTraceCommand { impl DapCommand for StackTraceCommand {
type ProtoRequest = proto::DapStackTraceRequest; type ProtoRequest = proto::DapStackTraceRequest;
type ProtoResponse = proto::DapStackTraceResponse; type ProtoResponse = proto::DapStackTraceResponse;
const CACHEABLE: bool = true;
fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest {
proto::DapStackTraceRequest { proto::DapStackTraceRequest {
@ -1258,6 +1259,7 @@ pub(crate) struct ScopesCommand {
impl LocalDapCommand for ScopesCommand { impl LocalDapCommand for ScopesCommand {
type Response = Vec<dap::Scope>; type Response = Vec<dap::Scope>;
type DapRequest = dap::requests::Scopes; type DapRequest = dap::requests::Scopes;
const CACHEABLE: bool = true;
fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments { fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments {
dap::ScopesArguments { dap::ScopesArguments {
@ -1276,7 +1278,6 @@ impl LocalDapCommand for ScopesCommand {
impl DapCommand for ScopesCommand { impl DapCommand for ScopesCommand {
type ProtoRequest = proto::DapScopesRequest; type ProtoRequest = proto::DapScopesRequest;
type ProtoResponse = proto::DapScopesResponse; type ProtoResponse = proto::DapScopesResponse;
const CACHEABLE: bool = true;
fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest {
proto::DapScopesRequest { proto::DapScopesRequest {
@ -1313,6 +1314,7 @@ impl DapCommand for ScopesCommand {
impl LocalDapCommand for super::session::CompletionsQuery { impl LocalDapCommand for super::session::CompletionsQuery {
type Response = dap::CompletionsResponse; type Response = dap::CompletionsResponse;
type DapRequest = dap::requests::Completions; type DapRequest = dap::requests::Completions;
const CACHEABLE: bool = true;
fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments { fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments {
dap::CompletionsArguments { dap::CompletionsArguments {
@ -1340,7 +1342,6 @@ impl LocalDapCommand for super::session::CompletionsQuery {
impl DapCommand for super::session::CompletionsQuery { impl DapCommand for super::session::CompletionsQuery {
type ProtoRequest = proto::DapCompletionRequest; type ProtoRequest = proto::DapCompletionRequest;
type ProtoResponse = proto::DapCompletionResponse; type ProtoResponse = proto::DapCompletionResponse;
const CACHEABLE: bool = true;
fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest {
proto::DapCompletionRequest { proto::DapCompletionRequest {
@ -1477,6 +1478,7 @@ pub(crate) struct ThreadsCommand;
impl LocalDapCommand for ThreadsCommand { impl LocalDapCommand for ThreadsCommand {
type Response = Vec<dap::Thread>; type Response = Vec<dap::Thread>;
type DapRequest = dap::requests::Threads; type DapRequest = dap::requests::Threads;
const CACHEABLE: bool = true;
fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments { fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments {
dap::ThreadsArgument {} dap::ThreadsArgument {}
@ -1493,7 +1495,6 @@ impl LocalDapCommand for ThreadsCommand {
impl DapCommand for ThreadsCommand { impl DapCommand for ThreadsCommand {
type ProtoRequest = proto::DapThreadsRequest; type ProtoRequest = proto::DapThreadsRequest;
type ProtoResponse = proto::DapThreadsResponse; type ProtoResponse = proto::DapThreadsResponse;
const CACHEABLE: bool = true;
fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest {
proto::DapThreadsRequest { proto::DapThreadsRequest {
@ -1712,6 +1713,7 @@ pub(super) struct LocationsCommand {
impl LocalDapCommand for LocationsCommand { impl LocalDapCommand for LocationsCommand {
type Response = dap::LocationsResponse; type Response = dap::LocationsResponse;
type DapRequest = dap::requests::Locations; type DapRequest = dap::requests::Locations;
const CACHEABLE: bool = true;
fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments { fn to_dap(&self) -> <Self::DapRequest as dap::requests::Request>::Arguments {
dap::LocationsArguments { dap::LocationsArguments {
@ -1731,8 +1733,6 @@ impl DapCommand for LocationsCommand {
type ProtoRequest = proto::DapLocationsRequest; type ProtoRequest = proto::DapLocationsRequest;
type ProtoResponse = proto::DapLocationsResponse; type ProtoResponse = proto::DapLocationsResponse;
const CACHEABLE: bool = true;
fn client_id_from_proto(message: &Self::ProtoRequest) -> SessionId { fn client_id_from_proto(message: &Self::ProtoRequest) -> SessionId {
SessionId::from_proto(message.session_id) SessionId::from_proto(message.session_id)
} }

View file

@ -4,12 +4,12 @@ use super::breakpoint_store::{
BreakpointStore, BreakpointStoreEvent, BreakpointUpdatedReason, SourceBreakpoint, BreakpointStore, BreakpointStoreEvent, BreakpointUpdatedReason, SourceBreakpoint,
}; };
use super::dap_command::{ use super::dap_command::{
self, Attach, ConfigurationDone, ContinueCommand, DapCommand, DisconnectCommand, self, Attach, ConfigurationDone, ContinueCommand, DisconnectCommand, EvaluateCommand,
EvaluateCommand, Initialize, Launch, LoadedSourcesCommand, LocalDapCommand, LocationsCommand, Initialize, Launch, LoadedSourcesCommand, LocalDapCommand, LocationsCommand, ModulesCommand,
ModulesCommand, NextCommand, PauseCommand, RestartCommand, RestartStackFrameCommand, NextCommand, PauseCommand, RestartCommand, RestartStackFrameCommand, ScopesCommand,
ScopesCommand, SetExceptionBreakpoints, SetVariableValueCommand, StackTraceCommand, SetExceptionBreakpoints, SetVariableValueCommand, StackTraceCommand, StepBackCommand,
StepBackCommand, StepCommand, StepInCommand, StepOutCommand, TerminateCommand, StepCommand, StepInCommand, StepOutCommand, TerminateCommand, TerminateThreadsCommand,
TerminateThreadsCommand, ThreadsCommand, VariablesCommand, ThreadsCommand, VariablesCommand,
}; };
use super::dap_store::DapStore; use super::dap_store::DapStore;
use anyhow::{Context as _, Result, anyhow}; use anyhow::{Context as _, Result, anyhow};
@ -555,7 +555,7 @@ impl RunningMode {
} }
impl Mode { impl Mode {
pub(super) fn request_dap<R: DapCommand>(&self, request: R) -> Task<Result<R::Response>> pub(super) fn request_dap<R: LocalDapCommand>(&self, request: R) -> Task<Result<R::Response>>
where where
<R::DapRequest as dap::requests::Request>::Response: 'static, <R::DapRequest as dap::requests::Request>::Response: 'static,
<R::DapRequest as dap::requests::Request>::Arguments: 'static + Send, <R::DapRequest as dap::requests::Request>::Arguments: 'static + Send,
@ -689,7 +689,7 @@ trait CacheableCommand: Any + Send + Sync {
impl<T> CacheableCommand for T impl<T> CacheableCommand for T
where where
T: DapCommand + PartialEq + Eq + Hash, T: LocalDapCommand + PartialEq + Eq + Hash,
{ {
fn dyn_eq(&self, rhs: &dyn CacheableCommand) -> bool { fn dyn_eq(&self, rhs: &dyn CacheableCommand) -> bool {
(rhs as &dyn Any) (rhs as &dyn Any)
@ -708,7 +708,7 @@ where
pub(crate) struct RequestSlot(Arc<dyn CacheableCommand>); pub(crate) struct RequestSlot(Arc<dyn CacheableCommand>);
impl<T: DapCommand + PartialEq + Eq + Hash> From<T> for RequestSlot { impl<T: LocalDapCommand + PartialEq + Eq + Hash> From<T> for RequestSlot {
fn from(request: T) -> Self { fn from(request: T) -> Self {
Self(Arc::new(request)) Self(Arc::new(request))
} }
@ -1534,7 +1534,7 @@ impl Session {
} }
/// Ensure that there's a request in flight for the given command, and if not, send it. Use this to run requests that are idempotent. /// Ensure that there's a request in flight for the given command, and if not, send it. Use this to run requests that are idempotent.
fn fetch<T: DapCommand + PartialEq + Eq + Hash>( fn fetch<T: LocalDapCommand + PartialEq + Eq + Hash>(
&mut self, &mut self,
request: T, request: T,
process_result: impl FnOnce(&mut Self, Result<T::Response>, &mut Context<Self>) + 'static, process_result: impl FnOnce(&mut Self, Result<T::Response>, &mut Context<Self>) + 'static,
@ -1585,7 +1585,7 @@ impl Session {
} }
} }
fn request_inner<T: DapCommand + PartialEq + Eq + Hash>( fn request_inner<T: LocalDapCommand + PartialEq + Eq + Hash>(
capabilities: &Capabilities, capabilities: &Capabilities,
mode: &Mode, mode: &Mode,
request: T, request: T,
@ -1621,7 +1621,7 @@ impl Session {
}) })
} }
fn request<T: DapCommand + PartialEq + Eq + Hash>( fn request<T: LocalDapCommand + PartialEq + Eq + Hash>(
&self, &self,
request: T, request: T,
process_result: impl FnOnce( process_result: impl FnOnce(
@ -1635,7 +1635,7 @@ impl Session {
Self::request_inner(&self.capabilities, &self.mode, request, process_result, cx) Self::request_inner(&self.capabilities, &self.mode, request, process_result, cx)
} }
fn invalidate_command_type<Command: DapCommand>(&mut self) { fn invalidate_command_type<Command: LocalDapCommand>(&mut self) {
self.requests.remove(&std::any::TypeId::of::<Command>()); self.requests.remove(&std::any::TypeId::of::<Command>());
} }
@ -1816,7 +1816,7 @@ impl Session {
Some(()) Some(())
} }
fn on_step_response<T: DapCommand + PartialEq + Eq + Hash>( fn on_step_response<T: LocalDapCommand + PartialEq + Eq + Hash>(
thread_id: ThreadId, thread_id: ThreadId,
) -> impl FnOnce(&mut Self, Result<T::Response>, &mut Context<Self>) -> Option<T::Response> + 'static ) -> impl FnOnce(&mut Self, Result<T::Response>, &mut Context<Self>) -> Option<T::Response> + 'static
{ {