go.rs

 1use dap::{StartDebuggingRequestArguments, adapters::DebugTaskDefinition};
 2use gpui::{AsyncApp, SharedString};
 3use language::LanguageName;
 4use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
 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                "env": launch_config.env_json()
25            }),
26        };
27
28        let map = args.as_object_mut().unwrap();
29
30        if let Some(stop_on_entry) = config.stop_on_entry {
31            map.insert("stopOnEntry".into(), stop_on_entry.into());
32        }
33
34        StartDebuggingRequestArguments {
35            configuration: args,
36            request: config.request.to_dap(),
37        }
38    }
39}
40
41#[async_trait(?Send)]
42impl DebugAdapter for GoDebugAdapter {
43    fn name(&self) -> DebugAdapterName {
44        DebugAdapterName(Self::ADAPTER_NAME.into())
45    }
46
47    fn adapter_language_name(&self) -> Option<LanguageName> {
48        Some(SharedString::new_static("Go").into())
49    }
50
51    async fn get_binary(
52        &self,
53        delegate: &Arc<dyn DapDelegate>,
54        config: &DebugTaskDefinition,
55        _user_installed_path: Option<PathBuf>,
56        _cx: &mut AsyncApp,
57    ) -> Result<DebugAdapterBinary> {
58        let delve_path = delegate
59            .which(OsStr::new("dlv"))
60            .await
61            .and_then(|p| p.to_str().map(|p| p.to_string()))
62            .ok_or(anyhow!("Dlv not found in path"))?;
63
64        let tcp_connection = config.tcp_connection.clone().unwrap_or_default();
65        let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
66
67        Ok(DebugAdapterBinary {
68            command: delve_path,
69            arguments: vec![
70                "dap".into(),
71                "--listen".into(),
72                format!("{}:{}", host, port),
73            ],
74            cwd: None,
75            envs: HashMap::default(),
76            connection: Some(adapters::TcpArguments {
77                host,
78                port,
79                timeout,
80            }),
81            request_args: self.request_args(config),
82        })
83    }
84}