From 41b702807dd2829401aa57ca9cceff72260df345 Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Wed, 15 Jan 2025 14:13:01 +0100 Subject: [PATCH] Fix only allow autocompletion for variables that are from the current(first) stackframe So this changes the behavior for providing variables for autocompletion inside the debug console if the adapter does not support autocompletion. Before this change you would get variables based on the selected stack frame. But this is not correct, as you cannot use variables that are not in scope anymore. So changing it to only provide variables for the current(first) stack frame we should provide variables that could always be used for autocompletion and for expressions. --- crates/debugger_ui/src/console.rs | 4 +++- crates/debugger_ui/src/stack_frame_list.rs | 7 +++++++ crates/debugger_ui/src/tests/variable_list.rs | 2 +- crates/debugger_ui/src/variable_list.rs | 15 +++++++++++++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/crates/debugger_ui/src/console.rs b/crates/debugger_ui/src/console.rs index 456a94e51e..85cd80abf7 100644 --- a/crates/debugger_ui/src/console.rs +++ b/crates/debugger_ui/src/console.rs @@ -406,7 +406,9 @@ impl ConsoleQueryBarCompletionProvider { let mut variables = HashMap::new(); let mut string_matches = Vec::new(); - for variable in console.variable_list.update(cx, |v, cx| v.variables(cx)) { + for variable in console.variable_list.update(cx, |variable_list, cx| { + variable_list.completion_variables(cx) + }) { if let Some(evaluate_name) = &variable.variable.evaluate_name { variables.insert(evaluate_name.clone(), variable.variable.value.clone()); string_matches.push(StringMatchCandidate { diff --git a/crates/debugger_ui/src/stack_frame_list.rs b/crates/debugger_ui/src/stack_frame_list.rs index 8e53b73fc4..75d6babf45 100644 --- a/crates/debugger_ui/src/stack_frame_list.rs +++ b/crates/debugger_ui/src/stack_frame_list.rs @@ -109,6 +109,13 @@ impl StackFrameList { &self.stack_frames } + pub fn first_stack_frame_id(&self) -> u64 { + self.stack_frames + .first() + .map(|stack_frame| stack_frame.id) + .unwrap_or(0) + } + pub fn current_stack_frame_id(&self) -> u64 { self.current_stack_frame_id } diff --git a/crates/debugger_ui/src/tests/variable_list.rs b/crates/debugger_ui/src/tests/variable_list.rs index 6c75bd76ea..25a866d607 100644 --- a/crates/debugger_ui/src/tests/variable_list.rs +++ b/crates/debugger_ui/src/tests/variable_list.rs @@ -216,7 +216,7 @@ async fn test_basic_fetch_initial_scope_and_variables( depth: 1, }, ], - variable_list.variables(cx) + variable_list.variables_by_stack_frame_id(1) ); variable_list.assert_visual_entries( diff --git a/crates/debugger_ui/src/variable_list.rs b/crates/debugger_ui/src/variable_list.rs index 4f69894262..7746004e85 100644 --- a/crates/debugger_ui/src/variable_list.rs +++ b/crates/debugger_ui/src/variable_list.rs @@ -591,8 +591,19 @@ impl VariableList { self.variables.get(&(stack_frame_id, scope_id)) } - pub fn variables(&self, cx: &mut ViewContext) -> Vec { - let stack_frame_id = self.stack_frame_list.read(cx).current_stack_frame_id(); + #[cfg(any(test, feature = "test-support"))] + pub fn variables_by_stack_frame_id( + &self, + stack_frame_id: StackFrameId, + ) -> Vec { + self.variables + .range((stack_frame_id, u64::MIN)..(stack_frame_id, u64::MAX)) + .flat_map(|(_, containers)| containers.variables.iter().cloned()) + .collect() + } + + pub fn completion_variables(&self, cx: &mut ViewContext) -> Vec { + let stack_frame_id = self.stack_frame_list.read(cx).first_stack_frame_id(); self.variables .range((stack_frame_id, u64::MIN)..(stack_frame_id, u64::MAX))