go.rs

  1use dap::{StartDebuggingRequestArguments, adapters::DebugTaskDefinition};
  2use gpui::AsyncApp;
  3use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
  4
  5use crate::*;
  6
  7#[derive(Default, Debug)]
  8pub(crate) struct GoDebugAdapter;
  9
 10impl GoDebugAdapter {
 11    const ADAPTER_NAME: &'static str = "Delve";
 12    fn request_args(&self, config: &DebugTaskDefinition) -> StartDebuggingRequestArguments {
 13        let mut args = match &config.request {
 14            dap::DebugRequest::Attach(attach_config) => {
 15                json!({
 16                    "processId": attach_config.process_id,
 17                })
 18            }
 19            dap::DebugRequest::Launch(launch_config) => json!({
 20                "program": launch_config.program,
 21                "cwd": launch_config.cwd,
 22                "args": launch_config.args
 23            }),
 24        };
 25
 26        let map = args.as_object_mut().unwrap();
 27
 28        if let Some(stop_on_entry) = config.stop_on_entry {
 29            map.insert("stopOnEntry".into(), stop_on_entry.into());
 30        }
 31
 32        StartDebuggingRequestArguments {
 33            configuration: args,
 34            request: config.request.to_dap(),
 35        }
 36    }
 37}
 38
 39#[async_trait(?Send)]
 40impl DebugAdapter for GoDebugAdapter {
 41    fn name(&self) -> DebugAdapterName {
 42        DebugAdapterName(Self::ADAPTER_NAME.into())
 43    }
 44
 45    async fn get_binary(
 46        &self,
 47        delegate: &dyn DapDelegate,
 48        config: &DebugTaskDefinition,
 49        user_installed_path: Option<PathBuf>,
 50        cx: &mut AsyncApp,
 51    ) -> Result<DebugAdapterBinary> {
 52        self.get_installed_binary(delegate, config, user_installed_path, cx)
 53            .await
 54    }
 55
 56    async fn fetch_latest_adapter_version(
 57        &self,
 58        _delegate: &dyn DapDelegate,
 59    ) -> Result<AdapterVersion> {
 60        unimplemented!("This adapter is used from path for now");
 61    }
 62
 63    async fn install_binary(
 64        &self,
 65        version: AdapterVersion,
 66        delegate: &dyn DapDelegate,
 67    ) -> Result<()> {
 68        adapters::download_adapter_from_github(
 69            self.name(),
 70            version,
 71            adapters::DownloadedFileType::Zip,
 72            delegate,
 73        )
 74        .await?;
 75        Ok(())
 76    }
 77
 78    async fn get_installed_binary(
 79        &self,
 80        delegate: &dyn DapDelegate,
 81        config: &DebugTaskDefinition,
 82        _: Option<PathBuf>,
 83        _: &mut AsyncApp,
 84    ) -> Result<DebugAdapterBinary> {
 85        let delve_path = delegate
 86            .which(OsStr::new("dlv"))
 87            .and_then(|p| p.to_str().map(|p| p.to_string()))
 88            .ok_or(anyhow!("Dlv not found in path"))?;
 89
 90        let tcp_connection = config.tcp_connection.clone().unwrap_or_default();
 91        let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
 92
 93        Ok(DebugAdapterBinary {
 94            command: delve_path,
 95            arguments: vec![
 96                "dap".into(),
 97                "--listen".into(),
 98                format!("{}:{}", host, port),
 99            ],
100            cwd: None,
101            envs: HashMap::default(),
102            connection: Some(adapters::TcpArguments {
103                host,
104                port,
105                timeout,
106            }),
107            request_args: self.request_args(config),
108        })
109    }
110}