lldb.rs

  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}