1use std::{ffi::OsStr, path::PathBuf};
2
3use anyhow::Result;
4use async_trait::async_trait;
5use gpui::AsyncApp;
6use task::{DebugRequestType, DebugTaskDefinition};
7
8use crate::*;
9
10#[derive(Default)]
11pub(crate) struct LldbDebugAdapter;
12
13impl LldbDebugAdapter {
14 const ADAPTER_NAME: &'static str = "LLDB";
15
16 fn request_args(&self, config: &DebugTaskDefinition) -> dap::StartDebuggingRequestArguments {
17 let request = config.request.to_dap();
18 let mut args = json!({
19 "request": match config.request {
20 DebugRequestType::Launch(_) => "launch",
21 DebugRequestType::Attach(_) => "attach",
22 },
23 });
24 let map = args.as_object_mut().unwrap();
25 match &config.request {
26 DebugRequestType::Attach(attach) => {
27 map.insert("pid".into(), attach.process_id.into());
28 }
29 DebugRequestType::Launch(launch) => {
30 map.insert("program".into(), launch.program.clone().into());
31
32 if !launch.args.is_empty() {
33 map.insert("args".into(), launch.args.clone().into());
34 }
35
36 if let Some(stop_on_entry) = config.stop_on_entry {
37 map.insert("stopOnEntry".into(), stop_on_entry.into());
38 }
39 if let Some(cwd) = launch.cwd.as_ref() {
40 map.insert("cwd".into(), cwd.to_string_lossy().into_owned().into());
41 }
42 }
43 }
44 dap::StartDebuggingRequestArguments {
45 request,
46 configuration: args,
47 }
48 }
49}
50
51#[async_trait(?Send)]
52impl DebugAdapter for LldbDebugAdapter {
53 fn name(&self) -> DebugAdapterName {
54 DebugAdapterName(Self::ADAPTER_NAME.into())
55 }
56
57 async fn get_binary(
58 &self,
59 delegate: &dyn DapDelegate,
60 config: &DebugTaskDefinition,
61 user_installed_path: Option<PathBuf>,
62 _: &mut AsyncApp,
63 ) -> Result<DebugAdapterBinary> {
64 let lldb_dap_path = if let Some(user_installed_path) = user_installed_path {
65 user_installed_path.to_string_lossy().into()
66 } else {
67 delegate
68 .which(OsStr::new("lldb-dap"))
69 .and_then(|p| p.to_str().map(|s| s.to_string()))
70 .ok_or(anyhow!("Could not find lldb-dap in path"))?
71 };
72
73 Ok(DebugAdapterBinary {
74 adapter_name: Self::ADAPTER_NAME.into(),
75 command: lldb_dap_path,
76 arguments: None,
77 envs: None,
78 cwd: None,
79 connection: None,
80 request_args: self.request_args(config),
81 })
82 }
83
84 async fn install_binary(
85 &self,
86 _version: AdapterVersion,
87 _delegate: &dyn DapDelegate,
88 ) -> Result<()> {
89 unimplemented!("LLDB debug adapter cannot be installed by Zed (yet)")
90 }
91
92 async fn fetch_latest_adapter_version(&self, _: &dyn DapDelegate) -> Result<AdapterVersion> {
93 unimplemented!("Fetch latest adapter version not implemented for lldb (yet)")
94 }
95
96 async fn get_installed_binary(
97 &self,
98 _: &dyn DapDelegate,
99 _: &DebugTaskDefinition,
100 _: Option<PathBuf>,
101 _: &mut AsyncApp,
102 ) -> Result<DebugAdapterBinary> {
103 unimplemented!("LLDB debug adapter cannot be installed by Zed (yet)")
104 }
105}