go.rs

 1use anyhow::Context as _;
 2use dap::{StartDebuggingRequestArguments, adapters::DebugTaskDefinition};
 3use gpui::{AsyncApp, SharedString};
 4use language::LanguageName;
 5use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
 6
 7use crate::*;
 8
 9#[derive(Default, Debug)]
10pub(crate) struct GoDebugAdapter;
11
12impl GoDebugAdapter {
13    const ADAPTER_NAME: &'static str = "Delve";
14    fn request_args(&self, config: &DebugTaskDefinition) -> StartDebuggingRequestArguments {
15        let mut args = match &config.request {
16            dap::DebugRequest::Attach(attach_config) => {
17                json!({
18                    "processId": attach_config.process_id,
19                })
20            }
21            dap::DebugRequest::Launch(launch_config) => json!({
22                "program": launch_config.program,
23                "cwd": launch_config.cwd,
24                "args": launch_config.args,
25                "env": launch_config.env_json()
26            }),
27        };
28
29        let map = args.as_object_mut().unwrap();
30
31        if let Some(stop_on_entry) = config.stop_on_entry {
32            map.insert("stopOnEntry".into(), stop_on_entry.into());
33        }
34
35        StartDebuggingRequestArguments {
36            configuration: args,
37            request: config.request.to_dap(),
38        }
39    }
40}
41
42#[async_trait(?Send)]
43impl DebugAdapter for GoDebugAdapter {
44    fn name(&self) -> DebugAdapterName {
45        DebugAdapterName(Self::ADAPTER_NAME.into())
46    }
47
48    fn adapter_language_name(&self) -> Option<LanguageName> {
49        Some(SharedString::new_static("Go").into())
50    }
51
52    async fn get_binary(
53        &self,
54        delegate: &Arc<dyn DapDelegate>,
55        config: &DebugTaskDefinition,
56        _user_installed_path: Option<PathBuf>,
57        _cx: &mut AsyncApp,
58    ) -> Result<DebugAdapterBinary> {
59        let delve_path = delegate
60            .which(OsStr::new("dlv"))
61            .await
62            .and_then(|p| p.to_str().map(|p| p.to_string()))
63            .context("Dlv not found in path")?;
64
65        let tcp_connection = config.tcp_connection.clone().unwrap_or_default();
66        let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
67
68        Ok(DebugAdapterBinary {
69            command: delve_path,
70            arguments: vec!["dap".into(), "--listen".into(), format!("{host}:{port}")],
71            cwd: None,
72            envs: HashMap::default(),
73            connection: Some(adapters::TcpArguments {
74                host,
75                port,
76                timeout,
77            }),
78            request_args: self.request_args(config),
79        })
80    }
81}