debugger: Remove fake adapter and un-gate GDB (#27557)

This is a clean-up PR in anticipation of introduction of Debugger
Registry. I wanna get rid of DebugAdapterKind (or rather, it being an
enum).
Release Notes:

- N/A

---------

Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Anthony <anthony@zed.dev>
This commit is contained in:
Piotr Osiewicz 2025-03-27 23:31:58 +01:00 committed by GitHub
parent 56eb650f09
commit 4839195003
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 1315 additions and 924 deletions

View file

@ -8,6 +8,10 @@ license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/dap.rs"
doctest = false
[features]
test-support = [
"gpui/test-support",
@ -35,6 +39,7 @@ log.workspace = true
node_runtime.workspace = true
parking_lot.workspace = true
paths.workspace = true
regex.workspace = true
schemars.workspace = true
serde.workspace = true
serde_json.workspace = true

View file

@ -13,15 +13,16 @@ use serde_json::Value;
use settings::WorktreeId;
use smol::{self, fs::File, lock::Mutex};
use std::{
borrow::Borrow,
collections::{HashMap, HashSet},
ffi::{OsStr, OsString},
fmt::Debug,
net::Ipv4Addr,
ops::Deref,
path::{Path, PathBuf},
sync::Arc,
path::PathBuf,
sync::{Arc, LazyLock},
};
use task::DebugAdapterConfig;
use task::{DebugAdapterConfig, DebugTaskDefinition};
use util::ResultExt;
#[derive(Clone, Debug, PartialEq, Eq)]
@ -46,7 +47,7 @@ pub trait DapDelegate {
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub struct DebugAdapterName(pub Arc<str>);
pub struct DebugAdapterName(pub SharedString);
impl Deref for DebugAdapterName {
type Target = str;
@ -62,9 +63,9 @@ impl AsRef<str> for DebugAdapterName {
}
}
impl AsRef<Path> for DebugAdapterName {
fn as_ref(&self) -> &Path {
Path::new(&*self.0)
impl Borrow<str> for DebugAdapterName {
fn borrow(&self) -> &str {
&self.0
}
}
@ -76,7 +77,7 @@ impl std::fmt::Display for DebugAdapterName {
impl From<DebugAdapterName> for SharedString {
fn from(name: DebugAdapterName) -> Self {
SharedString::from(name.0)
name.0
}
}
@ -123,7 +124,7 @@ pub async fn download_adapter_from_github(
file_type: DownloadedFileType,
delegate: &dyn DapDelegate,
) -> Result<PathBuf> {
let adapter_path = paths::debug_adapters_dir().join(&adapter_name);
let adapter_path = paths::debug_adapters_dir().join(&adapter_name.as_ref());
let version_path = adapter_path.join(format!("{}_{}", adapter_name, github_version.tag_name));
let fs = delegate.fs();
@ -288,15 +289,21 @@ pub trait DebugAdapter: 'static + Send + Sync {
) -> Result<DebugAdapterBinary>;
/// Should return base configuration to make the debug adapter work
fn request_args(&self, config: &DebugAdapterConfig) -> Value;
fn request_args(&self, config: &DebugTaskDefinition) -> Value;
fn attach_processes_filter(&self) -> regex::Regex {
EMPTY_REGEX.clone()
}
}
static EMPTY_REGEX: LazyLock<regex::Regex> =
LazyLock::new(|| regex::Regex::new("").expect("Regex compilation to succeed"));
#[cfg(any(test, feature = "test-support"))]
pub struct FakeAdapter {}
#[cfg(any(test, feature = "test-support"))]
impl FakeAdapter {
const ADAPTER_NAME: &'static str = "fake-adapter";
pub const ADAPTER_NAME: &'static str = "fake-adapter";
pub fn new() -> Self {
Self {}
@ -351,13 +358,13 @@ impl DebugAdapter for FakeAdapter {
unimplemented!("get installed binary");
}
fn request_args(&self, config: &DebugAdapterConfig) -> Value {
fn request_args(&self, config: &DebugTaskDefinition) -> Value {
use serde_json::json;
use task::DebugRequestType;
json!({
"request": match config.request {
DebugRequestType::Launch => "launch",
DebugRequestType::Launch(_) => "launch",
DebugRequestType::Attach(_) => "attach",
},
"process_id": if let DebugRequestType::Attach(attach_config) = &config.request {
@ -367,4 +374,10 @@ impl DebugAdapter for FakeAdapter {
},
})
}
fn attach_processes_filter(&self) -> regex::Regex {
static REGEX: LazyLock<regex::Regex> =
LazyLock::new(|| regex::Regex::new("^fake-binary").unwrap());
REGEX.clone()
}
}

View file

@ -71,7 +71,6 @@ impl DebugAdapterClient {
let client_id = this.id;
// start handling events/reverse requests
cx.background_spawn(Self::handle_receive_messages(
client_id,
server_rx,
@ -119,7 +118,6 @@ impl DebugAdapterClient {
Ok(message) => message,
Err(e) => break Err(e.into()),
};
match message {
Message::Event(ev) => {
log::debug!("Client {} received event `{}`", client_id.0, &ev);
@ -164,7 +162,6 @@ impl DebugAdapterClient {
command: R::COMMAND.to_string(),
arguments: Some(serialized_arguments),
};
self.transport_delegate
.add_pending_request(sequence_id, callback_tx)
.await;
@ -434,7 +431,7 @@ mod tests {
let client = DebugAdapterClient::start(
crate::client::SessionId(1),
DebugAdapterName(Arc::from("test-adapter")),
DebugAdapterName("test-adapter".into()),
DebugAdapterBinary {
command: "command".into(),
arguments: Default::default(),

17
crates/dap/src/dap.rs Normal file
View file

@ -0,0 +1,17 @@
pub mod adapters;
pub mod client;
pub mod debugger_settings;
pub mod proto_conversions;
mod registry;
pub mod transport;
pub use dap_types::*;
pub use registry::DapRegistry;
pub use task::{DebugAdapterConfig, DebugRequestType};
pub type ScopeId = u64;
pub type VariableReference = u64;
pub type StackFrameId = u64;
#[cfg(any(test, feature = "test-support"))]
pub use adapters::FakeAdapter;

View file

@ -1,38 +0,0 @@
pub mod adapters;
pub mod client;
pub mod debugger_settings;
pub mod proto_conversions;
pub mod transport;
pub use dap_types::*;
pub use task::{DebugAdapterConfig, DebugAdapterKind, DebugRequestType};
pub type ScopeId = u64;
pub type VariableReference = u64;
pub type StackFrameId = u64;
#[cfg(any(test, feature = "test-support"))]
pub use adapters::FakeAdapter;
#[cfg(any(test, feature = "test-support"))]
pub fn test_config(
request: DebugRequestType,
fail: Option<bool>,
caps: Option<Capabilities>,
) -> DebugAdapterConfig {
DebugAdapterConfig {
label: "test config".into(),
kind: DebugAdapterKind::Fake((
fail.unwrap_or_default(),
caps.unwrap_or(Capabilities {
supports_step_back: Some(false),
..Default::default()
}),
)),
request,
program: None,
supports_attach: false,
cwd: None,
initialize_args: None,
}
}

View file

@ -0,0 +1,39 @@
use parking_lot::RwLock;
use crate::adapters::{DebugAdapter, DebugAdapterName};
use std::{collections::BTreeMap, sync::Arc};
#[derive(Default)]
struct DapRegistryState {
adapters: BTreeMap<DebugAdapterName, Arc<dyn DebugAdapter>>,
}
#[derive(Default)]
/// Stores available debug adapters.
pub struct DapRegistry(Arc<RwLock<DapRegistryState>>);
impl DapRegistry {
pub fn add_adapter(&self, adapter: Arc<dyn DebugAdapter>) {
let name = adapter.name();
let _previous_value = self.0.write().adapters.insert(name, adapter);
debug_assert!(
_previous_value.is_none(),
"Attempted to insert a new debug adapter when one is already registered"
);
}
pub fn adapter(&self, name: &str) -> Option<Arc<dyn DebugAdapter>> {
self.0.read().adapters.get(name).cloned()
}
pub fn enumerate_adapters(&self) -> Vec<DebugAdapterName> {
self.0.read().adapters.keys().cloned().collect()
}
#[cfg(any(test, feature = "test-support"))]
pub fn fake() -> Self {
use crate::FakeAdapter;
let register = Self::default();
register.add_adapter(Arc::new(FakeAdapter::new()));
register
}
}

View file

@ -261,8 +261,6 @@ impl TransportDelegate {
}
}
}
smol::future::yield_now().await;
};
log::debug!("Handle adapter log dropped");
@ -319,8 +317,6 @@ impl TransportDelegate {
}
Err(error) => break Err(error.into()),
}
smol::future::yield_now().await;
};
log::debug!("Handle adapter input dropped");
@ -360,8 +356,6 @@ impl TransportDelegate {
}
Err(e) => break Err(e),
}
smol::future::yield_now().await;
};
drop(client_tx);
@ -393,8 +387,6 @@ impl TransportDelegate {
}
Err(error) => break Err(error.into()),
}
smol::future::yield_now().await;
};
log::debug!("Handle adapter error dropped");