diff options
author | Dmitry Sharshakov | 2021-08-12 17:47:14 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2021-08-20 04:43:54 +0000 |
commit | 0fa127b1051ad9af9371a1c9b424921e4f52d066 (patch) | |
tree | d5d3d0059d77c2cafd0a0edc059321a4065fc38e | |
parent | 7d2d4ed4a86f28bfce8d2fda8a774701d80f5175 (diff) |
dap: support getting scopes and variables
-rw-r--r-- | helix-dap/examples/dap-basic.rs | 14 | ||||
-rw-r--r-- | 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<Source>, - line: usize, - column: usize, - end_line: Option<usize>, - end_column: Option<usize>, - can_restart: Option<bool>, - instruction_pointer_reference: Option<String>, + pub id: usize, + pub name: String, + pub source: Option<Source>, + pub line: usize, + pub column: usize, + pub end_line: Option<usize>, + pub end_column: Option<usize>, + pub can_restart: Option<bool>, + pub instruction_pointer_reference: Option<String>, // module_id - presentation_hint: Option<String>, + pub presentation_hint: Option<String>, } #[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<Thread>, } +#[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<String>, + pub variables_reference: usize, + pub named_variables: Option<usize>, + pub indexed_variables: Option<usize>, + pub expensive: bool, + pub source: Option<Source>, + pub line: Option<usize>, + pub column: Option<usize>, + pub end_line: Option<usize>, + pub end_column: Option<usize>, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct ScopesResponseBody { + scopes: Vec<Scope>, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct ValueFormat { + hex: Option<bool>, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct VariablesArguments { + variables_reference: usize, + filter: Option<String>, + start: Option<usize>, + count: Option<usize>, + format: Option<ValueFormat>, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct VariablePresentationHint { + pub kind: Option<String>, + pub attributes: Option<Vec<String>>, + pub visibility: Option<String>, +} + +#[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<String>, + pub presentation_hint: Option<VariablePresentationHint>, + pub evaluate_name: Option<String>, + pub variables_reference: usize, + pub named_variables: Option<usize>, + pub indexed_variables: Option<usize>, + pub memory_reference: Option<String>, +} + +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct VariablesResponseBody { + variables: Vec<Variable>, +} + #[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<Vec<Scope>> { + 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<Vec<Variable>> { + 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) + } } |