From 53336eedb75c8f7ef3bcbbfe11bb357f1fdd98a2 Mon Sep 17 00:00:00 2001 From: Anthony Eid Date: Fri, 14 Feb 2025 16:56:21 -0500 Subject: [PATCH] Move breakpoint serialization/deserialization to breakpoint store from project --- .../project/src/debugger/breakpoint_store.rs | 105 +++++++++++++++++- crates/project/src/project.rs | 101 +---------------- 2 files changed, 104 insertions(+), 102 deletions(-) diff --git a/crates/project/src/debugger/breakpoint_store.rs b/crates/project/src/debugger/breakpoint_store.rs index 52438322b2..ec7db5e747 100644 --- a/crates/project/src/debugger/breakpoint_store.rs +++ b/crates/project/src/debugger/breakpoint_store.rs @@ -3,14 +3,15 @@ use crate::{ BufferId, ProjectItem as _, ProjectPath, WorktreeStore, }; use anyhow::{Context as _, Result}; -use collections::{BTreeMap, HashSet}; -use dap::SourceBreakpoint; -use gpui::{AsyncApp, Context, Entity, EventEmitter}; +use collections::{BTreeMap, HashMap, HashSet}; +use dap::{debugger_settings::DebuggerSettings, SourceBreakpoint}; +use gpui::{App, AsyncApp, Context, Entity, EventEmitter}; use language::{ proto::{deserialize_anchor, serialize_anchor as serialize_text_anchor}, Buffer, BufferSnapshot, }; use rpc::{proto, AnyProtoClient, TypedEnvelope}; +use settings::Settings; use settings::WorktreeId; use std::{ hash::{Hash, Hasher}, @@ -18,7 +19,7 @@ use std::{ sync::Arc, }; use text::Point; -use util::ResultExt as _; +use util::{maybe, ResultExt as _}; struct RemoteBreakpointStore { upstream_client: Option, @@ -423,6 +424,102 @@ impl BreakpointStore { }) } + fn serialize_breakpoints_for_project_path( + &self, + project_path: &ProjectPath, + cx: &App, + ) -> Option<(Arc, Vec)> { + let buffer = maybe!({ + let buffer_id = self + .buffer_store + .read(cx) + .buffer_id_for_project_path(project_path)?; + Some(self.buffer_store.read(cx).get(*buffer_id)?.read(cx)) + }); + + let worktree_path = self + .worktree_store + .read(cx) + .worktree_for_id(project_path.worktree_id, cx)? + .read(cx) + .abs_path(); + + Some(( + worktree_path, + self.breakpoints + .get(&project_path)? + .iter() + .map(|bp| bp.to_serialized(buffer, project_path.path.clone())) + .collect(), + )) + } + + pub fn serialize_breakpoints(&self, cx: &App) -> HashMap, Vec> { + let mut result: HashMap, Vec> = Default::default(); + + if !DebuggerSettings::get_global(cx).save_breakpoints { + return result; + } + + for project_path in self.breakpoints.keys() { + if let Some((worktree_path, mut serialized_breakpoint)) = + self.serialize_breakpoints_for_project_path(project_path, cx) + { + result + .entry(worktree_path.clone()) + .or_default() + .append(&mut serialized_breakpoint) + } + } + + result + } + + pub fn all_breakpoints( + &self, + as_abs_path: bool, + cx: &App, + ) -> HashMap, Vec> { + let mut all_breakpoints: HashMap, Vec> = Default::default(); + + for (project_path, breakpoints) in &self.breakpoints { + let buffer = maybe!({ + let buffer_store = self.buffer_store.read(cx); + let buffer_id = buffer_store.buffer_id_for_project_path(project_path)?; + let buffer = buffer_store.get(*buffer_id)?; + Some(buffer.read(cx)) + }); + + let Some(path) = maybe!({ + if as_abs_path { + let worktree = self + .worktree_store + .read(cx) + .worktree_for_id(project_path.worktree_id, cx)?; + Some(Arc::from( + worktree + .read(cx) + .absolutize(&project_path.path) + .ok()? + .as_path(), + )) + } else { + Some(project_path.clone().path) + } + }) else { + continue; + }; + + all_breakpoints.entry(path).or_default().extend( + breakpoints + .into_iter() + .map(|bp| bp.to_serialized(buffer, project_path.clone().path)), + ); + } + + all_breakpoints + } + #[cfg(any(test, feature = "test-support"))] pub fn breakpoints(&self) -> &BTreeMap> { &self.breakpoints diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index eb28e7e881..82fc4d9e89 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1311,48 +1311,6 @@ impl Project { } } - pub fn all_breakpoints( - &self, - as_abs_path: bool, - cx: &mut Context, - ) -> HashMap, Vec> { - let mut all_breakpoints: HashMap, Vec> = Default::default(); - - for (project_path, breakpoints) in &self.breakpoint_store.read(cx).breakpoints { - let buffer = maybe!({ - let buffer_store = self.buffer_store.read(cx); - let buffer_id = buffer_store.buffer_id_for_project_path(project_path)?; - let buffer = self.buffer_for_id(*buffer_id, cx)?; - Some(buffer.read(cx)) - }); - - let Some(path) = maybe!({ - if as_abs_path { - let worktree = self.worktree_for_id(project_path.worktree_id, cx)?; - Some(Arc::from( - worktree - .read(cx) - .absolutize(&project_path.path) - .ok()? - .as_path(), - )) - } else { - Some(project_path.clone().path) - } - }) else { - continue; - }; - - all_breakpoints.entry(path).or_default().extend( - breakpoints - .into_iter() - .map(|bp| bp.to_serialized(buffer, project_path.clone().path)), - ); - } - - all_breakpoints - } - pub fn initial_send_breakpoints( &self, session_id: &DebugSessionId, @@ -1362,7 +1320,8 @@ impl Project { let mut tasks = Vec::new(); for (abs_path, serialized_breakpoints) in self - .all_breakpoints(true, cx) + .breakpoint_store() + .read_with(cx, |store, cx| store.all_breakpoints(true, cx)) .into_iter() .filter(|(_, bps)| !bps.is_empty()) { @@ -1410,65 +1369,11 @@ impl Project { }) } - /// Get all serialized breakpoints that belong to a buffer - pub fn serialize_breakpoints_for_project_path( - &self, - project_path: &ProjectPath, - cx: &Context, - ) -> Option<(Arc, Vec)> { - let buffer = maybe!({ - let buffer_id = self - .buffer_store - .read(cx) - .buffer_id_for_project_path(project_path)?; - Some(self.buffer_for_id(*buffer_id, cx)?.read(cx)) - }); - - let worktree_path = self - .worktree_for_id(project_path.worktree_id, cx)? - .read(cx) - .abs_path(); - - Some(( - worktree_path, - self.breakpoint_store - .read(cx) - .breakpoints - .get(&project_path)? - .iter() - .map(|bp| bp.to_serialized(buffer, project_path.path.clone())) - .collect(), - )) - } - - /// Serialize all breakpoints to save within workspace's database - /// - /// # Return - /// HashMap: - /// Key: A valid worktree path - /// Value: All serialized breakpoints that belong to a worktree pub fn serialize_breakpoints( &self, cx: &Context, ) -> HashMap, Vec> { - let mut result: HashMap, Vec> = Default::default(); - - if !DebuggerSettings::get_global(cx).save_breakpoints { - return result; - } - - for project_path in self.breakpoint_store.read(cx).breakpoints.keys() { - if let Some((worktree_path, mut serialized_breakpoint)) = - self.serialize_breakpoints_for_project_path(project_path, cx) - { - result - .entry(worktree_path.clone()) - .or_default() - .append(&mut serialized_breakpoint) - } - } - - result + self.breakpoint_store.read(cx).serialize_breakpoints(cx) } async fn handle_toggle_ignore_breakpoints(