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

Piotr Osiewicz created

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


Release Notes:

- N/A

Change summary

crates/project/src/debugger/dap_command.rs | 20 ++++++++--------
crates/project/src/debugger/session.rs     | 28 ++++++++++++------------
2 files changed, 24 insertions(+), 24 deletions(-)

Detailed changes

crates/project/src/debugger/dap_command.rs 🔗

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

crates/project/src/debugger/session.rs 🔗

@@ -4,12 +4,12 @@ use super::breakpoint_store::{
     BreakpointStore, BreakpointStoreEvent, BreakpointUpdatedReason, SourceBreakpoint,
 };
 use super::dap_command::{
-    self, Attach, ConfigurationDone, ContinueCommand, DapCommand, DisconnectCommand,
-    EvaluateCommand, Initialize, Launch, LoadedSourcesCommand, LocalDapCommand, LocationsCommand,
-    ModulesCommand, NextCommand, PauseCommand, RestartCommand, RestartStackFrameCommand,
-    ScopesCommand, SetExceptionBreakpoints, SetVariableValueCommand, StackTraceCommand,
-    StepBackCommand, StepCommand, StepInCommand, StepOutCommand, TerminateCommand,
-    TerminateThreadsCommand, ThreadsCommand, VariablesCommand,
+    self, Attach, ConfigurationDone, ContinueCommand, DisconnectCommand, EvaluateCommand,
+    Initialize, Launch, LoadedSourcesCommand, LocalDapCommand, LocationsCommand, ModulesCommand,
+    NextCommand, PauseCommand, RestartCommand, RestartStackFrameCommand, ScopesCommand,
+    SetExceptionBreakpoints, SetVariableValueCommand, StackTraceCommand, StepBackCommand,
+    StepCommand, StepInCommand, StepOutCommand, TerminateCommand, TerminateThreadsCommand,
+    ThreadsCommand, VariablesCommand,
 };
 use super::dap_store::DapStore;
 use anyhow::{Context as _, Result, anyhow};
@@ -555,7 +555,7 @@ impl RunningMode {
 }
 
 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
         <R::DapRequest as dap::requests::Request>::Response: 'static,
         <R::DapRequest as dap::requests::Request>::Arguments: 'static + Send,
@@ -689,7 +689,7 @@ trait CacheableCommand: Any + Send + Sync {
 
 impl<T> CacheableCommand for T
 where
-    T: DapCommand + PartialEq + Eq + Hash,
+    T: LocalDapCommand + PartialEq + Eq + Hash,
 {
     fn dyn_eq(&self, rhs: &dyn CacheableCommand) -> bool {
         (rhs as &dyn Any)
@@ -708,7 +708,7 @@ where
 
 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 {
         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.
-    fn fetch<T: DapCommand + PartialEq + Eq + Hash>(
+    fn fetch<T: LocalDapCommand + PartialEq + Eq + Hash>(
         &mut self,
         request: T,
         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,
         mode: &Mode,
         request: T,
@@ -1621,7 +1621,7 @@ impl Session {
         })
     }
 
-    fn request<T: DapCommand + PartialEq + Eq + Hash>(
+    fn request<T: LocalDapCommand + PartialEq + Eq + Hash>(
         &self,
         request: T,
         process_result: impl FnOnce(
@@ -1635,7 +1635,7 @@ impl Session {
         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>());
     }
 
@@ -1816,7 +1816,7 @@ impl Session {
         Some(())
     }
 
-    fn on_step_response<T: DapCommand + PartialEq + Eq + Hash>(
+    fn on_step_response<T: LocalDapCommand + PartialEq + Eq + Hash>(
         thread_id: ThreadId,
     ) -> impl FnOnce(&mut Self, Result<T::Response>, &mut Context<Self>) -> Option<T::Response> + 'static
     {