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:
parent
56eb650f09
commit
4839195003
53 changed files with 1315 additions and 924 deletions
|
@ -1,6 +1,6 @@
|
|||
use dap_types::StartDebuggingRequestArguments;
|
||||
use schemars::{gen::SchemaSettings, JsonSchema};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::path::PathBuf;
|
||||
use util::ResultExt;
|
||||
|
@ -45,97 +45,121 @@ pub struct AttachConfig {
|
|||
pub process_id: Option<u32>,
|
||||
}
|
||||
|
||||
/// Represents the launch request information of the debug adapter
|
||||
#[derive(Deserialize, Serialize, Default, PartialEq, Eq, JsonSchema, Clone, Debug)]
|
||||
pub struct LaunchConfig {
|
||||
/// The program that you trying to debug
|
||||
pub program: String,
|
||||
/// The current working directory of your project
|
||||
pub cwd: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Represents the type that will determine which request to call on the debug adapter
|
||||
#[derive(Default, Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase", untagged)]
|
||||
pub enum DebugRequestType {
|
||||
/// Call the `launch` request on the debug adapter
|
||||
#[default]
|
||||
Launch,
|
||||
Launch(LaunchConfig),
|
||||
/// Call the `attach` request on the debug adapter
|
||||
Attach(AttachConfig),
|
||||
}
|
||||
|
||||
/// The Debug adapter to use
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase", tag = "adapter")]
|
||||
pub enum DebugAdapterKind {
|
||||
/// Manually setup starting a debug adapter
|
||||
/// The argument within is used to start the DAP
|
||||
Custom(CustomArgs),
|
||||
/// Use debugpy
|
||||
Python(TCPHost),
|
||||
/// Use vscode-php-debug
|
||||
Php(TCPHost),
|
||||
/// Use vscode-js-debug
|
||||
Javascript(TCPHost),
|
||||
/// Use delve
|
||||
Go(TCPHost),
|
||||
/// Use lldb
|
||||
Lldb,
|
||||
/// Use GDB's built-in DAP support
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
Gdb,
|
||||
/// Used for integration tests
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
#[serde(skip)]
|
||||
Fake((bool, dap_types::Capabilities)),
|
||||
/// Represents a request for starting the debugger.
|
||||
/// Contrary to `DebugRequestType`, `DebugRequestDisposition` is not Serializable.
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub enum DebugRequestDisposition {
|
||||
/// Debug session configured by the user.
|
||||
UserConfigured(DebugRequestType),
|
||||
/// Debug session configured by the debug adapter
|
||||
ReverseRequest(StartDebuggingRequestArguments),
|
||||
}
|
||||
|
||||
impl DebugAdapterKind {
|
||||
/// Returns the display name for the adapter kind
|
||||
pub fn display_name(&self) -> &str {
|
||||
impl DebugRequestDisposition {
|
||||
/// Get the current working directory from request if it's a launch request and exits
|
||||
pub fn cwd(&self) -> Option<PathBuf> {
|
||||
match self {
|
||||
Self::Custom(_) => "Custom",
|
||||
Self::Python(_) => "Python",
|
||||
Self::Php(_) => "PHP",
|
||||
Self::Javascript(_) => "JavaScript",
|
||||
Self::Lldb => "LLDB",
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
Self::Gdb => "GDB",
|
||||
Self::Go(_) => "Go",
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
Self::Fake(_) => "Fake",
|
||||
Self::UserConfigured(DebugRequestType::Launch(launch_config)) => {
|
||||
launch_config.cwd.clone()
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom arguments used to setup a custom debugger
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
|
||||
pub struct CustomArgs {
|
||||
/// The connection that a custom debugger should use
|
||||
#[serde(flatten)]
|
||||
pub connection: DebugConnectionType,
|
||||
/// The cli command used to start the debug adapter e.g. `python3`, `node` or the adapter binary
|
||||
pub command: String,
|
||||
/// The cli arguments used to start the debug adapter
|
||||
pub args: Option<Vec<String>>,
|
||||
/// The cli envs used to start the debug adapter
|
||||
pub envs: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
/// Represents the configuration for the debug adapter
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct DebugAdapterConfig {
|
||||
/// Name of the debug task
|
||||
pub label: String,
|
||||
/// The type of adapter you want to use
|
||||
#[serde(flatten)]
|
||||
pub kind: DebugAdapterKind,
|
||||
pub adapter: String,
|
||||
/// The type of request that should be called on the debug adapter
|
||||
#[serde(default)]
|
||||
pub request: DebugRequestType,
|
||||
/// The program that you trying to debug
|
||||
pub program: Option<String>,
|
||||
/// The current working directory of your project
|
||||
pub cwd: Option<PathBuf>,
|
||||
pub request: DebugRequestDisposition,
|
||||
/// Additional initialization arguments to be sent on DAP initialization
|
||||
pub initialize_args: Option<serde_json::Value>,
|
||||
/// Whether the debug adapter supports attaching to a running process.
|
||||
pub supports_attach: bool,
|
||||
/// Optional TCP connection information
|
||||
///
|
||||
/// If provided, this will be used to connect to the debug adapter instead of
|
||||
/// spawning a new process. This is useful for connecting to a debug adapter
|
||||
/// that is already running or is started by another process.
|
||||
pub tcp_connection: Option<TCPHost>,
|
||||
}
|
||||
|
||||
impl From<DebugTaskDefinition> for DebugAdapterConfig {
|
||||
fn from(def: DebugTaskDefinition) -> Self {
|
||||
Self {
|
||||
label: def.label,
|
||||
adapter: def.adapter,
|
||||
request: DebugRequestDisposition::UserConfigured(def.request),
|
||||
initialize_args: def.initialize_args,
|
||||
tcp_connection: def.tcp_connection,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<DebugAdapterConfig> for DebugTaskDefinition {
|
||||
type Error = ();
|
||||
fn try_from(def: DebugAdapterConfig) -> Result<Self, Self::Error> {
|
||||
let request = match def.request {
|
||||
DebugRequestDisposition::UserConfigured(debug_request_type) => debug_request_type,
|
||||
DebugRequestDisposition::ReverseRequest(_) => return Err(()),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
label: def.label,
|
||||
adapter: def.adapter,
|
||||
request,
|
||||
initialize_args: def.initialize_args,
|
||||
tcp_connection: def.tcp_connection,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugTaskDefinition {
|
||||
/// Translate from debug definition to a task template
|
||||
pub fn to_zed_format(self) -> anyhow::Result<TaskTemplate> {
|
||||
let command = "".to_string();
|
||||
|
||||
let cwd = if let DebugRequestType::Launch(ref launch) = self.request {
|
||||
launch
|
||||
.cwd
|
||||
.as_ref()
|
||||
.map(|path| path.to_string_lossy().into_owned())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let label = self.label.clone();
|
||||
let task_type = TaskType::Debug(self);
|
||||
|
||||
Ok(TaskTemplate {
|
||||
label,
|
||||
command,
|
||||
args: vec![],
|
||||
task_type,
|
||||
cwd,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
/// Represents the type of the debugger adapter connection
|
||||
#[derive(Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase", tag = "connection")]
|
||||
|
@ -151,48 +175,20 @@ pub enum DebugConnectionType {
|
|||
#[serde(rename_all = "snake_case")]
|
||||
pub struct DebugTaskDefinition {
|
||||
/// The adapter to run
|
||||
#[serde(flatten)]
|
||||
kind: DebugAdapterKind,
|
||||
pub adapter: String,
|
||||
/// The type of request that should be called on the debug adapter
|
||||
#[serde(default)]
|
||||
request: DebugRequestType,
|
||||
#[serde(flatten)]
|
||||
pub request: DebugRequestType,
|
||||
/// Name of the debug task
|
||||
label: String,
|
||||
/// Program to run the debugger on
|
||||
program: Option<String>,
|
||||
/// The current working directory of your project
|
||||
cwd: Option<String>,
|
||||
pub label: String,
|
||||
/// Additional initialization arguments to be sent on DAP initialization
|
||||
initialize_args: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
impl DebugTaskDefinition {
|
||||
/// Translate from debug definition to a task template
|
||||
pub fn to_zed_format(self) -> anyhow::Result<TaskTemplate> {
|
||||
let command = "".to_string();
|
||||
let cwd = self.cwd.clone().map(PathBuf::from).take_if(|p| p.exists());
|
||||
|
||||
let task_type = TaskType::Debug(DebugAdapterConfig {
|
||||
label: self.label.clone(),
|
||||
kind: self.kind,
|
||||
request: self.request,
|
||||
program: self.program,
|
||||
cwd: cwd.clone(),
|
||||
initialize_args: self.initialize_args,
|
||||
supports_attach: true,
|
||||
});
|
||||
|
||||
let args: Vec<String> = Vec::new();
|
||||
|
||||
Ok(TaskTemplate {
|
||||
label: self.label,
|
||||
command,
|
||||
args,
|
||||
task_type,
|
||||
cwd: self.cwd,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
pub initialize_args: Option<serde_json::Value>,
|
||||
/// Optional TCP connection information
|
||||
///
|
||||
/// If provided, this will be used to connect to the debug adapter instead of
|
||||
/// spawning a new process. This is useful for connecting to a debug adapter
|
||||
/// that is already running or is started by another process.
|
||||
pub tcp_connection: Option<TCPHost>,
|
||||
}
|
||||
|
||||
/// A group of Debug Tasks defined in a JSON file.
|
||||
|
|
|
@ -15,8 +15,8 @@ use std::path::PathBuf;
|
|||
use std::str::FromStr;
|
||||
|
||||
pub use debug_format::{
|
||||
AttachConfig, CustomArgs, DebugAdapterConfig, DebugAdapterKind, DebugConnectionType,
|
||||
DebugRequestType, DebugTaskDefinition, DebugTaskFile, TCPHost,
|
||||
AttachConfig, DebugAdapterConfig, DebugConnectionType, DebugRequestDisposition,
|
||||
DebugRequestType, DebugTaskDefinition, DebugTaskFile, LaunchConfig, TCPHost,
|
||||
};
|
||||
pub use task_template::{
|
||||
HideStrategy, RevealStrategy, TaskModal, TaskTemplate, TaskTemplates, TaskType,
|
||||
|
@ -104,14 +104,20 @@ impl ResolvedTask {
|
|||
}
|
||||
|
||||
/// Get the configuration for the debug adapter that should be used for this task.
|
||||
pub fn resolved_debug_adapter_config(&self) -> Option<DebugAdapterConfig> {
|
||||
pub fn resolved_debug_adapter_config(&self) -> Option<DebugTaskDefinition> {
|
||||
match self.original_task.task_type.clone() {
|
||||
TaskType::Script => None,
|
||||
TaskType::Debug(mut adapter_config) => {
|
||||
if let Some(resolved) = &self.resolved {
|
||||
adapter_config.label = resolved.label.clone();
|
||||
adapter_config.program = resolved.program.clone().or(adapter_config.program);
|
||||
adapter_config.cwd = resolved.cwd.clone().or(adapter_config.cwd);
|
||||
if let DebugRequestType::Launch(ref mut launch) = adapter_config.request {
|
||||
if let Some(program) = resolved.program.clone() {
|
||||
launch.program = program;
|
||||
}
|
||||
if let Some(cwd) = resolved.cwd.clone() {
|
||||
launch.cwd = Some(cwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(adapter_config)
|
||||
|
|
|
@ -9,7 +9,7 @@ use sha2::{Digest, Sha256};
|
|||
use util::{truncate_and_remove_front, ResultExt};
|
||||
|
||||
use crate::{
|
||||
debug_format::DebugAdapterConfig, ResolvedTask, RevealTarget, Shell, SpawnInTerminal,
|
||||
DebugRequestType, DebugTaskDefinition, ResolvedTask, RevealTarget, Shell, SpawnInTerminal,
|
||||
TaskContext, TaskId, VariableName, ZED_VARIABLE_NAME_PREFIX,
|
||||
};
|
||||
|
||||
|
@ -78,18 +78,18 @@ pub struct TaskTemplate {
|
|||
/// Represents the type of task that is being ran
|
||||
#[derive(Default, Deserialize, Serialize, Eq, PartialEq, JsonSchema, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case", tag = "type")]
|
||||
#[expect(clippy::large_enum_variant)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum TaskType {
|
||||
/// Act like a typically task that runs commands
|
||||
#[default]
|
||||
Script,
|
||||
/// This task starts the debugger for a language
|
||||
Debug(DebugAdapterConfig),
|
||||
Debug(DebugTaskDefinition),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod deserialization_tests {
|
||||
use crate::{DebugAdapterKind, TCPHost};
|
||||
use crate::LaunchConfig;
|
||||
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
@ -105,19 +105,20 @@ mod deserialization_tests {
|
|||
|
||||
#[test]
|
||||
fn deserialize_task_type_debug() {
|
||||
let adapter_config = DebugAdapterConfig {
|
||||
let adapter_config = DebugTaskDefinition {
|
||||
label: "test config".into(),
|
||||
kind: DebugAdapterKind::Python(TCPHost::default()),
|
||||
request: crate::DebugRequestType::Launch,
|
||||
program: Some("main".to_string()),
|
||||
supports_attach: false,
|
||||
cwd: None,
|
||||
adapter: "Debugpy".into(),
|
||||
request: crate::DebugRequestType::Launch(LaunchConfig {
|
||||
program: "main".to_string(),
|
||||
cwd: None,
|
||||
}),
|
||||
initialize_args: None,
|
||||
tcp_connection: None,
|
||||
};
|
||||
let json = json!({
|
||||
"label": "test config",
|
||||
"type": "debug",
|
||||
"adapter": "python",
|
||||
"adapter": "Debugpy",
|
||||
"program": "main",
|
||||
"supports_attach": false,
|
||||
});
|
||||
|
@ -272,9 +273,9 @@ impl TaskTemplate {
|
|||
let program = match &self.task_type {
|
||||
TaskType::Script => None,
|
||||
TaskType::Debug(adapter_config) => {
|
||||
if let Some(program) = &adapter_config.program {
|
||||
if let DebugRequestType::Launch(ref launch) = &adapter_config.request {
|
||||
Some(substitute_all_template_variables_in_str(
|
||||
program,
|
||||
&launch.program,
|
||||
&task_variables,
|
||||
&variable_names,
|
||||
&mut substituted_variables,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue