debugger: Add inline value tests (#29815)
## Context This PR improves the accuracy of our inline values for Rust/Python. It does this by only adding inline value hints to the last valid use of a variable and checking whether variables are valid within a given scope or not. We also added tests for Rust/Python inline values and inline values refreshing when stepping in a debug session. ### Future tasks 1. Handle functions that have inner functions defined within them. 2. Add inline values to variables that were used in inner scopes but not defined in them. 3. Move the inline value provider trait and impls to the language trait (or somewhere else). 4. Use Semantic tokens as the first inline value provider and fall back to tree sitter 5. add let some variable statement, for loops, and function inline value hints to Rust. 6. Make writing tests more streamlined. 6.1 We should be able to write a test by only passing in variables, language, source file, expected result, and stop position to a function. 7. Write a test that has coverage for selecting different stack frames. co-authored-by: Remco Smits \<djsmits12@gmail.com\> Release Notes: - N/A --------- Co-authored-by: Remco Smits <djsmits12@gmail.com>
This commit is contained in:
parent
7bc3f74cab
commit
1a520990cc
21 changed files with 2273 additions and 281 deletions
|
@ -27,7 +27,6 @@ dap.workspace = true
|
|||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
lsp-types.workspace = true
|
||||
paths.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::{collections::HashMap, path::PathBuf, sync::OnceLock};
|
|||
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
use dap::adapters::{DebugTaskDefinition, InlineValueProvider, latest_github_release};
|
||||
use dap::adapters::{DebugTaskDefinition, latest_github_release};
|
||||
use futures::StreamExt;
|
||||
use gpui::AsyncApp;
|
||||
use task::DebugRequest;
|
||||
|
@ -159,25 +159,4 @@ impl DebugAdapter for CodeLldbDebugAdapter {
|
|||
connection: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn inline_value_provider(&self) -> Option<Box<dyn InlineValueProvider>> {
|
||||
Some(Box::new(CodeLldbInlineValueProvider))
|
||||
}
|
||||
}
|
||||
|
||||
struct CodeLldbInlineValueProvider;
|
||||
|
||||
impl InlineValueProvider for CodeLldbInlineValueProvider {
|
||||
fn provide(&self, variables: Vec<(String, lsp_types::Range)>) -> Vec<lsp_types::InlineValue> {
|
||||
variables
|
||||
.into_iter()
|
||||
.map(|(variable, range)| {
|
||||
lsp_types::InlineValue::VariableLookup(lsp_types::InlineValueVariableLookup {
|
||||
range,
|
||||
variable_name: Some(variable),
|
||||
case_sensitive_lookup: true,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use dap::{
|
|||
self, AdapterVersion, DapDelegate, DebugAdapter, DebugAdapterBinary, DebugAdapterName,
|
||||
GithubRepo,
|
||||
},
|
||||
inline_value::{PythonInlineValueProvider, RustInlineValueProvider},
|
||||
};
|
||||
use gdb::GdbDebugAdapter;
|
||||
use go::GoDebugAdapter;
|
||||
|
@ -34,6 +35,10 @@ pub fn init(cx: &mut App) {
|
|||
registry.add_adapter(Arc::from(JsDebugAdapter::default()));
|
||||
registry.add_adapter(Arc::from(GoDebugAdapter));
|
||||
registry.add_adapter(Arc::from(GdbDebugAdapter));
|
||||
|
||||
registry.add_inline_value_provider("Rust".to_string(), Arc::from(RustInlineValueProvider));
|
||||
registry
|
||||
.add_inline_value_provider("Python".to_string(), Arc::from(PythonInlineValueProvider));
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use crate::*;
|
||||
use dap::{
|
||||
DebugRequest, StartDebuggingRequestArguments, adapters::DebugTaskDefinition,
|
||||
adapters::InlineValueProvider,
|
||||
};
|
||||
use dap::{DebugRequest, StartDebuggingRequestArguments, adapters::DebugTaskDefinition};
|
||||
use gpui::AsyncApp;
|
||||
use std::{collections::HashMap, ffi::OsStr, path::PathBuf, sync::OnceLock};
|
||||
use util::ResultExt;
|
||||
|
@ -182,34 +179,4 @@ impl DebugAdapter for PythonDebugAdapter {
|
|||
self.get_installed_binary(delegate, &config, user_installed_path, cx)
|
||||
.await
|
||||
}
|
||||
|
||||
fn inline_value_provider(&self) -> Option<Box<dyn InlineValueProvider>> {
|
||||
Some(Box::new(PythonInlineValueProvider))
|
||||
}
|
||||
}
|
||||
|
||||
struct PythonInlineValueProvider;
|
||||
|
||||
impl InlineValueProvider for PythonInlineValueProvider {
|
||||
fn provide(&self, variables: Vec<(String, lsp_types::Range)>) -> Vec<lsp_types::InlineValue> {
|
||||
variables
|
||||
.into_iter()
|
||||
.map(|(variable, range)| {
|
||||
if variable.contains(".") || variable.contains("[") {
|
||||
lsp_types::InlineValue::EvaluatableExpression(
|
||||
lsp_types::InlineValueEvaluatableExpression {
|
||||
range,
|
||||
expression: Some(variable),
|
||||
},
|
||||
)
|
||||
} else {
|
||||
lsp_types::InlineValue::VariableLookup(lsp_types::InlineValueVariableLookup {
|
||||
range,
|
||||
variable_name: Some(variable),
|
||||
case_sensitive_lookup: true,
|
||||
})
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue