From 3d512f6b864e3eed714948da731583b30a47b42e Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Wed, 22 Jan 2025 11:41:42 +0100 Subject: [PATCH] Revert debugger branch merge --- .../20221109000000_test_schema.sql | 1 - .../20250121181012_add_ignore_breakpoints.sql | 2 - crates/collab/src/db/queries/projects.rs | 39 -- crates/collab/src/db/tables/debug_clients.rs | 1 - crates/collab/src/rpc.rs | 29 -- crates/collab/src/tests/debug_panel_tests.rs | 490 ------------------ crates/dap/src/session.rs | 117 ++--- crates/debugger_tools/src/dap_log.rs | 41 +- crates/debugger_ui/src/debugger_panel.rs | 19 +- crates/debugger_ui/src/debugger_panel_item.rs | 6 - .../debugger_ui/src/tests/debugger_panel.rs | 4 +- crates/project/src/dap_store.rs | 233 ++------- crates/project/src/project.rs | 44 -- crates/proto/proto/zed.proto | 25 +- crates/proto/src/proto.rs | 6 - 15 files changed, 88 insertions(+), 969 deletions(-) delete mode 100644 crates/collab/migrations/20250121181012_add_ignore_breakpoints.sql diff --git a/crates/collab/migrations.sqlite/20221109000000_test_schema.sql b/crates/collab/migrations.sqlite/20221109000000_test_schema.sql index c36207514aed29..5a065878af4ab7 100644 --- a/crates/collab/migrations.sqlite/20221109000000_test_schema.sql +++ b/crates/collab/migrations.sqlite/20221109000000_test_schema.sql @@ -474,7 +474,6 @@ CREATE TABLE IF NOT EXISTS "debug_clients" ( project_id INTEGER NOT NULL, session_id BIGINT NOT NULL, capabilities INTEGER NOT NULL, - ignore_breakpoints BOOLEAN NOT NULL DEFAULT FALSE, PRIMARY KEY (id, project_id, session_id), FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE ); diff --git a/crates/collab/migrations/20250121181012_add_ignore_breakpoints.sql b/crates/collab/migrations/20250121181012_add_ignore_breakpoints.sql deleted file mode 100644 index e1e362c5cf84ad..00000000000000 --- a/crates/collab/migrations/20250121181012_add_ignore_breakpoints.sql +++ /dev/null @@ -1,2 +0,0 @@ - -ALTER TABLE debug_clients ADD COLUMN ignore_breakpoints BOOLEAN NOT NULL DEFAULT FALSE; diff --git a/crates/collab/src/db/queries/projects.rs b/crates/collab/src/db/queries/projects.rs index b25c754d83c7a6..da0d99432be96a 100644 --- a/crates/collab/src/db/queries/projects.rs +++ b/crates/collab/src/db/queries/projects.rs @@ -556,40 +556,6 @@ impl Database { .await } - pub async fn ignore_breakpoint_state( - &self, - connection_id: ConnectionId, - update: &proto::IgnoreBreakpointState, - ) -> Result>> { - let project_id = ProjectId::from_proto(update.project_id); - self.project_transaction(project_id, |tx| async move { - let debug_clients = debug_clients::Entity::find() - .filter( - Condition::all() - .add(debug_clients::Column::ProjectId.eq(project_id)) - .add(debug_clients::Column::SessionId.eq(update.session_id)), - ) - .all(&*tx) - .await?; - - for debug_client in debug_clients { - debug_clients::Entity::update(debug_clients::ActiveModel { - id: ActiveValue::Unchanged(debug_client.id), - project_id: ActiveValue::Unchanged(debug_client.project_id), - session_id: ActiveValue::Unchanged(debug_client.session_id), - capabilities: ActiveValue::Unchanged(debug_client.capabilities), - ignore_breakpoints: ActiveValue::Set(update.ignore), - }) - .exec(&*tx) - .await?; - } - - self.internal_project_connection_ids(project_id, connection_id, true, &tx) - .await - }) - .await - } - pub async fn update_debug_adapter( &self, connection_id: ConnectionId, @@ -681,7 +647,6 @@ impl Database { project_id: ActiveValue::Set(project_id), session_id: ActiveValue::Set(update.session_id as i64), capabilities: ActiveValue::Set(0), - ignore_breakpoints: ActiveValue::Set(false), }; new_debug_client.insert(&*tx).await?; } @@ -764,7 +729,6 @@ impl Database { project_id: ActiveValue::Set(project_id), session_id: ActiveValue::Set(update.session_id as i64), capabilities: ActiveValue::Set(0), - ignore_breakpoints: ActiveValue::Set(false), }; debug_client = Some(new_debug_client.insert(&*tx).await?); } @@ -778,7 +742,6 @@ impl Database { project_id: ActiveValue::Unchanged(debug_client.project_id), session_id: ActiveValue::Unchanged(debug_client.session_id), capabilities: ActiveValue::Set(debug_client.capabilities), - ignore_breakpoints: ActiveValue::Set(debug_client.ignore_breakpoints), }) .exec(&*tx) .await?; @@ -1123,7 +1086,6 @@ impl Database { for (session_id, clients) in debug_sessions.into_iter() { let mut debug_clients = Vec::default(); - let ignore_breakpoints = clients.iter().any(|debug| debug.ignore_breakpoints); // Temp solution until client -> session change for debug_client in clients.into_iter() { let debug_panel_items = debug_client @@ -1146,7 +1108,6 @@ impl Database { project_id, session_id: session_id as u64, clients: debug_clients, - ignore_breakpoints, }); } diff --git a/crates/collab/src/db/tables/debug_clients.rs b/crates/collab/src/db/tables/debug_clients.rs index 498b9ed7359091..02758acaa0c4fa 100644 --- a/crates/collab/src/db/tables/debug_clients.rs +++ b/crates/collab/src/db/tables/debug_clients.rs @@ -25,7 +25,6 @@ pub struct Model { pub session_id: i64, #[sea_orm(column_type = "Integer")] pub capabilities: i32, - pub ignore_breakpoints: bool, } impl Model { diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index fa116c8cc54938..cf7083a21c1a99 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -438,13 +438,6 @@ impl Server { .add_request_handler(forward_mutating_project_request::) .add_message_handler( broadcast_project_message_from_host::, - ) - .add_message_handler( - broadcast_project_message_from_host::, - ) - .add_message_handler(ignore_breakpoint_state) - .add_message_handler( - broadcast_project_message_from_host::, ); Arc::new(server) @@ -2162,28 +2155,6 @@ async fn shutdown_debug_client( Ok(()) } -async fn ignore_breakpoint_state( - request: proto::IgnoreBreakpointState, - session: Session, -) -> Result<()> { - let guest_connection_ids = session - .db() - .await - .ignore_breakpoint_state(session.connection_id, &request) - .await?; - - broadcast( - Some(session.connection_id), - guest_connection_ids.iter().copied(), - |connection_id| { - session - .peer - .forward_send(session.connection_id, connection_id, request.clone()) - }, - ); - Ok(()) -} - /// Notify other participants that a debug panel item has been updated async fn update_debug_adapter(request: proto::UpdateDebugAdapter, session: Session) -> Result<()> { let guest_connection_ids = session diff --git a/crates/collab/src/tests/debug_panel_tests.rs b/crates/collab/src/tests/debug_panel_tests.rs index c90144b4e94230..40c2a5af97a59e 100644 --- a/crates/collab/src/tests/debug_panel_tests.rs +++ b/crates/collab/src/tests/debug_panel_tests.rs @@ -1836,493 +1836,3 @@ async fn test_variable_list( shutdown_client.await.unwrap(); } - -#[gpui::test] -async fn test_ignore_breakpoints( - cx_a: &mut TestAppContext, - cx_b: &mut TestAppContext, - cx_c: &mut TestAppContext, -) { - let executor = cx_a.executor(); - let mut server = TestServer::start(executor.clone()).await; - let client_a = server.create_client(cx_a, "user_a").await; - let client_b = server.create_client(cx_b, "user_b").await; - let client_c = server.create_client(cx_c, "user_c").await; - - client_a - .fs() - .insert_tree( - "/project", - json!({ - "test.txt": "one\ntwo\nthree\nfour\nfive", - }), - ) - .await; - - init_test(cx_a); - init_test(cx_b); - init_test(cx_c); - - server - .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)]) - .await; - let active_call_a = cx_a.read(ActiveCall::global); - let active_call_b = cx_b.read(ActiveCall::global); - let active_call_c = cx_c.read(ActiveCall::global); - - let (project_a, worktree_id) = client_a.build_local_project("/project", cx_a).await; - active_call_a - .update(cx_a, |call, cx| call.set_location(Some(&project_a), cx)) - .await - .unwrap(); - - let project_path = ProjectPath { - worktree_id, - path: Arc::from(Path::new(&"test.txt")), - }; - - let project_id = active_call_a - .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) - .await - .unwrap(); - let project_b = client_b.join_remote_project(project_id, cx_b).await; - active_call_b - .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) - .await - .unwrap(); - - let (workspace_a, cx_a) = client_a.build_workspace(&project_a, cx_a); - let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b); - - add_debugger_panel(&workspace_a, cx_a).await; - add_debugger_panel(&workspace_b, cx_b).await; - - let local_editor = workspace_a - .update(cx_a, |workspace, cx| { - workspace.open_path(project_path.clone(), None, true, cx) - }) - .await - .unwrap() - .downcast::() - .unwrap(); - - local_editor.update(cx_a, |editor, cx| { - editor.move_down(&editor::actions::MoveDown, cx); - editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, cx); // Line 2 - editor.move_down(&editor::actions::MoveDown, cx); - editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, cx); // Line 3 - }); - - cx_a.run_until_parked(); - cx_b.run_until_parked(); - - let task = project_a.update(cx_a, |project, cx| { - project.start_debug_session( - dap::DebugAdapterConfig { - label: "test config".into(), - kind: dap::DebugAdapterKind::Fake, - request: dap::DebugRequestType::Launch, - program: None, - cwd: None, - initialize_args: None, - }, - cx, - ) - }); - - let (session, client) = task.await.unwrap(); - let client_id = client.id(); - - client - .on_request::(move |_, _| { - Ok(dap::Capabilities { - supports_configuration_done_request: Some(true), - ..Default::default() - }) - }) - .await; - - let called_set_breakpoints = Arc::new(AtomicBool::new(false)); - client - .on_request::({ - let called_set_breakpoints = called_set_breakpoints.clone(); - move |_, args| { - assert_eq!("/project/test.txt", args.source.path.unwrap()); - - let mut actual_breakpoints = args.breakpoints.unwrap(); - actual_breakpoints.sort_by_key(|b| b.line); - - let expected_breakpoints = vec![ - SourceBreakpoint { - line: 2, - column: None, - condition: None, - hit_condition: None, - log_message: None, - mode: None, - }, - SourceBreakpoint { - line: 3, - column: None, - condition: None, - hit_condition: None, - log_message: None, - mode: None, - }, - ]; - - assert_eq!(actual_breakpoints, expected_breakpoints); - - called_set_breakpoints.store(true, Ordering::SeqCst); - - Ok(dap::SetBreakpointsResponse { - breakpoints: Vec::default(), - }) - } - }) - .await; - - client.on_request::(move |_, _| Ok(())).await; - client - .on_request::(move |_, _| { - Ok(dap::StackTraceResponse { - stack_frames: Vec::default(), - total_frames: None, - }) - }) - .await; - - client.on_request::(move |_, _| Ok(())).await; - - client - .fake_event(dap::messages::Events::Initialized(Some( - dap::Capabilities { - supports_configuration_done_request: Some(true), - ..Default::default() - }, - ))) - .await; - - cx_a.run_until_parked(); - cx_b.run_until_parked(); - - assert!( - called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst), - "SetBreakpoint request must be called when starting debug session" - ); - - client - .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { - reason: dap::StoppedEventReason::Pause, - description: None, - thread_id: Some(1), - preserve_focus_hint: None, - text: None, - all_threads_stopped: None, - hit_breakpoint_ids: None, - })) - .await; - - cx_a.run_until_parked(); - cx_b.run_until_parked(); - - let remote_debug_item = workspace_b.update(cx_b, |workspace, cx| { - let debug_panel = workspace.panel::(cx).unwrap(); - let active_debug_panel_item = debug_panel - .update(cx, |this, cx| this.active_debug_panel_item(cx)) - .unwrap(); - - assert_eq!( - 1, - debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len()) - ); - - let session_id = debug_panel.update(cx, |this, cx| { - this.dap_store() - .read(cx) - .as_remote() - .unwrap() - .session_by_client_id(&client.id()) - .unwrap() - .read(cx) - .id() - }); - - let breakpoints_ignored = active_debug_panel_item.read(cx).are_breakpoints_ignored(cx); - - assert_eq!(session_id, active_debug_panel_item.read(cx).session_id()); - assert_eq!(false, breakpoints_ignored); - assert_eq!(client.id(), active_debug_panel_item.read(cx).client_id()); - assert_eq!(1, active_debug_panel_item.read(cx).thread_id()); - active_debug_panel_item - }); - - called_set_breakpoints.store(false, Ordering::SeqCst); - - client - .on_request::({ - let called_set_breakpoints = called_set_breakpoints.clone(); - move |_, args| { - assert_eq!("/project/test.txt", args.source.path.unwrap()); - assert_eq!(args.breakpoints, Some(vec![])); - - called_set_breakpoints.store(true, Ordering::SeqCst); - - Ok(dap::SetBreakpointsResponse { - breakpoints: Vec::default(), - }) - } - }) - .await; - - let local_debug_item = workspace_a.update(cx_a, |workspace, cx| { - let debug_panel = workspace.panel::(cx).unwrap(); - let active_debug_panel_item = debug_panel - .update(cx, |this, cx| this.active_debug_panel_item(cx)) - .unwrap(); - - assert_eq!( - 1, - debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len()) - ); - - assert_eq!( - false, - active_debug_panel_item.read(cx).are_breakpoints_ignored(cx) - ); - assert_eq!(client.id(), active_debug_panel_item.read(cx).client_id()); - assert_eq!(1, active_debug_panel_item.read(cx).thread_id()); - - active_debug_panel_item - }); - - local_debug_item.update(cx_a, |item, cx| { - item.toggle_ignore_breakpoints(cx); // Set to true - assert_eq!(true, item.are_breakpoints_ignored(cx)); - }); - - cx_a.run_until_parked(); - cx_b.run_until_parked(); - - assert!( - called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst), - "SetBreakpoint request must be called to ignore breakpoints" - ); - - client - .on_request::({ - let called_set_breakpoints = called_set_breakpoints.clone(); - move |_, _args| { - called_set_breakpoints.store(true, Ordering::SeqCst); - - Ok(dap::SetBreakpointsResponse { - breakpoints: Vec::default(), - }) - } - }) - .await; - - let remote_editor = workspace_b - .update(cx_b, |workspace, cx| { - workspace.open_path(project_path.clone(), None, true, cx) - }) - .await - .unwrap() - .downcast::() - .unwrap(); - - called_set_breakpoints.store(false, std::sync::atomic::Ordering::SeqCst); - - remote_editor.update(cx_b, |editor, cx| { - editor.toggle_breakpoint(&editor::actions::ToggleBreakpoint, cx); // Line 1 - }); - - cx_a.run_until_parked(); - cx_b.run_until_parked(); - - assert!( - called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst), - "SetBreakpoint request be called whenever breakpoints are toggled but with not breakpoints" - ); - - remote_debug_item.update(cx_b, |debug_panel, cx| { - let breakpoints_ignored = debug_panel.are_breakpoints_ignored(cx); - - assert_eq!(true, breakpoints_ignored); - assert_eq!(client.id(), debug_panel.client_id()); - assert_eq!(1, debug_panel.thread_id()); - }); - - client - .on_request::({ - let called_set_breakpoints = called_set_breakpoints.clone(); - move |_, args| { - assert_eq!("/project/test.txt", args.source.path.unwrap()); - - let mut actual_breakpoints = args.breakpoints.unwrap(); - actual_breakpoints.sort_by_key(|b| b.line); - - let expected_breakpoints = vec![ - SourceBreakpoint { - line: 1, - column: None, - condition: None, - hit_condition: None, - log_message: None, - mode: None, - }, - SourceBreakpoint { - line: 2, - column: None, - condition: None, - hit_condition: None, - log_message: None, - mode: None, - }, - SourceBreakpoint { - line: 3, - column: None, - condition: None, - hit_condition: None, - log_message: None, - mode: None, - }, - ]; - - assert_eq!(actual_breakpoints, expected_breakpoints); - - called_set_breakpoints.store(true, Ordering::SeqCst); - - Ok(dap::SetBreakpointsResponse { - breakpoints: Vec::default(), - }) - } - }) - .await; - - let project_c = client_c.join_remote_project(project_id, cx_c).await; - active_call_c - .update(cx_c, |call, cx| call.set_location(Some(&project_c), cx)) - .await - .unwrap(); - - let (workspace_c, cx_c) = client_c.build_workspace(&project_c, cx_c); - add_debugger_panel(&workspace_c, cx_c).await; - - let last_join_remote_item = workspace_c.update(cx_c, |workspace, cx| { - let debug_panel = workspace.panel::(cx).unwrap(); - let active_debug_panel_item = debug_panel - .update(cx, |this, cx| this.active_debug_panel_item(cx)) - .unwrap(); - - let breakpoints_ignored = active_debug_panel_item.read(cx).are_breakpoints_ignored(cx); - - assert_eq!(true, breakpoints_ignored); - - assert_eq!( - 1, - debug_panel.update(cx, |this, cx| this.pane().unwrap().read(cx).items_len()) - ); - assert_eq!(client.id(), active_debug_panel_item.read(cx).client_id()); - assert_eq!(1, active_debug_panel_item.read(cx).thread_id()); - active_debug_panel_item - }); - - remote_debug_item.update(cx_b, |item, cx| { - item.toggle_ignore_breakpoints(cx); - }); - - cx_a.run_until_parked(); - cx_b.run_until_parked(); - cx_c.run_until_parked(); - - assert!( - called_set_breakpoints.load(std::sync::atomic::Ordering::SeqCst), - "SetBreakpoint request should be called to update breakpoints" - ); - - client - .on_request::({ - let called_set_breakpoints = called_set_breakpoints.clone(); - move |_, args| { - assert_eq!("/project/test.txt", args.source.path.unwrap()); - assert_eq!(args.breakpoints, Some(vec![])); - - called_set_breakpoints.store(true, Ordering::SeqCst); - - Ok(dap::SetBreakpointsResponse { - breakpoints: Vec::default(), - }) - } - }) - .await; - - local_debug_item.update(cx_a, |debug_panel_item, cx| { - assert_eq!( - false, - debug_panel_item.are_breakpoints_ignored(cx), - "Remote client set this to false" - ); - }); - - remote_debug_item.update(cx_b, |debug_panel_item, cx| { - assert_eq!( - false, - debug_panel_item.are_breakpoints_ignored(cx), - "Remote client set this to false" - ); - }); - - last_join_remote_item.update(cx_c, |debug_panel_item, cx| { - assert_eq!( - false, - debug_panel_item.are_breakpoints_ignored(cx), - "Remote client set this to false" - ); - }); - - let shutdown_client = project_a.update(cx_a, |project, cx| { - project.dap_store().update(cx, |dap_store, cx| { - dap_store.shutdown_session(&session.read(cx).id(), cx) - }) - }); - - shutdown_client.await.unwrap(); - - cx_a.run_until_parked(); - cx_b.run_until_parked(); - - project_b.update(cx_b, |project, cx| { - project.dap_store().update(cx, |dap_store, _cx| { - let sessions = dap_store.sessions().collect::>(); - - assert_eq!( - None, - dap_store.session_by_client_id(&client_id), - "No client_id to session mapping should exist after shutdown" - ); - assert_eq!( - 0, - sessions.len(), - "No sessions should be left after shutdown" - ); - }) - }); - - project_c.update(cx_c, |project, cx| { - project.dap_store().update(cx, |dap_store, _cx| { - let sessions = dap_store.sessions().collect::>(); - - assert_eq!( - None, - dap_store.session_by_client_id(&client_id), - "No client_id to session mapping should exist after shutdown" - ); - assert_eq!( - 0, - sessions.len(), - "No sessions should be left after shutdown" - ); - }) - }); -} diff --git a/crates/dap/src/session.rs b/crates/dap/src/session.rs index 745b0ec5244f53..77e07a76a526e0 100644 --- a/crates/dap/src/session.rs +++ b/crates/dap/src/session.rs @@ -19,37 +19,54 @@ impl DebugSessionId { } } -pub enum DebugSession { - Local(LocalDebugSession), - Remote(RemoteDebugSession), -} - -pub struct LocalDebugSession { +pub struct DebugSession { id: DebugSessionId, ignore_breakpoints: bool, configuration: DebugAdapterConfig, clients: HashMap>, } -impl LocalDebugSession { +impl DebugSession { + pub fn new(id: DebugSessionId, configuration: DebugAdapterConfig) -> Self { + Self { + id, + configuration, + ignore_breakpoints: false, + clients: HashMap::default(), + } + } + + pub fn id(&self) -> DebugSessionId { + self.id + } + + pub fn name(&self) -> String { + self.configuration.label.clone() + } + pub fn configuration(&self) -> &DebugAdapterConfig { &self.configuration } + pub fn ignore_breakpoints(&self) -> bool { + self.ignore_breakpoints + } + + pub fn set_ignore_breakpoints(&mut self, ignore: bool, cx: &mut ModelContext) { + self.ignore_breakpoints = ignore; + cx.notify(); + } + pub fn update_configuration( &mut self, f: impl FnOnce(&mut DebugAdapterConfig), - cx: &mut ModelContext, + cx: &mut ModelContext, ) { f(&mut self.configuration); cx.notify(); } - pub fn add_client( - &mut self, - client: Arc, - cx: &mut ModelContext, - ) { + pub fn add_client(&mut self, client: Arc, cx: &mut ModelContext) { self.clients.insert(client.id(), client); cx.notify(); } @@ -57,7 +74,7 @@ impl LocalDebugSession { pub fn remove_client( &mut self, client_id: &DebugAdapterClientId, - cx: &mut ModelContext, + cx: &mut ModelContext, ) -> Option> { let client = self.clients.remove(client_id); cx.notify(); @@ -84,76 +101,4 @@ impl LocalDebugSession { pub fn client_ids(&self) -> impl Iterator + '_ { self.clients.keys().cloned() } - - pub fn id(&self) -> DebugSessionId { - self.id - } -} - -pub struct RemoteDebugSession { - id: DebugSessionId, - ignore_breakpoints: bool, - label: String, -} - -impl DebugSession { - pub fn new_local(id: DebugSessionId, configuration: DebugAdapterConfig) -> Self { - Self::Local(LocalDebugSession { - id, - ignore_breakpoints: false, - configuration, - clients: HashMap::default(), - }) - } - - pub fn as_local(&self) -> Option<&LocalDebugSession> { - match self { - DebugSession::Local(local) => Some(local), - _ => None, - } - } - - pub fn as_local_mut(&mut self) -> Option<&mut LocalDebugSession> { - match self { - DebugSession::Local(local) => Some(local), - _ => None, - } - } - - pub fn new_remote(id: DebugSessionId, label: String, ignore_breakpoints: bool) -> Self { - Self::Remote(RemoteDebugSession { - id, - label: label.clone(), - ignore_breakpoints, - }) - } - - pub fn id(&self) -> DebugSessionId { - match self { - DebugSession::Local(local) => local.id, - DebugSession::Remote(remote) => remote.id, - } - } - - pub fn name(&self) -> String { - match self { - DebugSession::Local(local) => local.configuration.label.clone(), - DebugSession::Remote(remote) => remote.label.clone(), - } - } - - pub fn ignore_breakpoints(&self) -> bool { - match self { - DebugSession::Local(local) => local.ignore_breakpoints, - DebugSession::Remote(remote) => remote.ignore_breakpoints, - } - } - - pub fn set_ignore_breakpoints(&mut self, ignore: bool, cx: &mut ModelContext) { - match self { - DebugSession::Local(local) => local.ignore_breakpoints = ignore, - DebugSession::Remote(remote) => remote.ignore_breakpoints = ignore, - } - cx.notify(); - } } diff --git a/crates/debugger_tools/src/dap_log.rs b/crates/debugger_tools/src/dap_log.rs index b111ecb1f8bb93..c315a12384833c 100644 --- a/crates/debugger_tools/src/dap_log.rs +++ b/crates/debugger_tools/src/dap_log.rs @@ -580,28 +580,25 @@ impl DapLogView { .dap_store() .read(cx) .sessions() - .filter_map(|session| { - Some(DapMenuItem { - session_id: session.read(cx).id(), - session_name: session.read(cx).name(), - clients: { - let mut clients = session - .read(cx) - .as_local()? - .clients() - .map(|client| DapMenuSubItem { - client_id: client.id(), - client_name: client.adapter_id(), - has_adapter_logs: client.has_adapter_logs(), - selected_entry: self - .current_view - .map_or(LogKind::Adapter, |(_, kind)| kind), - }) - .collect::>(); - clients.sort_by_key(|item| item.client_id.0); - clients - }, - }) + .map(|session| DapMenuItem { + session_id: session.read(cx).id(), + session_name: session.read(cx).name(), + clients: { + let mut clients = session + .read(cx) + .clients() + .map(|client| DapMenuSubItem { + client_id: client.id(), + client_name: client.adapter_id(), + has_adapter_logs: client.has_adapter_logs(), + selected_entry: self + .current_view + .map_or(LogKind::Adapter, |(_, kind)| kind), + }) + .collect::>(); + clients.sort_by_key(|item| item.client_id.0); + clients + }, }) .collect::>(); menu_items.sort_by_key(|item| item.session_id.0); diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 9d588cd06e8138..ec343930ef45e2 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -292,11 +292,6 @@ impl DebugPanel { &self.message_queue } - #[cfg(any(test, feature = "test-support"))] - pub fn dap_store(&self) -> Model { - self.dap_store.clone() - } - pub fn active_debug_panel_item( &self, cx: &mut ViewContext, @@ -570,19 +565,14 @@ impl DebugPanel { client_id: &DebugAdapterClientId, cx: &mut ViewContext, ) { - let Some(session) = self - .dap_store - .read(cx) - .session_by_id(session_id) - .and_then(|session| session.read(cx).as_local()) - else { + let Some(session) = self.dap_store.read(cx).session_by_id(session_id) else { return; }; let session_id = *session_id; let client_id = *client_id; let workspace = self.workspace.clone(); - let request_type = session.configuration().request.clone(); + let request_type = session.read(cx).configuration().request.clone(); cx.spawn(|this, mut cx| async move { let task = this.update(&mut cx, |this, cx| { this.dap_store.update(cx, |store, cx| { @@ -1040,11 +1030,6 @@ impl DebugPanel { ) }); - self.dap_store.update(cx, |dap_store, cx| { - dap_store.add_remote_session(session_id, None, cx); - dap_store.add_client_to_session(session_id, client_id); - }); - pane.add_item(Box::new(debug_panel_item.clone()), true, true, None, cx); debug_panel_item }); diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index a645578f3fda1f..35ee5957f41737 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -506,12 +506,6 @@ impl DebugPanelItem { &self.thread_state } - #[cfg(any(test, feature = "test-support"))] - pub fn are_breakpoints_ignored(&self, cx: &AppContext) -> bool { - self.dap_store - .read_with(cx, |dap, cx| dap.ignore_breakpoints(&self.session_id, cx)) - } - pub fn capabilities(&self, cx: &mut ViewContext) -> Capabilities { self.dap_store.read(cx).capabilities_by_id(&self.client_id) } diff --git a/crates/debugger_ui/src/tests/debugger_panel.rs b/crates/debugger_ui/src/tests/debugger_panel.rs index 62e397e2ec3de6..33915218083af8 100644 --- a/crates/debugger_ui/src/tests/debugger_panel.rs +++ b/crates/debugger_ui/src/tests/debugger_panel.rs @@ -749,7 +749,7 @@ async fn test_handle_start_debugging_reverse_request( cx.run_until_parked(); project.update(cx, |_, cx| { - assert_eq!(2, session.read(cx).as_local().unwrap().clients_len()); + assert_eq!(2, session.read(cx).clients_len()); }); assert!( send_response.load(std::sync::atomic::Ordering::SeqCst), @@ -759,8 +759,6 @@ async fn test_handle_start_debugging_reverse_request( let second_client = project.update(cx, |_, cx| { session .read(cx) - .as_local() - .unwrap() .client_by_id(&DebugAdapterClientId(1)) .unwrap() }); diff --git a/crates/project/src/dap_store.rs b/crates/project/src/dap_store.rs index f107ee1ad01099..046b9a55814936 100644 --- a/crates/project/src/dap_store.rs +++ b/crates/project/src/dap_store.rs @@ -128,22 +128,9 @@ impl LocalDapStore { pub struct RemoteDapStore { upstream_client: Option, upstream_project_id: u64, - sessions: HashMap>, - client_by_session: HashMap, event_queue: Option>, } -impl RemoteDapStore { - pub fn session_by_client_id( - &self, - client_id: &DebugAdapterClientId, - ) -> Option> { - self.client_by_session - .get(client_id) - .and_then(|session_id| self.sessions.get(session_id).cloned()) - } -} - pub struct DapStore { mode: DapStoreMode, downstream_client: Option<(AnyProtoClient, u64)>, @@ -166,8 +153,6 @@ impl DapStore { client.add_model_message_handler(DapStore::handle_synchronize_breakpoints); client.add_model_message_handler(DapStore::handle_update_debug_adapter); client.add_model_message_handler(DapStore::handle_update_thread_status); - client.add_model_message_handler(DapStore::handle_ignore_breakpoint_state); - client.add_model_message_handler(DapStore::handle_session_has_shutdown); client.add_model_request_handler(DapStore::handle_dap_command::); client.add_model_request_handler(DapStore::handle_dap_command::); @@ -181,7 +166,7 @@ impl DapStore { client.add_model_request_handler(DapStore::handle_dap_command::); client.add_model_request_handler(DapStore::handle_dap_command::); client.add_model_request_handler(DapStore::handle_dap_command::); - client.add_model_request_handler(DapStore::handle_shutdown_session_request); + client.add_model_request_handler(DapStore::handle_shutdown_session); } pub fn new_local( @@ -220,8 +205,6 @@ impl DapStore { mode: DapStoreMode::Remote(RemoteDapStore { upstream_client: Some(upstream_client), upstream_project_id: project_id, - sessions: Default::default(), - client_by_session: Default::default(), event_queue: Some(VecDeque::default()), }), downstream_client: None, @@ -280,91 +263,21 @@ impl DapStore { self.downstream_client.as_ref() } - pub fn add_remote_session( - &mut self, - session_id: DebugSessionId, - ignore: Option, - cx: &mut ModelContext, - ) { - match &mut self.mode { - DapStoreMode::Remote(remote) => { - remote - .sessions - .entry(session_id) - .or_insert(cx.new_model(|_| { - DebugSession::new_remote( - session_id, - "Remote-Debug".to_owned(), - ignore.unwrap_or(false), - ) - })); - } - _ => {} - } - } - - pub fn add_client_to_session( - &mut self, - session_id: DebugSessionId, - client_id: DebugAdapterClientId, - ) { - match &mut self.mode { - DapStoreMode::Local(local) => { - if local.sessions.contains_key(&session_id) { - local.client_by_session.insert(client_id, session_id); - } - } - DapStoreMode::Remote(remote) => { - if remote.sessions.contains_key(&session_id) { - remote.client_by_session.insert(client_id, session_id); - } - } - } - } - - pub fn remove_session(&mut self, session_id: DebugSessionId, cx: &mut ModelContext) { - match &mut self.mode { - DapStoreMode::Local(local) => { - if let Some(session) = local.sessions.remove(&session_id) { - for client_id in session - .read(cx) - .as_local() - .map(|local| local.client_ids()) - .expect("Local Dap can only have local sessions") - { - local.client_by_session.remove(&client_id); - } - } - } - DapStoreMode::Remote(remote) => { - remote.sessions.remove(&session_id); - remote.client_by_session.retain(|_, val| val != &session_id) - } - } - } - pub fn sessions(&self) -> impl Iterator> + '_ { - match &self.mode { - DapStoreMode::Local(local) => local.sessions.values().cloned(), - DapStoreMode::Remote(remote) => remote.sessions.values().cloned(), - } + self.as_local().unwrap().sessions.values().cloned() } pub fn session_by_id(&self, session_id: &DebugSessionId) -> Option> { - match &self.mode { - DapStoreMode::Local(local) => local.sessions.get(session_id).cloned(), - DapStoreMode::Remote(remote) => remote.sessions.get(session_id).cloned(), - } + self.as_local() + .and_then(|store| store.sessions.get(session_id).cloned()) } pub fn session_by_client_id( &self, client_id: &DebugAdapterClientId, ) -> Option> { - match &self.mode { - DapStoreMode::Local(local) => local.session_by_client_id(client_id), - DapStoreMode::Remote(remote) => remote.session_by_client_id(client_id), - } + self.as_local() + .and_then(|store| store.session_by_client_id(client_id)) } pub fn client_by_id( @@ -372,10 +285,10 @@ impl DapStore { client_id: &DebugAdapterClientId, cx: &ModelContext, ) -> Option<(Model, Arc)> { - let local_session = self.session_by_client_id(client_id)?; - let client = local_session.read(cx).as_local()?.client_by_id(client_id)?; + let session = self.session_by_client_id(client_id)?; + let client = session.read(cx).client_by_id(client_id)?; - Some((local_session, client)) + Some((session, client)) } pub fn capabilities_by_id(&self, client_id: &DebugAdapterClientId) -> Capabilities { @@ -458,50 +371,7 @@ impl DapStore { &self.breakpoints } - async fn handle_session_has_shutdown( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result<()> { - this.update(&mut cx, |this, cx| { - this.remove_session(DebugSessionId::from_proto(envelope.payload.session_id), cx); - })?; - - Ok(()) - } - - async fn handle_ignore_breakpoint_state( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result<()> { - let session_id = DebugSessionId::from_proto(envelope.payload.session_id); - - this.update(&mut cx, |this, cx| { - if let Some(session) = this.session_by_id(&session_id) { - session.update(cx, |session, cx| { - session.set_ignore_breakpoints(envelope.payload.ignore, cx) - }); - } - })?; - - Ok(()) - } - - pub fn set_ignore_breakpoints( - &mut self, - session_id: &DebugSessionId, - ignore: bool, - cx: &mut ModelContext, - ) { - if let Some(session) = self.session_by_id(session_id) { - session.update(cx, |session, cx| { - session.set_ignore_breakpoints(ignore, cx); - }); - } - } - - pub fn ignore_breakpoints(&self, session_id: &DebugSessionId, cx: &AppContext) -> bool { + pub fn ignore_breakpoints(&self, session_id: &DebugSessionId, cx: &ModelContext) -> bool { self.session_by_id(session_id) .map(|session| session.read(cx).ignore_breakpoints()) .unwrap_or_default() @@ -647,15 +517,13 @@ impl DapStore { let session = store.session_by_id(&session_id).unwrap(); session.update(cx, |session, cx| { - let local_session = session.as_local_mut().unwrap(); - - local_session.update_configuration( + session.update_configuration( |old_config| { *old_config = config.clone(); }, cx, ); - local_session.add_client(Arc::new(client), cx); + session.add_client(Arc::new(client), cx); }); // don't emit this event ourself in tests, so we can add request, @@ -778,7 +646,7 @@ impl DapStore { self.start_client_internal(session_id, worktree, config.clone(), cx); cx.spawn(|this, mut cx| async move { - let session = cx.new_model(|_| DebugSession::new_local(session_id, config))?; + let session = cx.new_model(|_| DebugSession::new(session_id, config))?; let client = match start_client_task.await { Ok(client) => client, @@ -794,10 +662,7 @@ impl DapStore { this.update(&mut cx, |store, cx| { session.update(cx, |session, cx| { - session - .as_local_mut() - .unwrap() - .add_client(client.clone(), cx); + session.add_client(client.clone(), cx); }); let client_id = client.id(); @@ -873,7 +738,7 @@ impl DapStore { ))); }; - let config = session.read(cx).as_local().unwrap().configuration(); + let config = session.read(cx).configuration(); let mut adapter_args = client.adapter().request_args(&config); if let Some(args) = config.initialize_args.clone() { merge_json_value_into(args, &mut adapter_args); @@ -920,7 +785,7 @@ impl DapStore { // comes in we send another `attach` request with the already selected PID // If we don't do this the user has to select the process twice if the adapter sends a `startDebugging` request session.update(cx, |session, cx| { - session.as_local_mut().unwrap().update_configuration( + session.update_configuration( |config| { config.request = DebugRequestType::Attach(task::AttachConfig { process_id: Some(process_id), @@ -930,7 +795,7 @@ impl DapStore { ); }); - let config = session.read(cx).as_local().unwrap().configuration(); + let config = session.read(cx).configuration(); let mut adapter_args = client.adapter().request_args(&config); if let Some(args) = config.initialize_args.clone() { @@ -1097,15 +962,8 @@ impl DapStore { ))); }; - let Some(config) = session - .read(cx) - .as_local() - .map(|session| session.configuration()) - else { - return Task::ready(Err(anyhow!("Cannot find debug session: {:?}", session_id))); - }; - let session_id = *session_id; + let config = session.read(cx).configuration().clone(); let request_args = args.unwrap_or_else(|| StartDebuggingRequestArguments { configuration: config.initialize_args.clone().unwrap_or_default(), @@ -1116,17 +974,17 @@ impl DapStore { }); // Merge the new configuration over the existing configuration - let mut initialize_args = config.initialize_args.clone().unwrap_or_default(); + let mut initialize_args = config.initialize_args.unwrap_or_default(); merge_json_value_into(request_args.configuration, &mut initialize_args); let new_config = DebugAdapterConfig { label: config.label.clone(), kind: config.kind.clone(), - request: match &request_args.request { + request: match request_args.request { StartDebuggingRequestArgumentsRequest::Launch => DebugRequestType::Launch, StartDebuggingRequestArgumentsRequest::Attach => DebugRequestType::Attach( - if let DebugRequestType::Attach(attach_config) = &config.request { - attach_config.clone() + if let DebugRequestType::Attach(attach_config) = config.request { + attach_config } else { AttachConfig::default() }, @@ -1664,27 +1522,11 @@ impl DapStore { return Task::ready(Err(anyhow!("Could not find session: {:?}", session_id))); }; - let Some(local_session) = session.read(cx).as_local() else { - return Task::ready(Err(anyhow!( - "Cannot shutdown session on remote side: {:?}", - session_id - ))); - }; - let mut tasks = Vec::new(); - for client in local_session.clients().collect::>() { + for client in session.read(cx).clients().collect::>() { tasks.push(self.shutdown_client(&session, client, cx)); } - if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() { - downstream_client - .send(proto::DebuggerSessionEnded { - project_id: *project_id, - session_id: session_id.to_proto(), - }) - .log_err(); - } - cx.background_executor().spawn(async move { futures::future::join_all(tasks).await; Ok(()) @@ -1746,13 +1588,11 @@ impl DapStore { debug_sessions: Vec, cx: &mut ModelContext, ) { - for session in debug_sessions.into_iter() { - let session_id = DebugSessionId::from_proto(session.session_id); - let ignore_breakpoints = Some(session.ignore_breakpoints); - - self.add_remote_session(session_id, ignore_breakpoints, cx); - - for debug_client in session.clients { + for (session_id, debug_clients) in debug_sessions + .into_iter() + .map(|session| (session.session_id, session.clients)) + { + for debug_client in debug_clients { if let DapStoreMode::Remote(remote) = &mut self.mode { if let Some(queue) = &mut remote.event_queue { debug_client.debug_panel_items.into_iter().for_each(|item| { @@ -1761,13 +1601,9 @@ impl DapStore { } } - let client = DebugAdapterClientId::from_proto(debug_client.client_id); - - self.add_client_to_session(session_id, client); - self.update_capabilities_for_client( - &session_id, - &client, + &DebugSessionId::from_proto(session_id), + &DebugAdapterClientId::from_proto(debug_client.client_id), &dap::proto_conversions::capabilities_from_proto( &debug_client.capabilities.unwrap_or_default(), ), @@ -1804,7 +1640,7 @@ impl DapStore { cx.notify(); } - async fn handle_shutdown_session_request( + async fn handle_shutdown_session( this: Model, envelope: TypedEnvelope, mut cx: AsyncAppContext, @@ -2092,11 +1928,8 @@ impl DapStore { .collect::>(); let mut tasks = Vec::new(); - for session in local_store - .sessions - .values() - .filter_map(|session| session.read(cx).as_local()) - { + for session in local_store.sessions.values() { + let session = session.read(cx); let ignore_breakpoints = self.ignore_breakpoints(&session.id(), cx); for client in session.clients().collect::>() { tasks.push(self.send_breakpoints( diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 8f7ae15f0d73e1..74da6fb446b00a 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -634,8 +634,6 @@ impl Project { client.add_model_request_handler(WorktreeStore::handle_rename_project_entry); - client.add_model_message_handler(Self::handle_toggle_ignore_breakpoints); - WorktreeStore::init(&client); BufferStore::init(&client); LspStore::init(&client); @@ -1398,26 +1396,6 @@ impl Project { result } - async fn handle_toggle_ignore_breakpoints( - this: Model, - envelope: TypedEnvelope, - mut cx: AsyncAppContext, - ) -> Result<()> { - this.update(&mut cx, |project, cx| { - // Only the host should handle this message because the host - // handles direct communication with the debugger servers. - if let Some((_, _)) = project.dap_store.read(cx).downstream_client() { - project - .toggle_ignore_breakpoints( - &DebugSessionId::from_proto(envelope.payload.session_id), - &DebugAdapterClientId::from_proto(envelope.payload.client_id), - cx, - ) - .detach_and_log_err(cx); - } - }) - } - pub fn toggle_ignore_breakpoints( &self, session_id: &DebugSessionId, @@ -1425,30 +1403,8 @@ impl Project { cx: &mut ModelContext, ) -> Task> { let tasks = self.dap_store.update(cx, |store, cx| { - if let Some((upstream_client, project_id)) = store.upstream_client() { - upstream_client - .send(proto::ToggleIgnoreBreakpoints { - session_id: session_id.to_proto(), - client_id: client_id.to_proto(), - project_id, - }) - .log_err(); - - return Vec::new(); - } - store.toggle_ignore_breakpoints(session_id, cx); - if let Some((downstream_client, project_id)) = store.downstream_client() { - downstream_client - .send(proto::IgnoreBreakpointState { - session_id: session_id.to_proto(), - project_id: *project_id, - ignore: store.ignore_breakpoints(session_id, cx), - }) - .log_err(); - } - let mut tasks = Vec::new(); for (project_path, breakpoints) in store.breakpoints() { diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index b6e6690d601b3a..52426ac69e882d 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -331,10 +331,7 @@ message Envelope { UpdateThreadStatus update_thread_status = 310; VariablesRequest variables_request = 311; DapVariables dap_variables = 312; - DapRestartStackFrameRequest dap_restart_stack_frame_request = 313; - IgnoreBreakpointState ignore_breakpoint_state = 314; - ToggleIgnoreBreakpoints toggle_ignore_breakpoints = 315; - DebuggerSessionEnded debugger_session_ended = 316; // current max + DapRestartStackFrameRequest dap_restart_stack_frame_request = 313; // current max } reserved 87 to 88; @@ -2474,16 +2471,10 @@ enum BreakpointKind { Log = 1; } -message DebuggerSessionEnded { - uint64 project_id = 1; - uint64 session_id = 2; -} - message DebuggerSession { uint64 session_id = 1; uint64 project_id = 2; - bool ignore_breakpoints = 3; - repeated DebugClient clients = 4; + repeated DebugClient clients = 3; } message DebugClient { @@ -2718,18 +2709,6 @@ message DapShutdownSession { optional uint64 session_id = 2; // Shutdown all sessions if this is None } -message ToggleIgnoreBreakpoints { - uint64 project_id = 1; - uint64 client_id = 2; - uint64 session_id = 3; -} - -message IgnoreBreakpointState { - uint64 project_id = 1; - uint64 session_id = 2; - bool ignore = 3; -} - message DapNextRequest { uint64 project_id = 1; uint64 client_id = 2; diff --git a/crates/proto/src/proto.rs b/crates/proto/src/proto.rs index a79bcf08183941..0af3cbaf4cb548 100644 --- a/crates/proto/src/proto.rs +++ b/crates/proto/src/proto.rs @@ -397,9 +397,6 @@ messages!( (UsersResponse, Foreground), (VariablesRequest, Background), (DapVariables, Background), - (IgnoreBreakpointState, Background), - (ToggleIgnoreBreakpoints, Background), - (DebuggerSessionEnded, Background), ); request_messages!( @@ -647,9 +644,6 @@ entity_messages!( DapShutdownSession, UpdateThreadStatus, VariablesRequest, - IgnoreBreakpointState, - ToggleIgnoreBreakpoints, - DebuggerSessionEnded, ); entity_messages!(