extension: Update DAP extension API (#32448)

- DAP schemas will be stored in `debug_adapters_schemas` subdirectory in
extension work dir.
- Added Debug Config integration and such.

Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2025-06-16 16:25:32 +02:00 committed by GitHub
parent 41e9f3148c
commit 8df6ce2aac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 620 additions and 47 deletions

View file

@ -12,6 +12,7 @@ dap.workspace = true
extension.workspace = true
gpui.workspace = true
serde_json.workspace = true
util.workspace = true
task.workspace = true
workspace-hack = { version = "0.1", path = "../../tooling/workspace-hack" }

View file

@ -1,4 +1,5 @@
mod extension_dap_adapter;
mod extension_locator_adapter;
use std::sync::Arc;
@ -6,6 +7,9 @@ use dap::DapRegistry;
use extension::{ExtensionDebugAdapterProviderProxy, ExtensionHostProxy};
use extension_dap_adapter::ExtensionDapAdapter;
use gpui::App;
use util::ResultExt;
use crate::extension_locator_adapter::ExtensionLocatorAdapter;
pub fn init(extension_host_proxy: Arc<ExtensionHostProxy>, cx: &mut App) {
let language_server_registry_proxy = DebugAdapterRegistryProxy::new(cx);
@ -30,11 +34,21 @@ impl ExtensionDebugAdapterProviderProxy for DebugAdapterRegistryProxy {
&self,
extension: Arc<dyn extension::Extension>,
debug_adapter_name: Arc<str>,
) {
if let Some(adapter) = ExtensionDapAdapter::new(extension, debug_adapter_name).log_err() {
self.debug_adapter_registry.add_adapter(Arc::new(adapter));
}
}
fn register_debug_locator(
&self,
extension: Arc<dyn extension::Extension>,
locator_name: Arc<str>,
) {
self.debug_adapter_registry
.add_adapter(Arc::new(ExtensionDapAdapter::new(
.add_locator(Arc::new(ExtensionLocatorAdapter::new(
extension,
debug_adapter_name,
locator_name,
)));
}
}

View file

@ -1,6 +1,10 @@
use std::{path::PathBuf, sync::Arc};
use std::{
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
};
use anyhow::Result;
use anyhow::{Context, Result};
use async_trait::async_trait;
use dap::adapters::{
DapDelegate, DebugAdapter, DebugAdapterBinary, DebugAdapterName, DebugTaskDefinition,
@ -12,17 +16,26 @@ use task::{DebugScenario, ZedDebugConfig};
pub(crate) struct ExtensionDapAdapter {
extension: Arc<dyn Extension>,
debug_adapter_name: Arc<str>,
schema: serde_json::Value,
}
impl ExtensionDapAdapter {
pub(crate) fn new(
extension: Arc<dyn extension::Extension>,
debug_adapter_name: Arc<str>,
) -> Self {
Self {
) -> Result<Self> {
let schema = std::fs::read_to_string(extension.path_from_extension(
&Path::new("debug_adapter_schemas").join(debug_adapter_name.as_ref()),
))
.with_context(|| format!("Failed to read debug adapter schema for {debug_adapter_name}"))?;
let schema = serde_json::Value::from_str(&schema).with_context(|| {
format!("Debug adapter schema for {debug_adapter_name} is not a valid JSON")
})?;
Ok(Self {
extension,
debug_adapter_name,
}
schema,
})
}
}
@ -61,8 +74,8 @@ impl DebugAdapter for ExtensionDapAdapter {
self.debug_adapter_name.as_ref().into()
}
async fn dap_schema(&self) -> serde_json::Value {
self.extension.get_dap_schema().await.unwrap_or_default()
fn dap_schema(&self) -> serde_json::Value {
self.schema.clone()
}
async fn get_binary(

View file

@ -0,0 +1,50 @@
use anyhow::Result;
use async_trait::async_trait;
use dap::{DapLocator, DebugRequest, adapters::DebugAdapterName};
use extension::Extension;
use gpui::SharedString;
use std::sync::Arc;
use task::{DebugScenario, SpawnInTerminal, TaskTemplate};
pub(crate) struct ExtensionLocatorAdapter {
extension: Arc<dyn Extension>,
locator_name: SharedString,
}
impl ExtensionLocatorAdapter {
pub(crate) fn new(extension: Arc<dyn extension::Extension>, locator_name: Arc<str>) -> Self {
Self {
extension,
locator_name: SharedString::from(locator_name),
}
}
}
#[async_trait]
impl DapLocator for ExtensionLocatorAdapter {
fn name(&self) -> SharedString {
self.locator_name.clone()
}
/// Determines whether this locator can generate debug target for given task.
async fn create_scenario(
&self,
build_config: &TaskTemplate,
resolved_label: &str,
adapter: &DebugAdapterName,
) -> Option<DebugScenario> {
self.extension
.dap_locator_create_scenario(
self.locator_name.as_ref().to_owned(),
build_config.clone(),
resolved_label.to_owned(),
adapter.0.as_ref().to_owned(),
)
.await
.ok()
.flatten()
}
async fn run(&self, _build_config: SpawnInTerminal) -> Result<DebugRequest> {
Err(anyhow::anyhow!("Not implemented"))
}
}