From 0fa127b1051ad9af9371a1c9b424921e4f52d066 Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Thu, 12 Aug 2021 20:47:14 +0300 Subject: [PATCH] dap: support getting scopes and variables --- helix-dap/examples/dap-basic.rs | 14 +++- helix-dap/src/client.rs | 127 +++++++++++++++++++++++++++++--- 2 files changed, 127 insertions(+), 14 deletions(-) diff --git a/helix-dap/examples/dap-basic.rs b/helix-dap/examples/dap-basic.rs index cc05cd8e..9c4f2f3e 100644 --- a/helix-dap/examples/dap-basic.rs +++ b/helix-dap/examples/dap-basic.rs @@ -28,7 +28,7 @@ pub async fn main() -> Result<()> { .set_breakpoints( "/tmp/godebug/main.go".to_owned(), vec![SourceBreakpoint { - line: 6, + line: 8, column: Some(2), }] ) @@ -43,7 +43,17 @@ pub async fn main() -> Result<()> { println!("configurationDone: {:?}", client.configuration_done().await); println!("stopped: {:?}", client.wait_for_stopped().await); println!("threads: {:#?}", client.threads().await); - println!("stack trace: {:#?}", client.stack_trace(1).await); + let bt = client.stack_trace(1).await.expect("expected stack trace"); + println!("stack trace: {:#?}", bt); + let scopes = client + .scopes(bt.0[0].id) + .await + .expect("expected scopes for thread"); + println!("scopes: {:#?}", scopes); + println!( + "vars: {:#?}", + client.variables(scopes[1].variables_reference).await + ); let mut _in = String::new(); std::io::stdin() diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs index d76f9af3..b41d1d43 100644 --- a/helix-dap/src/client.rs +++ b/helix-dap/src/client.rs @@ -128,17 +128,17 @@ struct StackTraceArguments { #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct StackFrame { - id: usize, - name: String, - source: Option, - line: usize, - column: usize, - end_line: Option, - end_column: Option, - can_restart: Option, - instruction_pointer_reference: Option, + pub id: usize, + pub name: String, + pub source: Option, + pub line: usize, + pub column: usize, + pub end_line: Option, + pub end_column: Option, + pub can_restart: Option, + pub instruction_pointer_reference: Option, // module_id - presentation_hint: Option, + pub presentation_hint: Option, } #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] @@ -151,8 +151,8 @@ struct StackTraceResponseBody { #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Thread { - id: usize, - name: String, + pub id: usize, + pub name: String, } #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] @@ -161,6 +161,79 @@ struct ThreadsResponseBody { threads: Vec, } +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct ScopesArguments { + frame_id: usize, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Scope { + pub name: String, + pub presentation_hint: Option, + pub variables_reference: usize, + pub named_variables: Option, + pub indexed_variables: Option, + pub expensive: bool, + pub source: Option, + pub line: Option, + pub column: Option, + pub end_line: Option, + pub end_column: Option, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct ScopesResponseBody { + scopes: Vec, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct ValueFormat { + hex: Option, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct VariablesArguments { + variables_reference: usize, + filter: Option, + start: Option, + count: Option, + format: Option, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct VariablePresentationHint { + pub kind: Option, + pub attributes: Option>, + pub visibility: Option, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Variable { + pub name: String, + pub value: String, + #[serde(rename = "type")] + pub data_type: Option, + pub presentation_hint: Option, + pub evaluate_name: Option, + pub variables_reference: usize, + pub named_variables: Option, + pub indexed_variables: Option, + pub memory_reference: Option, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct VariablesResponseBody { + variables: Vec, +} + #[derive(Debug)] pub struct Client { id: usize, @@ -370,4 +443,34 @@ impl Client { Ok(body.threads) } + + pub async fn scopes(&mut self, frame_id: usize) -> Result> { + let args = ScopesArguments { frame_id }; + + let response = self + .request("scopes".to_owned(), to_value(args).ok()) + .await?; + + let body: ScopesResponseBody = from_value(response.body.unwrap()).unwrap(); + + Ok(body.scopes) + } + + pub async fn variables(&mut self, variables_reference: usize) -> Result> { + let args = VariablesArguments { + variables_reference, + filter: None, + start: None, + count: None, + format: None, + }; + + let response = self + .request("variables".to_owned(), to_value(args).ok()) + .await?; + + let body: VariablesResponseBody = from_value(response.body.unwrap()).unwrap(); + + Ok(body.variables) + } }