aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Sharshakov2021-08-12 17:47:14 +0000
committerBlaž Hrastnik2021-08-20 04:43:54 +0000
commit0fa127b1051ad9af9371a1c9b424921e4f52d066 (patch)
treed5d3d0059d77c2cafd0a0edc059321a4065fc38e
parent7d2d4ed4a86f28bfce8d2fda8a774701d80f5175 (diff)
dap: support getting scopes and variables
-rw-r--r--helix-dap/examples/dap-basic.rs14
-rw-r--r--helix-dap/src/client.rs127
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)
+ }
}