go.rs

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