From 05b475ab9d661e02b9a9bffedd3653b3bd3662d5 Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Sun, 11 Aug 2024 13:18:35 +0200 Subject: [PATCH] Refactor how we store thread data We now store the information in a better way so we could filter on it easier and faster. --- Cargo.lock | 2 +- crates/dap/src/client.rs | 14 +--- crates/debugger_ui/src/debugger_panel.rs | 84 +++++++++---------- crates/debugger_ui/src/debugger_panel_item.rs | 55 +++++++++--- 4 files changed, 85 insertions(+), 70 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1113e3c69a19..e3c3a03b5af91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3242,7 +3242,7 @@ dependencies = [ [[package]] name = "dap-types" version = "0.0.1" -source = "git+https://github.com/zed-industries/dap-types#e715437f1193d5da6d7de6a71abdd1ac1fbf4c9d" +source = "git+https://github.com/zed-industries/dap-types#04f7b33db5f825cd874b5be73919609f4c5d8169" dependencies = [ "serde", "serde_json", diff --git a/crates/dap/src/client.rs b/crates/dap/src/client.rs index 9606a1ad19f91..ea3425421626e 100644 --- a/crates/dap/src/client.rs +++ b/crates/dap/src/client.rs @@ -25,7 +25,7 @@ use smol::{ process::{self, Child}, }; use std::{ - collections::HashMap, + collections::{BTreeMap, HashMap}, net::{Ipv4Addr, SocketAddrV4}, path::PathBuf, process::Stdio, @@ -38,16 +38,6 @@ use std::{ use task::{DebugAdapterConfig, DebugConnectionType, DebugRequestType, TCPHost}; use text::Point; -#[derive(Debug, Clone)] -pub enum ThreadEntry { - Scope(Scope), - Variable { - depth: usize, - variable: Variable, - has_children: bool, - }, -} - #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum ThreadStatus { #[default] @@ -65,7 +55,7 @@ pub struct DebugAdapterClientId(pub usize); pub struct ThreadState { pub status: ThreadStatus, pub stack_frames: Vec, - pub stack_frame_entries: HashMap>, // stack_frame_id -> ThreadEntry(scope & variables) + pub variables: BTreeMap>>, pub current_stack_frame_id: u64, } diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 5db8836f45738..12d1c70d0b061 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -3,11 +3,11 @@ use anyhow::Result; use dap::client::{DebugAdapterClientId, ThreadState, ThreadStatus}; use dap::requests::{Disconnect, Request, Scopes, StackTrace, StartDebugging, Variables}; use dap::transport::Payload; -use dap::{client::DebugAdapterClient, client::ThreadEntry, transport::Events}; +use dap::{client::DebugAdapterClient, transport::Events}; use dap::{ Capabilities, ContinuedEvent, DisconnectArguments, ExitedEvent, OutputEvent, ScopesArguments, StackFrame, StackTraceArguments, StartDebuggingRequestArguments, StoppedEvent, TerminatedEvent, - ThreadEvent, ThreadEventReason, VariablesArguments, + ThreadEvent, ThreadEventReason, Variable, VariablesArguments, }; use editor::Editor; use futures::future::try_join_all; @@ -16,8 +16,9 @@ use gpui::{ Subscription, Task, View, ViewContext, WeakView, }; use serde_json::json; +use std::collections::BTreeMap; use std::path::Path; -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; use task::DebugRequestType; use ui::prelude::*; use util::{merge_json_value_into, ResultExt}; @@ -393,7 +394,7 @@ impl DebugPanel { client: Arc, variables_reference: u64, depth: usize, - ) -> Result> { + ) -> Result> { let response = client .request::(VariablesArguments { variables_reference, @@ -408,35 +409,30 @@ impl DebugPanel { for variable in response.variables { let client = client.clone(); tasks.push(async move { - let mut entries = Vec::new(); - entries.push(ThreadEntry::Variable { - depth, - variable: variable.clone(), - has_children: variable.variables_reference > 0, - }); + let mut variables = vec![(depth, variable.clone())]; if variable.variables_reference > 0 { - let mut nested_entries = Box::pin(Self::fetch_variables( + let mut nested_variables = Box::pin(Self::fetch_variables( client, variable.variables_reference, depth + 1, )) .await?; - entries.append(&mut nested_entries); + variables.append(&mut nested_variables); } - anyhow::Ok(entries) + anyhow::Ok(variables) }); } - let mut entries = Vec::new(); + let mut variables = Vec::new(); for mut variable_entries in try_join_all(tasks).await? { - entries.append(&mut variable_entries); + variables.append(&mut variable_entries); } - anyhow::Ok(entries) + anyhow::Ok(variables) } fn handle_stopped_event( @@ -461,65 +457,65 @@ impl DebugPanel { }) .await?; + let mut thread_state = ThreadState::default(); + let current_stack_frame = stack_trace_response.stack_frames.first().unwrap().clone(); let mut scope_tasks = Vec::new(); for stack_frame in stack_trace_response.stack_frames.clone().into_iter() { - let frame_id = stack_frame.id; let client = client.clone(); scope_tasks.push(async move { anyhow::Ok(( - frame_id, + stack_frame.clone(), client - .request::(ScopesArguments { frame_id }) + .request::(ScopesArguments { + frame_id: stack_frame.id, + }) .await?, )) }); } - let mut stack_frame_entries: HashMap> = HashMap::new(); - - let mut tasks = Vec::new(); - - for (stack_frame_id, response) in try_join_all(scope_tasks).await? { + let mut stack_frame_tasks = Vec::new(); + for (stack_frame, response) in try_join_all(scope_tasks).await? { let client = client.clone(); - tasks.push(async move { - let mut entries = Vec::new(); + stack_frame_tasks.push(async move { + let mut variable_tasks = Vec::new(); for scope in response.scopes { let scope_reference = scope.variables_reference; - entries.push(ThreadEntry::Scope(scope)); - - entries.append( - &mut Self::fetch_variables(client.clone(), scope_reference, 1) - .await?, - ); + let client = client.clone(); + variable_tasks.push(async move { + anyhow::Ok(( + scope, + Self::fetch_variables(client, scope_reference, 1).await?, + )) + }); } - anyhow::Ok((stack_frame_id, entries)) + anyhow::Ok((stack_frame, try_join_all(variable_tasks).await?)) }); } - for (stack_frame_id, mut scope_entries) in try_join_all(tasks).await? { - let entries = stack_frame_entries - .entry(stack_frame_id) - .or_insert(Vec::default()); + for (stack_frame, scopes) in try_join_all(stack_frame_tasks).await? { + let stack_frame_state = thread_state + .variables + .entry(stack_frame) + .or_insert_with(BTreeMap::default); - entries.append(&mut scope_entries); + for (scope, variables) in scopes { + stack_frame_state.insert(scope, variables); + } } this.update(&mut cx, |this, cx| { - let mut thread_state = client.thread_states(); - let thread_state = thread_state - .entry(thread_id) - .or_insert(ThreadState::default()); - thread_state.current_stack_frame_id = current_stack_frame.clone().id; thread_state.stack_frames = stack_trace_response.stack_frames; - thread_state.stack_frame_entries = stack_frame_entries; thread_state.status = ThreadStatus::Stopped; + client.thread_states().insert(thread_id, thread_state); + let existing_item = this .pane .read(cx) diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index c3a2e2ec4ccd1..3d867fd8ca52d 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -1,8 +1,6 @@ use crate::debugger_panel::{DebugPanel, DebugPanelEvent}; use anyhow::Result; -use dap::client::{ - DebugAdapterClient, DebugAdapterClientId, ThreadEntry, ThreadState, ThreadStatus, -}; +use dap::client::{DebugAdapterClient, DebugAdapterClientId, ThreadState, ThreadStatus}; use dap::{ OutputEvent, OutputEventCategory, Scope, StackFrame, StoppedEvent, ThreadEvent, Variable, }; @@ -11,6 +9,7 @@ use gpui::{ actions, list, AnyElement, AppContext, AsyncWindowContext, EventEmitter, FocusHandle, FocusableView, ListState, Subscription, View, WeakView, }; +use std::collections::HashMap; use std::sync::Arc; use ui::{prelude::*, Tooltip}; use ui::{ListItem, WindowContext}; @@ -23,6 +22,16 @@ enum ThreadItem { Output, } +#[derive(Debug, Clone)] +pub enum ThreadEntry { + Scope(Scope), + Variable { + depth: usize, + variable: Variable, + has_children: bool, + }, +} + pub struct DebugPanelItem { thread_id: u64, variable_list: ListState, @@ -30,6 +39,7 @@ pub struct DebugPanelItem { stack_frame_list: ListState, output_editor: View, collapsed_variables: Vec, + stack_frame_entries: HashMap>, active_thread_item: ThreadItem, client: Arc, _subscriptions: Vec, @@ -109,6 +119,7 @@ impl DebugPanelItem { output_editor, _subscriptions, stack_frame_list, + stack_frame_entries: Default::default(), collapsed_variables: Default::default(), active_thread_item: ThreadItem::Variables, } @@ -135,9 +146,9 @@ impl DebugPanelItem { let thread_state = this.current_thread_state(); this.stack_frame_list.reset(thread_state.stack_frames.len()); - if let Some(stack_frame_id) = thread_state.stack_frames.first().map(|s| s.id) { - this.update_stack_frame_id(stack_frame_id); - this.build_variable_list_entries(stack_frame_id); + if let Some(stack_frame) = thread_state.stack_frames.first() { + this.update_stack_frame_id(stack_frame.id); + this.build_variable_list_entries(stack_frame); }; cx.notify(); @@ -265,10 +276,9 @@ impl DebugPanelItem { ix: usize, cx: &mut ViewContext, ) -> AnyElement { - let thread_state = self.current_thread_state(); - let Some(entries) = thread_state + let Some(entries) = self .stack_frame_entries - .get(&thread_state.current_stack_frame_id) + .get(&self.current_thread_state().current_stack_frame_id) else { return div().into_any_element(); }; @@ -425,13 +435,31 @@ impl DebugPanelItem { .into_any() } - pub fn build_variable_list_entries(&mut self, stack_frame_id: u64) { + pub fn build_variable_list_entries(&mut self, stack_frame: &StackFrame) { let thread_state = self.current_thread_state(); - let Some(entries) = thread_state.stack_frame_entries.get(&stack_frame_id) else { + + let Some(scopes_and_vars) = thread_state.variables.get(stack_frame) else { return; }; - self.variable_list.reset(entries.len()); + let mut entries: Vec = Vec::default(); + + for (scope, variables) in scopes_and_vars { + entries.push(ThreadEntry::Scope(scope.clone())); + + for (depth, variable) in variables { + entries.push(ThreadEntry::Variable { + depth: *depth, + variable: variable.clone(), + has_children: variable.variables_reference > 0, + }); + } + } + + let len = entries.len(); + self.stack_frame_entries.insert(stack_frame.id, entries); + + self.variable_list.reset(len); } // fn render_scopes(&self, cx: &mut ViewContext) -> impl IntoElement { @@ -636,7 +664,8 @@ impl DebugPanelItem { } }; - self.build_variable_list_entries(self.current_thread_state().current_stack_frame_id); + // TODO: + // self.build_variable_list_entries(self.current_thread_state().current_stack_frame_id); cx.notify(); }