Debugger: Add stop on entry support to debug adapter configs (#27942)

Anthony Eid created

This PR adds passing in `stop_on_entry` to debug configs in debug.json
instead of going through initialization args.

This has two benefits:

1. It's more streamlined to a user since every internal adapter supports
`stop_on_entry` for launch requests and Go's adapter supports it for
attach requests too.
2. It will allow @osiewicz `NewSesssionModal` PR to use this field for
the stop on entry checkbox.

Release Notes:

- N/A

Change summary

crates/dap_adapters/src/gdb.rs               | 2 +-
crates/dap_adapters/src/go.rs                | 4 +++-
crates/dap_adapters/src/javascript.rs        | 1 +
crates/dap_adapters/src/lldb.rs              | 1 +
crates/dap_adapters/src/php.rs               | 1 +
crates/dap_adapters/src/python.rs            | 1 +
crates/debugger_ui/src/session/inert.rs      | 2 ++
crates/debugger_ui/src/tests/attach_modal.rs | 1 +
crates/languages/src/rust.rs                 | 2 ++
crates/project/src/debugger/dap_store.rs     | 1 +
crates/project/src/project.rs                | 1 +
crates/task/src/debug_format.rs              | 7 +++++++
crates/task/src/lib.rs                       | 1 +
crates/task/src/task_template.rs             | 2 ++
14 files changed, 25 insertions(+), 2 deletions(-)

Detailed changes

crates/dap_adapters/src/gdb.rs 🔗

@@ -79,7 +79,7 @@ impl DebugAdapter for GdbDebugAdapter {
                 json!({"pid": attach_config.process_id})
             }
             dap::DebugRequestType::Launch(launch_config) => {
-                json!({"program": launch_config.program, "cwd": launch_config.cwd})
+                json!({"program": launch_config.program, "cwd": launch_config.cwd, "stopOnEntry": config.stop_on_entry})
             }
         }
     }

crates/dap_adapters/src/go.rs 🔗

@@ -86,12 +86,14 @@ impl DebugAdapter for GoDebugAdapter {
         match &config.request {
             dap::DebugRequestType::Attach(attach_config) => {
                 json!({
-                    "processId": attach_config.process_id
+                    "processId": attach_config.process_id,
+                    "stopOnEntry": config.stop_on_entry,
                 })
             }
             dap::DebugRequestType::Launch(launch_config) => json!({
                 "program": launch_config.program,
                 "cwd": launch_config.cwd,
+                "stopOnEntry": config.stop_on_entry,
             }),
         }
     }

crates/dap_adapters/src/javascript.rs 🔗

@@ -131,6 +131,7 @@ impl DebugAdapter for JsDebugAdapter {
         match &config.request {
             DebugRequestType::Attach(attach) => {
                 map.insert("processId".into(), attach.process_id.into());
+                map.insert("stopOnEntry".into(), config.stop_on_entry.into());
             }
             DebugRequestType::Launch(launch) => {
                 map.insert("program".into(), launch.program.clone().into());

crates/dap_adapters/src/lldb.rs 🔗

@@ -78,6 +78,7 @@ impl DebugAdapter for LldbDebugAdapter {
         match &config.request {
             DebugRequestType::Attach(attach) => {
                 map.insert("pid".into(), attach.process_id.into());
+                map.insert("stopOnEntry".into(), config.stop_on_entry.into());
             }
             DebugRequestType::Launch(launch) => {
                 map.insert("program".into(), launch.program.clone().into());

crates/dap_adapters/src/php.rs 🔗

@@ -118,6 +118,7 @@ impl DebugAdapter for PhpDebugAdapter {
                 json!({
                     "program": launch_config.program,
                     "cwd": launch_config.cwd,
+                    "stopOnEntry": config.stop_on_entry,
                 })
             }
         }

crates/dap_adapters/src/python.rs 🔗

@@ -133,6 +133,7 @@ impl DebugAdapter for PythonDebugAdapter {
                     "subProcess": true,
                     "cwd": launch_config.cwd,
                     "redirectOutput": true,
+                    "StopOnEntry": config.stop_on_entry,
                 })
             }
             dap::DebugRequestType::Attach(attach_config) => {

crates/debugger_ui/src/session/inert.rs 🔗

@@ -161,6 +161,7 @@ impl Render for InertState {
                             initialize_args: None,
                             args: Default::default(),
                             locator: None,
+                            stop_on_entry: None,
                         },
                     });
                 } else {
@@ -324,6 +325,7 @@ impl InertState {
             args: Default::default(),
             locator: None,
             tcp_connection: Some(TCPHost::default()),
+            stop_on_entry: None,
         };
 
         let _ = self.workspace.update(cx, |workspace, cx| {

crates/debugger_ui/src/tests/attach_modal.rs 🔗

@@ -90,6 +90,7 @@ async fn test_show_attach_modal_and_select_process(
                         initialize_args: None,
                         tcp_connection: Some(TCPHost::default()),
                         locator: None,
+                        stop_on_entry: None,
                         args: Default::default(),
                     },
                     vec![

crates/languages/src/rust.rs 🔗

@@ -637,6 +637,7 @@ impl ContextProvider for RustContextProvider {
                     locator: Some("cargo".into()),
                     tcp_connection: None,
                     initialize_args: None,
+                    stop_on_entry: None,
                 }),
                 command: "cargo".into(),
                 args: vec![
@@ -737,6 +738,7 @@ impl ContextProvider for RustContextProvider {
                     initialize_args: None,
                     locator: Some("cargo".into()),
                     tcp_connection: None,
+                    stop_on_entry: None,
                 }),
                 args: debug_task_args,
                 tags: vec!["rust-main".to_owned()],

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

@@ -472,6 +472,7 @@ impl DapStore {
             tcp_connection: config.tcp_connection.clone(),
             locator: None,
             args: Default::default(),
+            stop_on_entry: config.stop_on_entry,
         };
 
         #[cfg(any(test, feature = "test-support"))]

crates/project/src/project.rs 🔗

@@ -1490,6 +1490,7 @@ impl Project {
             tcp_connection: None,
             locator: None,
             args: Default::default(),
+            stop_on_entry: None,
         };
         let caps = caps.unwrap_or(Capabilities {
             supports_step_back: Some(false),

crates/task/src/debug_format.rs 🔗

@@ -106,6 +106,8 @@ pub struct DebugAdapterConfig {
     pub locator: Option<String>,
     /// Args to pass to a debug adapter (only used in locator right now)
     pub args: Vec<String>,
+    /// Whether to tell the debug adapter to stop on entry
+    pub stop_on_entry: Option<bool>,
 }
 
 impl From<DebugTaskDefinition> for DebugAdapterConfig {
@@ -118,6 +120,7 @@ impl From<DebugTaskDefinition> for DebugAdapterConfig {
             tcp_connection: def.tcp_connection,
             locator: def.locator,
             args: def.args,
+            stop_on_entry: def.stop_on_entry,
         }
     }
 }
@@ -138,6 +141,7 @@ impl TryFrom<DebugAdapterConfig> for DebugTaskDefinition {
             tcp_connection: def.tcp_connection,
             locator: def.locator,
             args: def.args,
+            stop_on_entry: def.stop_on_entry,
         })
     }
 }
@@ -166,6 +170,7 @@ impl DebugTaskDefinition {
             initialize_args: self.initialize_args,
             locator: self.locator,
             tcp_connection: self.tcp_connection,
+            stop_on_entry: self.stop_on_entry,
         });
 
         let label = self.label.clone();
@@ -215,6 +220,8 @@ pub struct DebugTaskDefinition {
     /// Args to pass to a debug adapter (only used in locator right now)
     #[serde(skip)]
     pub args: Vec<String>,
+    /// Whether to tell the debug adapter to stop on entry
+    pub stop_on_entry: Option<bool>,
 }
 
 /// A group of Debug Tasks defined in a JSON file.

crates/task/src/lib.rs 🔗

@@ -144,6 +144,7 @@ impl ResolvedTask {
                     tcp_connection: debug_args.tcp_connection,
                     args,
                     locator: debug_args.locator.clone(),
+                    stop_on_entry: debug_args.stop_on_entry,
                 })
             }
             _ => None,

crates/task/src/task_template.rs 🔗

@@ -97,6 +97,8 @@ pub struct DebugArgs {
     pub initialize_args: Option<serde_json::value::Value>,
     /// the locator to use
     pub locator: Option<String>,
+    /// Whether to tell the debug adapter to stop on entry
+    pub stop_on_entry: Option<bool>,
 }
 
 /// Represents the type of task that is being ran