extension: Another batch of updates for DAP extension API (#32809)

Closes #ISSUE

Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2025-06-16 21:34:05 +02:00 committed by GitHub
parent 4383fee3c1
commit 0f0ff40c6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 142 additions and 107 deletions

View file

@ -337,7 +337,7 @@ pub async fn download_adapter_from_github(
pub trait DebugAdapter: 'static + Send + Sync { pub trait DebugAdapter: 'static + Send + Sync {
fn name(&self) -> DebugAdapterName; fn name(&self) -> DebugAdapterName;
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario>; async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario>;
async fn get_binary( async fn get_binary(
&self, &self,
@ -355,7 +355,7 @@ pub trait DebugAdapter: 'static + Send + Sync {
/// Extracts the kind (attach/launch) of debug configuration from the given JSON config. /// Extracts the kind (attach/launch) of debug configuration from the given JSON config.
/// This method should only return error when the kind cannot be determined for a given configuration; /// This method should only return error when the kind cannot be determined for a given configuration;
/// in particular, it *should not* validate whether the request as a whole is valid, because that's best left to the debug adapter itself to decide. /// in particular, it *should not* validate whether the request as a whole is valid, because that's best left to the debug adapter itself to decide.
fn request_kind( async fn request_kind(
&self, &self,
config: &serde_json::Value, config: &serde_json::Value,
) -> Result<StartDebuggingRequestArgumentsRequest> { ) -> Result<StartDebuggingRequestArgumentsRequest> {
@ -398,7 +398,7 @@ impl DebugAdapter for FakeAdapter {
serde_json::Value::Null serde_json::Value::Null
} }
fn request_kind( async fn request_kind(
&self, &self,
config: &serde_json::Value, config: &serde_json::Value,
) -> Result<StartDebuggingRequestArgumentsRequest> { ) -> Result<StartDebuggingRequestArgumentsRequest> {
@ -417,7 +417,7 @@ impl DebugAdapter for FakeAdapter {
None None
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
let config = serde_json::to_value(zed_scenario.request).unwrap(); let config = serde_json::to_value(zed_scenario.request).unwrap();
Ok(DebugScenario { Ok(DebugScenario {
@ -443,7 +443,7 @@ impl DebugAdapter for FakeAdapter {
envs: HashMap::default(), envs: HashMap::default(),
cwd: None, cwd: None,
request_args: StartDebuggingRequestArguments { request_args: StartDebuggingRequestArguments {
request: self.request_kind(&task_definition.config)?, request: self.request_kind(&task_definition.config).await?,
configuration: task_definition.config.clone(), configuration: task_definition.config.clone(),
}, },
}) })

View file

@ -51,18 +51,26 @@ pub fn send_telemetry(scenario: &DebugScenario, location: TelemetrySpawnLocation
let Some(adapter) = cx.global::<DapRegistry>().adapter(&scenario.adapter) else { let Some(adapter) = cx.global::<DapRegistry>().adapter(&scenario.adapter) else {
return; return;
}; };
let kind = adapter
.request_kind(&scenario.config)
.ok()
.map(serde_json::to_value)
.and_then(Result::ok);
let dock = DebuggerSettings::get_global(cx).dock; let dock = DebuggerSettings::get_global(cx).dock;
telemetry::event!( let config = scenario.config.clone();
"Debugger Session Started", let with_build_task = scenario.build.is_some();
spawn_location = location, let adapter_name = scenario.adapter.clone();
with_build_task = scenario.build.is_some(), cx.spawn(async move |_| {
kind = kind, let kind = adapter
adapter = scenario.adapter.as_ref(), .request_kind(&config)
dock_position = dock, .await
); .ok()
.map(serde_json::to_value)
.and_then(Result::ok);
telemetry::event!(
"Debugger Session Started",
spawn_location = location,
with_build_task = with_build_task,
kind = kind,
adapter = adapter_name,
dock_position = dock,
);
})
.detach();
} }

View file

@ -19,7 +19,7 @@ pub(crate) struct CodeLldbDebugAdapter {
impl CodeLldbDebugAdapter { impl CodeLldbDebugAdapter {
const ADAPTER_NAME: &'static str = "CodeLLDB"; const ADAPTER_NAME: &'static str = "CodeLLDB";
fn request_args( async fn request_args(
&self, &self,
delegate: &Arc<dyn DapDelegate>, delegate: &Arc<dyn DapDelegate>,
task_definition: &DebugTaskDefinition, task_definition: &DebugTaskDefinition,
@ -37,7 +37,7 @@ impl CodeLldbDebugAdapter {
obj.entry("cwd") obj.entry("cwd")
.or_insert(delegate.worktree_root_path().to_string_lossy().into()); .or_insert(delegate.worktree_root_path().to_string_lossy().into());
let request = self.request_kind(&configuration)?; let request = self.request_kind(&configuration).await?;
Ok(dap::StartDebuggingRequestArguments { Ok(dap::StartDebuggingRequestArguments {
request, request,
@ -89,7 +89,7 @@ impl DebugAdapter for CodeLldbDebugAdapter {
DebugAdapterName(Self::ADAPTER_NAME.into()) DebugAdapterName(Self::ADAPTER_NAME.into())
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
let mut configuration = json!({ let mut configuration = json!({
"request": match zed_scenario.request { "request": match zed_scenario.request {
DebugRequest::Launch(_) => "launch", DebugRequest::Launch(_) => "launch",
@ -368,7 +368,7 @@ impl DebugAdapter for CodeLldbDebugAdapter {
"--settings".into(), "--settings".into(),
json!({"sourceLanguages": ["cpp", "rust"]}).to_string(), json!({"sourceLanguages": ["cpp", "rust"]}).to_string(),
], ],
request_args: self.request_args(delegate, &config)?, request_args: self.request_args(delegate, &config).await?,
envs: HashMap::default(), envs: HashMap::default(),
connection: None, connection: None,
}) })

View file

@ -21,7 +21,7 @@ impl DebugAdapter for GdbDebugAdapter {
DebugAdapterName(Self::ADAPTER_NAME.into()) DebugAdapterName(Self::ADAPTER_NAME.into())
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
let mut obj = serde_json::Map::default(); let mut obj = serde_json::Map::default();
match &zed_scenario.request { match &zed_scenario.request {
@ -191,7 +191,7 @@ impl DebugAdapter for GdbDebugAdapter {
cwd: Some(delegate.worktree_root_path().to_path_buf()), cwd: Some(delegate.worktree_root_path().to_path_buf()),
connection: None, connection: None,
request_args: StartDebuggingRequestArguments { request_args: StartDebuggingRequestArguments {
request: self.request_kind(&config.config)?, request: self.request_kind(&config.config).await?,
configuration, configuration,
}, },
}) })

View file

@ -352,7 +352,7 @@ impl DebugAdapter for GoDebugAdapter {
}) })
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
let mut args = match &zed_scenario.request { let mut args = match &zed_scenario.request {
dap::DebugRequest::Attach(attach_config) => { dap::DebugRequest::Attach(attach_config) => {
json!({ json!({
@ -495,7 +495,7 @@ impl DebugAdapter for GoDebugAdapter {
connection, connection,
request_args: StartDebuggingRequestArguments { request_args: StartDebuggingRequestArguments {
configuration, configuration,
request: self.request_kind(&task_definition.config)?, request: self.request_kind(&task_definition.config).await?,
}, },
}) })
} }

View file

@ -124,7 +124,7 @@ impl JsDebugAdapter {
}), }),
request_args: StartDebuggingRequestArguments { request_args: StartDebuggingRequestArguments {
configuration, configuration,
request: self.request_kind(&task_definition.config)?, request: self.request_kind(&task_definition.config).await?,
}, },
}) })
} }
@ -136,7 +136,7 @@ impl DebugAdapter for JsDebugAdapter {
DebugAdapterName(Self::ADAPTER_NAME.into()) DebugAdapterName(Self::ADAPTER_NAME.into())
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
let mut args = json!({ let mut args = json!({
"type": "pwa-node", "type": "pwa-node",
"request": match zed_scenario.request { "request": match zed_scenario.request {

View file

@ -102,7 +102,8 @@ impl PhpDebugAdapter {
envs: HashMap::default(), envs: HashMap::default(),
request_args: StartDebuggingRequestArguments { request_args: StartDebuggingRequestArguments {
configuration, configuration,
request: <Self as DebugAdapter>::request_kind(self, &task_definition.config)?, request: <Self as DebugAdapter>::request_kind(self, &task_definition.config)
.await?,
}, },
}) })
} }
@ -290,11 +291,14 @@ impl DebugAdapter for PhpDebugAdapter {
Some(SharedString::new_static("PHP").into()) Some(SharedString::new_static("PHP").into())
} }
fn request_kind(&self, _: &serde_json::Value) -> Result<StartDebuggingRequestArgumentsRequest> { async fn request_kind(
&self,
_: &serde_json::Value,
) -> Result<StartDebuggingRequestArgumentsRequest> {
Ok(StartDebuggingRequestArgumentsRequest::Launch) Ok(StartDebuggingRequestArgumentsRequest::Launch)
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
let obj = match &zed_scenario.request { let obj = match &zed_scenario.request {
dap::DebugRequest::Attach(_) => { dap::DebugRequest::Attach(_) => {
bail!("Php adapter doesn't support attaching") bail!("Php adapter doesn't support attaching")

View file

@ -81,12 +81,12 @@ impl PythonDebugAdapter {
} }
} }
fn request_args( async fn request_args(
&self, &self,
delegate: &Arc<dyn DapDelegate>, delegate: &Arc<dyn DapDelegate>,
task_definition: &DebugTaskDefinition, task_definition: &DebugTaskDefinition,
) -> Result<StartDebuggingRequestArguments> { ) -> Result<StartDebuggingRequestArguments> {
let request = self.request_kind(&task_definition.config)?; let request = self.request_kind(&task_definition.config).await?;
let mut configuration = task_definition.config.clone(); let mut configuration = task_definition.config.clone();
if let Ok(console) = configuration.dot_get_mut("console") { if let Ok(console) = configuration.dot_get_mut("console") {
@ -202,7 +202,7 @@ impl PythonDebugAdapter {
}), }),
cwd: Some(delegate.worktree_root_path().to_path_buf()), cwd: Some(delegate.worktree_root_path().to_path_buf()),
envs: HashMap::default(), envs: HashMap::default(),
request_args: self.request_args(delegate, config)?, request_args: self.request_args(delegate, config).await?,
}) })
} }
} }
@ -217,7 +217,7 @@ impl DebugAdapter for PythonDebugAdapter {
Some(SharedString::new_static("Python").into()) Some(SharedString::new_static("Python").into())
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
let mut args = json!({ let mut args = json!({
"request": match zed_scenario.request { "request": match zed_scenario.request {
DebugRequest::Launch(_) => "launch", DebugRequest::Launch(_) => "launch",

View file

@ -45,7 +45,10 @@ impl DebugAdapter for RubyDebugAdapter {
Some(SharedString::new_static("Ruby").into()) Some(SharedString::new_static("Ruby").into())
} }
fn request_kind(&self, _: &serde_json::Value) -> Result<StartDebuggingRequestArgumentsRequest> { async fn request_kind(
&self,
_: &serde_json::Value,
) -> Result<StartDebuggingRequestArgumentsRequest> {
Ok(StartDebuggingRequestArgumentsRequest::Launch) Ok(StartDebuggingRequestArgumentsRequest::Launch)
} }
@ -83,7 +86,7 @@ impl DebugAdapter for RubyDebugAdapter {
}) })
} }
fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
match zed_scenario.request { match zed_scenario.request {
DebugRequest::Launch(launch) => { DebugRequest::Launch(launch) => {
let config = RubyDebugConfig { let config = RubyDebugConfig {
@ -196,7 +199,7 @@ impl DebugAdapter for RubyDebugAdapter {
), ),
envs: ruby_config.env.into_iter().collect(), envs: ruby_config.env.into_iter().collect(),
request_args: StartDebuggingRequestArguments { request_args: StartDebuggingRequestArguments {
request: self.request_kind(&definition.config)?, request: self.request_kind(&definition.config).await?,
configuration, configuration,
}, },
}) })

View file

@ -6,8 +6,11 @@ use std::{
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
use dap::adapters::{ use dap::{
DapDelegate, DebugAdapter, DebugAdapterBinary, DebugAdapterName, DebugTaskDefinition, StartDebuggingRequestArgumentsRequest,
adapters::{
DapDelegate, DebugAdapter, DebugAdapterBinary, DebugAdapterName, DebugTaskDefinition,
},
}; };
use extension::{Extension, WorktreeDelegate}; use extension::{Extension, WorktreeDelegate};
use gpui::AsyncApp; use gpui::AsyncApp;
@ -95,7 +98,16 @@ impl DebugAdapter for ExtensionDapAdapter {
.await .await
} }
fn config_from_zed_format(&self, _zed_scenario: ZedDebugConfig) -> Result<DebugScenario> { async fn config_from_zed_format(&self, zed_scenario: ZedDebugConfig) -> Result<DebugScenario> {
Err(anyhow::anyhow!("DAP extensions are not implemented yet")) self.extension.dap_config_to_scenario(zed_scenario).await
}
async fn request_kind(
&self,
config: &serde_json::Value,
) -> Result<StartDebuggingRequestArgumentsRequest> {
self.extension
.dap_request_kind(self.debug_adapter_name.clone(), config.clone())
.await
} }
} }

View file

@ -228,26 +228,36 @@ impl PickerDelegate for AttachModalDelegate {
} }
} }
let Some(scenario) = cx.read_global::<DapRegistry, _>(|registry, _| { let Some(adapter) = cx.read_global::<DapRegistry, _>(|registry, _| {
registry registry.adapter(&self.definition.adapter)
.adapter(&self.definition.adapter)
.and_then(|adapter| adapter.config_from_zed_format(self.definition.clone()).ok())
}) else { }) else {
return; return;
}; };
let panel = self let workspace = self.workspace.clone();
.workspace let definition = self.definition.clone();
.update(cx, |workspace, cx| workspace.panel::<DebugPanel>(cx)) cx.spawn_in(window, async move |this, cx| {
.ok() let Ok(scenario) = adapter.config_from_zed_format(definition).await else {
.flatten(); return;
if let Some(panel) = panel { };
panel.update(cx, |panel, cx| {
panel.start_session(scenario, Default::default(), None, None, window, cx);
});
}
cx.emit(DismissEvent); let panel = workspace
.update(cx, |workspace, cx| workspace.panel::<DebugPanel>(cx))
.ok()
.flatten();
if let Some(panel) = panel {
panel
.update_in(cx, |panel, window, cx| {
panel.start_session(scenario, Default::default(), None, None, window, cx);
})
.ok();
}
this.update(cx, |_, cx| {
cx.emit(DismissEvent);
})
.ok();
})
.detach();
} }
fn dismissed(&mut self, _window: &mut Window, cx: &mut Context<Picker<Self>>) { fn dismissed(&mut self, _window: &mut Window, cx: &mut Context<Picker<Self>>) {

View file

@ -1,3 +1,4 @@
use anyhow::bail;
use collections::{FxHashMap, HashMap}; use collections::{FxHashMap, HashMap};
use language::LanguageRegistry; use language::LanguageRegistry;
use paths::local_debug_file_relative_path; use paths::local_debug_file_relative_path;
@ -307,16 +308,16 @@ impl NewProcessModal {
} }
} }
fn debug_scenario(&self, debugger: &str, cx: &App) -> Option<DebugScenario> { fn debug_scenario(&self, debugger: &str, cx: &App) -> Task<Option<DebugScenario>> {
let request = match self.mode { let request = match self.mode {
NewProcessMode::Launch => Some(DebugRequest::Launch( NewProcessMode::Launch => {
self.configure_mode.read(cx).debug_request(cx), DebugRequest::Launch(self.configure_mode.read(cx).debug_request(cx))
)), }
NewProcessMode::Attach => Some(DebugRequest::Attach( NewProcessMode::Attach => {
self.attach_mode.read(cx).debug_request(), DebugRequest::Attach(self.attach_mode.read(cx).debug_request())
)), }
_ => None, _ => return Task::ready(None),
}?; };
let label = suggested_label(&request, debugger); let label = suggested_label(&request, debugger);
let stop_on_entry = if let NewProcessMode::Launch = &self.mode { let stop_on_entry = if let NewProcessMode::Launch = &self.mode {
@ -328,13 +329,15 @@ impl NewProcessModal {
let session_scenario = ZedDebugConfig { let session_scenario = ZedDebugConfig {
adapter: debugger.to_owned().into(), adapter: debugger.to_owned().into(),
label, label,
request: request, request,
stop_on_entry, stop_on_entry,
}; };
cx.global::<DapRegistry>() let adapter = cx
.adapter(&session_scenario.adapter) .global::<DapRegistry>()
.and_then(|adapter| adapter.config_from_zed_format(session_scenario).ok()) .adapter(&session_scenario.adapter);
cx.spawn(async move |_| adapter?.config_from_zed_format(session_scenario).await.ok())
} }
fn start_new_session(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn start_new_session(&mut self, window: &mut Window, cx: &mut Context<Self>) {
@ -356,12 +359,7 @@ impl NewProcessModal {
// } // }
// } // }
let Some(debugger) = self.debugger.as_ref() else { let Some(debugger) = self.debugger.clone() else {
return;
};
let Some(config) = self.debug_scenario(debugger, cx) else {
log::error!("debug config not found in mode: {}", self.mode);
return; return;
}; };
@ -369,11 +367,20 @@ impl NewProcessModal {
let Some(task_contexts) = self.task_contexts(cx) else { let Some(task_contexts) = self.task_contexts(cx) else {
return; return;
}; };
send_telemetry(&config, TelemetrySpawnLocation::Custom, cx);
let task_context = task_contexts.active_context().cloned().unwrap_or_default(); let task_context = task_contexts.active_context().cloned().unwrap_or_default();
let worktree_id = task_contexts.worktree(); let worktree_id = task_contexts.worktree();
let mode = self.mode;
cx.spawn_in(window, async move |this, cx| { cx.spawn_in(window, async move |this, cx| {
let Some(config) = this
.update(cx, |this, cx| this.debug_scenario(&debugger, cx))?
.await
else {
bail!("debug config not found in mode: {mode}");
};
debug_panel.update_in(cx, |debug_panel, window, cx| { debug_panel.update_in(cx, |debug_panel, window, cx| {
send_telemetry(&config, TelemetrySpawnLocation::Custom, cx);
debug_panel.start_session(config, task_context, None, worktree_id, window, cx) debug_panel.start_session(config, task_context, None, worktree_id, window, cx)
})?; })?;
this.update(cx, |_, cx| { this.update(cx, |_, cx| {
@ -586,7 +593,7 @@ impl NewProcessModal {
static SELECT_DEBUGGER_LABEL: SharedString = SharedString::new_static("Select Debugger"); static SELECT_DEBUGGER_LABEL: SharedString = SharedString::new_static("Select Debugger");
#[derive(Clone)] #[derive(Clone, Copy)]
pub(crate) enum NewProcessMode { pub(crate) enum NewProcessMode {
Task, Task,
Launch, Launch,

View file

@ -816,10 +816,13 @@ impl RunningState {
Self::relativize_paths(None, &mut config, &task_context); Self::relativize_paths(None, &mut config, &task_context);
Self::substitute_variables_in_config(&mut config, &task_context); Self::substitute_variables_in_config(&mut config, &task_context);
let request_type = dap_registry let request_type = match dap_registry
.adapter(&adapter) .adapter(&adapter)
.with_context(|| format!("{}: is not a valid adapter name", &adapter)) .with_context(|| format!("{}: is not a valid adapter name", &adapter)) {
.and_then(|adapter| adapter.request_kind(&config)); Ok(adapter) => adapter.request_kind(&config).await,
Err(e) => Err(e)
};
let config_is_valid = request_type.is_ok(); let config_is_valid = request_type.is_ok();
@ -958,8 +961,8 @@ impl RunningState {
let scenario = dap_registry let scenario = dap_registry
.adapter(&adapter) .adapter(&adapter)
.with_context(|| anyhow!("{}: is not a valid adapter name", &adapter)) .with_context(|| anyhow!("{}: is not a valid adapter name", &adapter))?.config_from_zed_format(zed_config)
.map(|adapter| adapter.config_from_zed_format(zed_config))??; .await?;
config = scenario.config; config = scenario.config;
Self::substitute_variables_in_config(&mut config, &task_context); Self::substitute_variables_in_config(&mut config, &task_context);
} else { } else {

View file

@ -308,6 +308,7 @@ async fn test_dap_adapter_config_conversion_and_validation(cx: &mut TestAppConte
let debug_scenario = adapter let debug_scenario = adapter
.config_from_zed_format(adapter_specific_config) .config_from_zed_format(adapter_specific_config)
.await
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
panic!( panic!(
"Adapter {} should successfully convert from Zed format", "Adapter {} should successfully convert from Zed format",
@ -323,6 +324,7 @@ async fn test_dap_adapter_config_conversion_and_validation(cx: &mut TestAppConte
let request_type = adapter let request_type = adapter
.request_kind(&debug_scenario.config) .request_kind(&debug_scenario.config)
.await
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
panic!( panic!(
"Adapter {} should validate the config successfully", "Adapter {} should validate the config successfully",

View file

@ -151,11 +151,7 @@ pub trait Extension: Send + Sync + 'static {
config: serde_json::Value, config: serde_json::Value,
) -> Result<StartDebuggingRequestArgumentsRequest>; ) -> Result<StartDebuggingRequestArgumentsRequest>;
async fn dap_config_to_scenario( async fn dap_config_to_scenario(&self, config: ZedDebugConfig) -> Result<DebugScenario>;
&self,
config: ZedDebugConfig,
worktree: Arc<dyn WorktreeDelegate>,
) -> Result<DebugScenario>;
async fn dap_locator_create_scenario( async fn dap_locator_create_scenario(
&self, &self,

View file

@ -20,9 +20,9 @@ pub use wit::{
make_file_executable, make_file_executable,
zed::extension::context_server::ContextServerConfiguration, zed::extension::context_server::ContextServerConfiguration,
zed::extension::dap::{ zed::extension::dap::{
DebugAdapterBinary, DebugRequest, DebugTaskDefinition, StartDebuggingRequestArguments, DebugAdapterBinary, DebugConfig, DebugRequest, DebugScenario, DebugTaskDefinition,
StartDebuggingRequestArgumentsRequest, TaskTemplate, TcpArguments, TcpArgumentsTemplate, StartDebuggingRequestArguments, StartDebuggingRequestArgumentsRequest, TaskTemplate,
resolve_tcp_template, TcpArguments, TcpArgumentsTemplate, resolve_tcp_template,
}, },
zed::extension::github::{ zed::extension::github::{
GithubRelease, GithubReleaseAsset, GithubReleaseOptions, github_release_by_tag_name, GithubRelease, GithubReleaseAsset, GithubReleaseOptions, github_release_by_tag_name,
@ -214,7 +214,6 @@ pub trait Extension: Send + Sync {
fn dap_config_to_scenario( fn dap_config_to_scenario(
&mut self, &mut self,
_adapter_name: DebugConfig, _adapter_name: DebugConfig,
_config: &Worktree,
) -> Result<DebugScenario, String> { ) -> Result<DebugScenario, String> {
Err("`dap_config_to_scenario` not implemented".to_string()) Err("`dap_config_to_scenario` not implemented".to_string())
} }
@ -437,11 +436,8 @@ impl wit::Guest for Component {
serde_json::from_str(&config).map_err(|e| format!("Failed to parse config: {e}"))?, serde_json::from_str(&config).map_err(|e| format!("Failed to parse config: {e}"))?,
) )
} }
fn dap_config_to_scenario( fn dap_config_to_scenario(config: DebugConfig) -> Result<DebugScenario, String> {
config: DebugConfig, extension().dap_config_to_scenario(config)
worktree: &Worktree,
) -> Result<DebugScenario, String> {
extension().dap_config_to_scenario(config, worktree)
} }
fn dap_locator_create_scenario( fn dap_locator_create_scenario(
locator_name: String, locator_name: String,

View file

@ -161,7 +161,7 @@ world extension {
export get-dap-binary: func(adapter-name: string, config: debug-task-definition, user-installed-path: option<string>, worktree: borrow<worktree>) -> result<debug-adapter-binary, string>; export get-dap-binary: func(adapter-name: string, config: debug-task-definition, user-installed-path: option<string>, worktree: borrow<worktree>) -> result<debug-adapter-binary, string>;
/// Returns the kind of a debug scenario (launch or attach). /// Returns the kind of a debug scenario (launch or attach).
export dap-request-kind: func(adapter-name: string, config: string) -> result<start-debugging-request-arguments-request, string>; export dap-request-kind: func(adapter-name: string, config: string) -> result<start-debugging-request-arguments-request, string>;
export dap-config-to-scenario: func(config: debug-config, worktree: borrow<worktree>) -> result<debug-scenario, string>; export dap-config-to-scenario: func(config: debug-config) -> result<debug-scenario, string>;
export dap-locator-create-scenario: func(locator-name: string, build-config-template: build-task-template, resolved-label: string, debug-adapter-name: string) -> option<debug-scenario>; export dap-locator-create-scenario: func(locator-name: string, build-config-template: build-task-template, resolved-label: string, debug-adapter-name: string) -> option<debug-scenario>;
export run-dap-locator: func(locator-name: string, config: resolved-task) -> result<debug-request, string>; export run-dap-locator: func(locator-name: string, config: resolved-task) -> result<debug-request, string>;
} }

View file

@ -419,16 +419,11 @@ impl extension::Extension for WasmExtension {
.await .await
} }
async fn dap_config_to_scenario( async fn dap_config_to_scenario(&self, config: ZedDebugConfig) -> Result<DebugScenario> {
&self,
config: ZedDebugConfig,
worktree: Arc<dyn WorktreeDelegate>,
) -> Result<DebugScenario> {
self.call(|extension, store| { self.call(|extension, store| {
async move { async move {
let resource = store.data_mut().table().push(worktree)?;
let kind = extension let kind = extension
.call_dap_config_to_scenario(store, config, resource) .call_dap_config_to_scenario(store, config)
.await? .await?
.map_err(|err| store.data().extension_error(err))?; .map_err(|err| store.data().extension_error(err))?;
Ok(kind) Ok(kind)

View file

@ -950,13 +950,12 @@ impl Extension {
&self, &self,
store: &mut Store<WasmState>, store: &mut Store<WasmState>,
config: ZedDebugConfig, config: ZedDebugConfig,
resource: Resource<Arc<dyn WorktreeDelegate>>,
) -> Result<Result<DebugScenario, String>> { ) -> Result<Result<DebugScenario, String>> {
match self { match self {
Extension::V0_6_0(ext) => { Extension::V0_6_0(ext) => {
let config = config.into(); let config = config.into();
let dap_binary = ext let dap_binary = ext
.call_dap_config_to_scenario(store, &config, resource) .call_dap_config_to_scenario(store, &config)
.await? .await?
.map_err(|e| anyhow!("{e:?}"))?; .map_err(|e| anyhow!("{e:?}"))?;