diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 753e591914f45e..a985c97ac5afd7 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -441,15 +441,17 @@ impl Server { .add_request_handler(forward_read_only_project_request::) .add_request_handler(forward_read_only_project_request::) .add_request_handler(forward_mutating_project_request::) - .add_request_handler(forward_mutating_project_request::) - .add_message_handler(broadcast_project_message_from_host::) .add_request_handler(forward_mutating_project_request::) .add_request_handler(forward_mutating_project_request::) .add_request_handler(forward_mutating_project_request::) .add_request_handler(forward_mutating_project_request::) .add_request_handler(forward_mutating_project_request::) .add_message_handler(broadcast_project_message_from_host::) - .add_message_handler(update_context); + .add_message_handler(update_context) + .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(broadcast_project_message_from_host::); Arc::new(server) } diff --git a/crates/dap/src/proto_conversions.rs b/crates/dap/src/proto_conversions.rs index 7b7324644b3b91..383c54ec58b8c6 100644 --- a/crates/dap/src/proto_conversions.rs +++ b/crates/dap/src/proto_conversions.rs @@ -1,7 +1,8 @@ use anyhow::{Context as _, Result}; use client::proto::{ - self, DapChecksum, DapChecksumAlgorithm, DapEvaluateContext, DapModule, DapScope, - DapScopePresentationHint, DapSource, DapSourcePresentationHint, DapStackFrame, DapVariable, + self, BreakpointMode, BreakpointModeApplicability, Capabilities, DapChecksum, + DapChecksumAlgorithm, DapEvaluateContext, DapModule, DapScope, DapScopePresentationHint, + DapSource, DapSourcePresentationHint, DapStackFrame, DapVariable, ExceptionBreakpointsFilter, }; use dap_types::{OutputEventCategory, OutputEventGroup, ScopePresentationHint, Source}; @@ -120,7 +121,7 @@ impl ProtoConversion for dap_types::ScopePresentationHint { dap_types::ScopePresentationHint::Registers => DapScopePresentationHint::Registers, dap_types::ScopePresentationHint::ReturnValue => DapScopePresentationHint::ReturnValue, dap_types::ScopePresentationHint::Unknown => DapScopePresentationHint::ScopeUnknown, - &_ => unreachable!(), + _ => unreachable!(), } } @@ -361,11 +362,13 @@ impl ProtoConversion for dap_types::OutputEventCategory { fn to_proto(&self) -> Self::ProtoType { match self { - Self::Console => proto::DapOutputCategory::ConsoleOutput, - Self::Important => proto::DapOutputCategory::Important, - Self::Stdout => proto::DapOutputCategory::Stdout, - Self::Stderr => proto::DapOutputCategory::Stderr, - _ => proto::DapOutputCategory::Unknown, + OutputEventCategory::Console => proto::DapOutputCategory::ConsoleOutput, + OutputEventCategory::Important => proto::DapOutputCategory::Important, + OutputEventCategory::Stdout => proto::DapOutputCategory::Stdout, + OutputEventCategory::Stderr => proto::DapOutputCategory::Stderr, + OutputEventCategory::Unknown => proto::DapOutputCategory::Unknown, + OutputEventCategory::Telemetry => proto::DapOutputCategory::Telemetry, + _ => unreachable!(), } } @@ -376,6 +379,7 @@ impl ProtoConversion for dap_types::OutputEventCategory { proto::DapOutputCategory::Stdout => Self::Stdout, proto::DapOutputCategory::Stderr => Self::Stderr, proto::DapOutputCategory::Unknown => Self::Unknown, + proto::DapOutputCategory::Telemetry => Self::Telemetry, } } } @@ -498,7 +502,7 @@ impl ProtoConversion for dap_types::EvaluateArgumentsContext { dap_types::EvaluateArgumentsContext::Unknown => { proto::DapEvaluateContext::EvaluateUnknown } - _ => proto::DapEvaluateContext::EvaluateUnknown, + _ => unreachable!(), } } @@ -589,3 +593,435 @@ impl ProtoConversion for dap_types::Thread { } } } + +impl ProtoConversion for dap_types::ExceptionBreakMode { + type ProtoType = proto::ExceptionBreakMode; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + match self { + dap_types::ExceptionBreakMode::Never => proto::ExceptionBreakMode::Never, + dap_types::ExceptionBreakMode::Always => proto::ExceptionBreakMode::Always, + dap_types::ExceptionBreakMode::Unhandled => proto::ExceptionBreakMode::Unhandled, + dap_types::ExceptionBreakMode::UserUnhandled => { + proto::ExceptionBreakMode::AlwaysUnhandled + } + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + match payload { + proto::ExceptionBreakMode::Never => dap_types::ExceptionBreakMode::Never, + proto::ExceptionBreakMode::Always => dap_types::ExceptionBreakMode::Always, + proto::ExceptionBreakMode::Unhandled => dap_types::ExceptionBreakMode::Unhandled, + proto::ExceptionBreakMode::AlwaysUnhandled => { + dap_types::ExceptionBreakMode::UserUnhandled + } + } + } +} + +impl ProtoConversion for dap_types::ExceptionPathSegment { + type ProtoType = proto::ExceptionPathSegment; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + proto::ExceptionPathSegment { + negate: self.negate, + names: self.names.clone(), + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + Self { + negate: payload.negate, + names: payload.names, + } + } +} + +impl ProtoConversion for dap_types::ExceptionOptions { + type ProtoType = proto::ExceptionOptions; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + proto::ExceptionOptions { + path: self.path.as_ref().map(|p| p.to_proto()).unwrap_or_default(), + break_mode: self.break_mode.to_proto() as i32, + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + Self { + path: if payload.path.is_empty() { + None + } else { + Some( + payload + .path + .into_iter() + .map(dap_types::ExceptionPathSegment::from_proto) + .collect(), + ) + }, + break_mode: match payload.break_mode { + 0 => dap_types::ExceptionBreakMode::Never, + 1 => dap_types::ExceptionBreakMode::Always, + 2 => dap_types::ExceptionBreakMode::Unhandled, + 3 => dap_types::ExceptionBreakMode::UserUnhandled, + _ => dap_types::ExceptionBreakMode::Never, + }, + } + } +} + +impl ProtoConversion for dap_types::ExceptionFilterOptions { + type ProtoType = proto::ExceptionFilterOptions; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + proto::ExceptionFilterOptions { + filter_id: self.filter_id.clone(), + condition: self.condition.clone(), + mode: self.mode.clone(), + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + Self { + filter_id: payload.filter_id, + condition: payload.condition, + mode: payload.mode, + } + } +} + +impl ProtoConversion for dap_types::BreakpointReason { + type ProtoType = proto::DapBreakpointReason; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + match self { + dap_types::BreakpointReason::Pending => proto::DapBreakpointReason::Pending, + dap_types::BreakpointReason::Failed => proto::DapBreakpointReason::Failed, + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + match payload { + proto::DapBreakpointReason::Pending => dap_types::BreakpointReason::Pending, + proto::DapBreakpointReason::Failed => dap_types::BreakpointReason::Failed, + } + } +} + +impl ProtoConversion for dap_types::Breakpoint { + type ProtoType = proto::DapBreakpoint; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + proto::DapBreakpoint { + id: self.id.map(|id| id as i64), + verified: self.verified, + message: self.message.clone(), + source: self.source.as_ref().map(|source| source.to_proto()), + line: self.line.map(|line| line as u32), + column: self.column.map(|column| column as u32), + end_line: self.end_line.map(|line| line as u32), + end_column: self.end_column.map(|column| column as u32), + instruction_reference: self.instruction_reference.clone(), + offset: self.offset.map(|offset| offset as u32), + reason: self.reason.as_ref().map(|reason| reason.to_proto() as i32), + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + Self { + id: payload.id.map(|id| id as u64), + verified: payload.verified, + message: payload.message, + source: payload.source.map(dap_types::Source::from_proto), + line: payload.line.map(|line| line as u64), + column: payload.column.map(|column| column as u64), + end_line: payload.end_line.map(|line| line as u64), + end_column: payload.end_column.map(|column| column as u64), + instruction_reference: payload.instruction_reference, + offset: payload.offset.map(|offset| offset as u64), + reason: payload.reason.and_then(|reason| match reason { + 0 => Some(dap_types::BreakpointReason::Pending), + 1 => Some(dap_types::BreakpointReason::Failed), + _ => None, + }), + } + } +} + +impl ProtoConversion for dap_types::BreakpointModeApplicability { + type ProtoType = BreakpointModeApplicability; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + match self { + dap_types::BreakpointModeApplicability::Source => BreakpointModeApplicability::Source, + dap_types::BreakpointModeApplicability::Exception => { + BreakpointModeApplicability::Exception + } + dap_types::BreakpointModeApplicability::Data => BreakpointModeApplicability::Data, + dap_types::BreakpointModeApplicability::Instruction => { + BreakpointModeApplicability::InstructionBreakpoint + } + dap_types::BreakpointModeApplicability::Unknown => { + BreakpointModeApplicability::BreakpointModeUnknown + } + _ => unreachable!(), + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + match payload { + BreakpointModeApplicability::Source => dap_types::BreakpointModeApplicability::Source, + BreakpointModeApplicability::Exception => { + dap_types::BreakpointModeApplicability::Exception + } + BreakpointModeApplicability::Data => dap_types::BreakpointModeApplicability::Data, + BreakpointModeApplicability::InstructionBreakpoint => { + dap_types::BreakpointModeApplicability::Instruction + } + BreakpointModeApplicability::BreakpointModeUnknown => { + dap_types::BreakpointModeApplicability::Unknown + } + } + } +} + +impl ProtoConversion for dap_types::BreakpointMode { + type ProtoType = BreakpointMode; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + BreakpointMode { + mode: self.mode.clone(), + label: self.label.clone(), + description: self.description.clone(), + applies_to: self + .applies_to + .iter() + .map(|a| a.to_proto() as i32) + .collect(), + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + Self { + mode: payload.mode, + label: payload.label, + description: payload.description, + applies_to: payload + .applies_to + .into_iter() + .filter_map(BreakpointModeApplicability::from_i32) + .map(dap_types::BreakpointModeApplicability::from_proto) + .collect(), + } + } +} + +impl ProtoConversion for dap_types::ExceptionBreakpointsFilter { + type ProtoType = ExceptionBreakpointsFilter; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + ExceptionBreakpointsFilter { + filter: self.filter.clone(), + label: self.label.clone(), + description: self.description.clone(), + default_value: self.default, + supports_condition: self.supports_condition, + condition_description: self.condition_description.clone(), + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + Self { + filter: payload.filter, + label: payload.label, + description: payload.description, + default: payload.default_value, + supports_condition: payload.supports_condition, + condition_description: payload.condition_description, + } + } +} + +impl ProtoConversion for dap_types::Capabilities { + type ProtoType = Capabilities; + type Output = Self; + + fn to_proto(&self) -> Self::ProtoType { + Capabilities { + supports_configuration_done_request: self.supports_configuration_done_request, + supports_function_breakpoints: self.supports_function_breakpoints, + supports_conditional_breakpoints: self.supports_conditional_breakpoints, + supports_hit_conditional_breakpoints: self.supports_hit_conditional_breakpoints, + supports_evaluate_for_hovers: self.supports_evaluate_for_hovers, + exception_breakpoint_filters: self + .exception_breakpoint_filters + .as_ref() + .map(|filters| filters.to_proto()) + .unwrap_or_default(), + supports_step_back: self.supports_step_back, + supports_set_variable: self.supports_set_variable, + supports_restart_frame: self.supports_restart_frame, + supports_goto_targets_request: self.supports_goto_targets_request, + supports_step_in_targets_request: self.supports_step_in_targets_request, + supports_completions_request: self.supports_completions_request, + completion_trigger_characters: self + .completion_trigger_characters + .clone() + .unwrap_or_default(), + supports_modules_request: self.supports_modules_request, + additional_module_columns: self + .additional_module_columns + .as_ref() + .map(|columns| { + columns + .iter() + .map(|col| col.attribute_name.clone()) + .collect() + }) + .unwrap_or_default(), + supported_checksum_algorithms: self + .supported_checksum_algorithms + .as_ref() + .map(|algorithms| algorithms.iter().map(|alg| format!("{:?}", alg)).collect()) + .unwrap_or_default(), + supports_restart_request: self.supports_restart_request, + supports_exception_options: self.supports_exception_options, + supports_value_formatting_options: self.supports_value_formatting_options, + supports_exception_info_request: self.supports_exception_info_request, + support_terminate_debuggee: self.support_terminate_debuggee, + support_suspend_debuggee: self.support_suspend_debuggee, + supports_delayed_stack_trace_loading: self.supports_delayed_stack_trace_loading, + supports_loaded_sources_request: self.supports_loaded_sources_request, + supports_log_points: self.supports_log_points, + supports_terminate_threads_request: self.supports_terminate_threads_request, + supports_set_expression: self.supports_set_expression, + supports_terminate_request: self.supports_terminate_request, + supports_data_breakpoints: self.supports_data_breakpoints, + supports_read_memory_request: self.supports_read_memory_request, + supports_write_memory_request: self.supports_write_memory_request, + supports_disassemble_request: self.supports_disassemble_request, + supports_cancel_request: self.supports_cancel_request, + supports_breakpoint_locations_request: self.supports_breakpoint_locations_request, + supports_clipboard_context: self.supports_clipboard_context, + supports_stepping_granularity: self.supports_stepping_granularity, + supports_instruction_breakpoints: self.supports_instruction_breakpoints, + supports_exception_filter_options: self.supports_exception_filter_options, + supports_single_thread_execution_requests: self + .supports_single_thread_execution_requests, + supports_data_breakpoint_bytes: self.supports_data_breakpoint_bytes, + breakpoint_modes: self + .breakpoint_modes + .as_ref() + .map(|modes| modes.to_proto()) + .unwrap_or_default(), + supports_ansistyling: self.supports_ansistyling, + } + } + + fn from_proto(payload: Self::ProtoType) -> Self { + Self { + supports_configuration_done_request: payload.supports_configuration_done_request, + supports_function_breakpoints: payload.supports_function_breakpoints, + supports_conditional_breakpoints: payload.supports_conditional_breakpoints, + supports_hit_conditional_breakpoints: payload.supports_hit_conditional_breakpoints, + supports_evaluate_for_hovers: payload.supports_evaluate_for_hovers, + exception_breakpoint_filters: if payload.exception_breakpoint_filters.is_empty() { + None + } else { + Some(Vec::::from_proto( + payload.exception_breakpoint_filters, + )) + }, + supports_step_back: payload.supports_step_back, + supports_set_variable: payload.supports_set_variable, + supports_restart_frame: payload.supports_restart_frame, + supports_goto_targets_request: payload.supports_goto_targets_request, + supports_step_in_targets_request: payload.supports_step_in_targets_request, + supports_completions_request: payload.supports_completions_request, + completion_trigger_characters: if payload.completion_trigger_characters.is_empty() { + None + } else { + Some(payload.completion_trigger_characters) + }, + supports_modules_request: payload.supports_modules_request, + additional_module_columns: if payload.additional_module_columns.is_empty() { + None + } else { + Some( + payload + .additional_module_columns + .into_iter() + .map(|name| dap_types::ColumnDescriptor { + attribute_name: name, + label: String::new(), + format: None, + type_: None, + width: None, + }) + .collect(), + ) + }, + supported_checksum_algorithms: if payload.supported_checksum_algorithms.is_empty() { + None + } else { + Some( + payload + .supported_checksum_algorithms + .into_iter() + .filter_map(|alg| match alg.as_str() { + "Md5" => Some(dap_types::ChecksumAlgorithm::Md5), + "Sha1" => Some(dap_types::ChecksumAlgorithm::Sha1), + "Sha256" => Some(dap_types::ChecksumAlgorithm::Sha256), + "Timestamp" => Some(dap_types::ChecksumAlgorithm::Timestamp), + _ => None, + }) + .collect(), + ) + }, + supports_restart_request: payload.supports_restart_request, + supports_exception_options: payload.supports_exception_options, + supports_value_formatting_options: payload.supports_value_formatting_options, + supports_exception_info_request: payload.supports_exception_info_request, + support_terminate_debuggee: payload.support_terminate_debuggee, + support_suspend_debuggee: payload.support_suspend_debuggee, + supports_delayed_stack_trace_loading: payload.supports_delayed_stack_trace_loading, + supports_loaded_sources_request: payload.supports_loaded_sources_request, + supports_log_points: payload.supports_log_points, + supports_terminate_threads_request: payload.supports_terminate_threads_request, + supports_set_expression: payload.supports_set_expression, + supports_terminate_request: payload.supports_terminate_request, + supports_data_breakpoints: payload.supports_data_breakpoints, + supports_read_memory_request: payload.supports_read_memory_request, + supports_write_memory_request: payload.supports_write_memory_request, + supports_disassemble_request: payload.supports_disassemble_request, + supports_cancel_request: payload.supports_cancel_request, + supports_breakpoint_locations_request: payload.supports_breakpoint_locations_request, + supports_clipboard_context: payload.supports_clipboard_context, + supports_stepping_granularity: payload.supports_stepping_granularity, + supports_instruction_breakpoints: payload.supports_instruction_breakpoints, + supports_exception_filter_options: payload.supports_exception_filter_options, + supports_single_thread_execution_requests: payload + .supports_single_thread_execution_requests, + supports_data_breakpoint_bytes: payload.supports_data_breakpoint_bytes, + breakpoint_modes: if payload.breakpoint_modes.is_empty() { + None + } else { + Some(Vec::::from_proto( + payload.breakpoint_modes, + )) + }, + supports_ansistyling: payload.supports_ansistyling, + } + } +} diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index d03e8c5225f04f..839785f99c5e17 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -71,7 +71,7 @@ pub struct DebugPanel { pub(crate) session_picker_menu_handle: PopoverMenuHandle, fs: Arc, is_zoomed: bool, - _subscriptions: [Subscription; 1], + _subscriptions: Vec, breakpoint_list: Entity, } @@ -87,13 +87,41 @@ impl DebugPanel { let thread_picker_menu_handle = PopoverMenuHandle::default(); let session_picker_menu_handle = PopoverMenuHandle::default(); - let focus_subscription = cx.on_focus( - &focus_handle, - window, - |this: &mut DebugPanel, window, cx| { - this.focus_active_item(window, cx); - }, - ); + let _subscriptions = vec![ + cx.on_focus( + &focus_handle, + window, + |this: &mut DebugPanel, window, cx| { + this.focus_active_item(window, cx); + }, + ), + cx.subscribe_in( + &project.read(cx).dap_store(), + window, + |debug_panel, dap_store, event, window, cx| match event { + project::debugger::dap_store::DapStoreEvent::DebugClientStarted( + session_id, + ) => { + cx.notify(); + let has_session = debug_panel + .sessions + .iter() + .any(|session| session.read(cx).session_id(cx) == *session_id); + dbg!(has_session, debug_panel.sessions.len()); + if let Some(session) = dap_store.read(cx).session_by_id(session_id) { + cx.spawn_in(window, async move |this, cx| { + Self::register_session(this.clone(), session.clone(), true, cx) + .await?; + + anyhow::Ok(()) + }) + .detach(); + } + } + _ => {} + }, + ), + ]; Self { size: px(300.), @@ -114,7 +142,7 @@ impl DebugPanel { thread_picker_menu_handle, session_picker_menu_handle, is_zoomed: false, - _subscriptions: [focus_subscription], + _subscriptions, debug_scenario_scheduled_last: true, } }) diff --git a/crates/debugger_ui/src/session.rs b/crates/debugger_ui/src/session.rs index 482297b13671a9..7a1c0051419b6c 100644 --- a/crates/debugger_ui/src/session.rs +++ b/crates/debugger_ui/src/session.rs @@ -192,18 +192,31 @@ impl FollowableItem for DebugSession { self.remote_id } - fn to_state_proto(&self, _window: &Window, _cx: &App) -> Option { - None + fn to_state_proto(&self, _window: &Window, cx: &App) -> Option { + let session_id = self.running_state.read(cx).session_id().to_proto(); + + dbg!("here"); + + Some(proto::view::Variant::DebugSession( + proto::view::DebugSession { session_id }, + )) } fn from_state_proto( _workspace: Entity, _remote_id: ViewId, - _state: &mut Option, + state: &mut Option, _window: &mut Window, _cx: &mut App, ) -> Option>>> { - None + let proto::view::Variant::DebugSession(_) = state.as_ref()? else { + return None; + }; + let Some(proto::view::Variant::DebugSession(_state)) = state.take() else { + unreachable!() + }; + + todo!() } fn add_event_to_update_proto( @@ -225,6 +238,7 @@ impl FollowableItem for DebugSession { _window: &mut Window, _cx: &mut Context, ) -> gpui::Task> { + dbg!("here"); Task::ready(Ok(())) } diff --git a/crates/project/src/debugger/dap_command.rs b/crates/project/src/debugger/dap_command.rs index 735444b3f31f64..17391aeecd7894 100644 --- a/crates/project/src/debugger/dap_command.rs +++ b/crates/project/src/debugger/dap_command.rs @@ -2,10 +2,10 @@ use std::sync::Arc; use anyhow::{Context as _, Ok, Result}; use dap::{ - Capabilities, ContinueArguments, ExceptionFilterOptions, InitializeRequestArguments, - InitializeRequestArgumentsPathFormat, NextArguments, SetVariableResponse, SourceBreakpoint, - StepInArguments, StepOutArguments, SteppingGranularity, ValueFormat, Variable, - VariablesArgumentsFilter, + Breakpoint, Capabilities, ContinueArguments, ExceptionFilterOptions, ExceptionOptions, + InitializeRequestArguments, InitializeRequestArgumentsPathFormat, NextArguments, + SetVariableResponse, SourceBreakpoint, StepInArguments, StepOutArguments, SteppingGranularity, + ValueFormat, Variable, VariablesArgumentsFilter, client::SessionId, proto_conversions::ProtoConversion, requests::{Continue, Next}, @@ -31,27 +31,22 @@ pub trait LocalDapCommand: 'static + Send + Sync + std::fmt::Debug { } pub trait DapCommand: LocalDapCommand { - type ProtoRequest: 'static + Send; + type ProtoRequest: 'static + Send + proto::RequestMessage; type ProtoResponse: 'static + Send; const CACHEABLE: bool = false; - #[allow(dead_code)] - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId; + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId; - #[allow(dead_code)] fn from_proto(request: &Self::ProtoRequest) -> Self; - #[allow(unused)] - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest; + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest; - #[allow(dead_code)] - fn response_to_proto( - debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse; + fn response_to_proto(session_id: SessionId, message: Self::Response) -> Self::ProtoResponse; - #[allow(unused)] - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result; + fn response_from_proto( + &self, + message: ::Response, + ) -> Result; } impl LocalDapCommand for Arc { @@ -78,26 +73,26 @@ impl DapCommand for Arc { type ProtoRequest = T::ProtoRequest; type ProtoResponse = T::ProtoResponse; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - T::client_id_from_proto(request) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + T::session_id_from_proto(request) } fn from_proto(request: &Self::ProtoRequest) -> Self { Arc::new(T::from_proto(request)) } - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { - T::to_proto(self, debug_client_id, upstream_project_id) + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + T::to_proto(self, session_id, upstream_project_id) } - fn response_to_proto( - debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { - T::response_to_proto(debug_client_id, message) + fn response_to_proto(session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { + T::response_to_proto(session_id, message) } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { T::response_from_proto(self, message) } } @@ -156,8 +151,8 @@ impl DapCommand for NextCommand { type ProtoRequest = proto::DapNextRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -166,28 +161,24 @@ impl DapCommand for NextCommand { } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn to_proto( - &self, - debug_client_id: SessionId, - upstream_project_id: u64, - ) -> proto::DapNextRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> proto::DapNextRequest { proto::DapNextRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_id: self.inner.thread_id, single_thread: self.inner.single_thread, granularity: self.inner.granularity.map(|gran| gran.to_proto() as i32), } } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -222,15 +213,15 @@ impl DapCommand for StepInCommand { type ProtoRequest = proto::DapStepInRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { Self { inner: StepCommand::from_proto(proto::DapNextRequest { project_id: request.project_id, - client_id: request.client_id, + session_id: request.session_id, thread_id: request.thread_id, single_thread: request.single_thread, granularity: request.granularity, @@ -238,21 +229,14 @@ impl DapCommand for StepInCommand { } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn to_proto( - &self, - debug_client_id: SessionId, - upstream_project_id: u64, - ) -> proto::DapStepInRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> proto::DapStepInRequest { proto::DapStepInRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_id: self.inner.thread_id, single_thread: self.inner.single_thread, granularity: self.inner.granularity.map(|gran| gran.to_proto() as i32), @@ -260,7 +244,10 @@ impl DapCommand for StepInCommand { } } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -294,15 +281,15 @@ impl DapCommand for StepOutCommand { type ProtoRequest = proto::DapStepOutRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { Self { inner: StepCommand::from_proto(proto::DapNextRequest { project_id: request.project_id, - client_id: request.client_id, + session_id: request.session_id, thread_id: request.thread_id, single_thread: request.single_thread, granularity: request.granularity, @@ -310,28 +297,28 @@ impl DapCommand for StepOutCommand { } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapStepOutRequest { proto::DapStepOutRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_id: self.inner.thread_id, single_thread: self.inner.single_thread, granularity: self.inner.granularity.map(|gran| gran.to_proto() as i32), } } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -368,15 +355,15 @@ impl DapCommand for StepBackCommand { type ProtoRequest = proto::DapStepBackRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { Self { inner: StepCommand::from_proto(proto::DapNextRequest { project_id: request.project_id, - client_id: request.client_id, + session_id: request.session_id, thread_id: request.thread_id, single_thread: request.single_thread, granularity: request.granularity, @@ -384,28 +371,28 @@ impl DapCommand for StepBackCommand { } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapStepBackRequest { proto::DapStepBackRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_id: self.inner.thread_id, single_thread: self.inner.single_thread, granularity: self.inner.granularity.map(|gran| gran.to_proto() as i32), } } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -435,18 +422,18 @@ impl DapCommand for ContinueCommand { type ProtoRequest = proto::DapContinueRequest; type ProtoResponse = proto::DapContinueResponse; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapContinueRequest { proto::DapContinueRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_id: self.args.thread_id, single_thread: self.args.single_thread, } @@ -461,18 +448,18 @@ impl DapCommand for ContinueCommand { } } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(Self::Response { all_threads_continued: message.all_threads_continued, }) } - fn response_to_proto( - debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapContinueResponse { - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), all_threads_continued: message.all_threads_continued, } } @@ -504,8 +491,8 @@ impl DapCommand for PauseCommand { type ProtoRequest = proto::DapPauseRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -514,26 +501,22 @@ impl DapCommand for PauseCommand { } } - fn to_proto( - &self, - debug_client_id: SessionId, - upstream_project_id: u64, - ) -> proto::DapPauseRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> proto::DapPauseRequest { proto::DapPauseRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_id: self.thread_id, } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -569,8 +552,8 @@ impl DapCommand for DisconnectCommand { type ProtoRequest = proto::DapDisconnectRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -583,26 +566,26 @@ impl DapCommand for DisconnectCommand { fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapDisconnectRequest { proto::DapDisconnectRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), restart: self.restart, terminate_debuggee: self.terminate_debuggee, suspend_debuggee: self.suspend_debuggee, } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -640,8 +623,8 @@ impl DapCommand for TerminateThreadsCommand { type ProtoRequest = proto::DapTerminateThreadsRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -656,24 +639,24 @@ impl DapCommand for TerminateThreadsCommand { fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapTerminateThreadsRequest { proto::DapTerminateThreadsRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_ids: self.thread_ids.clone().unwrap_or_default(), } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -708,8 +691,8 @@ impl DapCommand for TerminateCommand { type ProtoRequest = proto::DapTerminateRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -720,24 +703,24 @@ impl DapCommand for TerminateCommand { fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapTerminateRequest { proto::DapTerminateRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), restart: self.restart, } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -773,8 +756,8 @@ impl DapCommand for RestartCommand { type ProtoRequest = proto::DapRestartRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -787,26 +770,26 @@ impl DapCommand for RestartCommand { fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapRestartRequest { let raw_args = serde_json::to_vec(&self.raw).log_err().unwrap_or_default(); proto::DapRestartRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), raw_args, } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -843,18 +826,18 @@ impl LocalDapCommand for VariablesCommand { } impl DapCommand for VariablesCommand { - type ProtoRequest = proto::VariablesRequest; - type ProtoResponse = proto::DapVariables; + type ProtoRequest = proto::DapVariablesRequest; + type ProtoResponse = proto::DapVariablesResponse; const CACHEABLE: bool = true; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { - proto::VariablesRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + proto::DapVariablesRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), variables_reference: self.variables_reference, filter: None, start: self.start, @@ -873,17 +856,17 @@ impl DapCommand for VariablesCommand { } } - fn response_to_proto( - debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { - proto::DapVariables { - client_id: debug_client_id.to_proto(), + fn response_to_proto(session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { + proto::DapVariablesResponse { + session_id: session_id.to_proto(), variables: message.to_proto(), } } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(Vec::from_proto(message.variables)) } } @@ -920,14 +903,14 @@ impl DapCommand for SetVariableValueCommand { type ProtoRequest = proto::DapSetVariableValueRequest; type ProtoResponse = proto::DapSetVariableValueResponse; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { proto::DapSetVariableValueRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), variables_reference: self.variables_reference, value: self.value.clone(), name: self.name.clone(), @@ -942,12 +925,9 @@ impl DapCommand for SetVariableValueCommand { } } - fn response_to_proto( - debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapSetVariableValueResponse { - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), value: message.value, variable_type: message.type_, named_variables: message.named_variables, @@ -957,7 +937,10 @@ impl DapCommand for SetVariableValueCommand { } } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(SetVariableResponse { value: message.value, type_: message.variable_type, @@ -1001,8 +984,8 @@ impl DapCommand for RestartStackFrameCommand { type ProtoRequest = proto::DapRestartStackFrameRequest; type ProtoResponse = proto::Ack; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -1013,24 +996,24 @@ impl DapCommand for RestartStackFrameCommand { fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapRestartStackFrameRequest { proto::DapRestartStackFrameRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), stack_frame_id: self.stack_frame_id, } } - fn response_to_proto( - _debug_client_id: SessionId, - _message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, _message: Self::Response) -> Self::ProtoResponse { proto::Ack {} } - fn response_from_proto(&self, _message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + _message: ::Response, + ) -> Result { Ok(()) } } @@ -1066,8 +1049,8 @@ impl DapCommand for ModulesCommand { type ProtoResponse = proto::DapModulesResponse; const CACHEABLE: bool = true; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(_request: &Self::ProtoRequest) -> Self { @@ -1076,29 +1059,29 @@ impl DapCommand for ModulesCommand { fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapModulesRequest { proto::DapModulesRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), } } - fn response_to_proto( - debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapModulesResponse { modules: message .into_iter() .map(|module| module.to_proto()) .collect(), - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), } } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(message .modules .into_iter() @@ -1136,8 +1119,8 @@ impl DapCommand for LoadedSourcesCommand { type ProtoResponse = proto::DapLoadedSourcesResponse; const CACHEABLE: bool = true; - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(_request: &Self::ProtoRequest) -> Self { @@ -1146,29 +1129,29 @@ impl DapCommand for LoadedSourcesCommand { fn to_proto( &self, - debug_client_id: SessionId, + session_id: SessionId, upstream_project_id: u64, ) -> proto::DapLoadedSourcesRequest { proto::DapLoadedSourcesRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), } } - fn response_to_proto( - debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapLoadedSourcesResponse { sources: message .into_iter() .map(|source| source.to_proto()) .collect(), - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), } } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(message .sources .into_iter() @@ -1210,10 +1193,10 @@ impl DapCommand for StackTraceCommand { type ProtoResponse = proto::DapStackTraceResponse; const CACHEABLE: bool = true; - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { proto::DapStackTraceRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), thread_id: self.thread_id, start_frame: self.start_frame, stack_trace_levels: self.levels, @@ -1228,11 +1211,14 @@ impl DapCommand for StackTraceCommand { } } - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(message .frames .into_iter() @@ -1240,10 +1226,7 @@ impl DapCommand for StackTraceCommand { .collect()) } - fn response_to_proto( - _debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapStackTraceResponse { frames: message.to_proto(), } @@ -1278,10 +1261,10 @@ impl DapCommand for ScopesCommand { type ProtoResponse = proto::DapScopesResponse; const CACHEABLE: bool = true; - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { proto::DapScopesRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), stack_frame_id: self.stack_frame_id, } } @@ -1292,18 +1275,18 @@ impl DapCommand for ScopesCommand { } } - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(Vec::from_proto(message.scopes)) } - fn response_to_proto( - _debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapScopesResponse { scopes: message.to_proto(), } @@ -1342,9 +1325,9 @@ impl DapCommand for super::session::CompletionsQuery { type ProtoResponse = proto::DapCompletionResponse; const CACHEABLE: bool = true; - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { proto::DapCompletionRequest { - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), project_id: upstream_project_id, frame_id: self.frame_id, query: self.query.clone(), @@ -1353,8 +1336,8 @@ impl DapCommand for super::session::CompletionsQuery { } } - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -1366,18 +1349,18 @@ impl DapCommand for super::session::CompletionsQuery { } } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(dap::CompletionsResponse { targets: Vec::from_proto(message.completions), }) } - fn response_to_proto( - _debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapCompletionResponse { - client_id: _debug_client_id.to_proto(), + session_id: _session_id.to_proto(), completions: message.targets.to_proto(), } } @@ -1417,9 +1400,9 @@ impl DapCommand for EvaluateCommand { type ProtoRequest = proto::DapEvaluateRequest; type ProtoResponse = proto::DapEvaluateResponse; - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { proto::DapEvaluateRequest { - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), project_id: upstream_project_id, expression: self.expression.clone(), frame_id: self.frame_id, @@ -1430,8 +1413,8 @@ impl DapCommand for EvaluateCommand { } } - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } fn from_proto(request: &Self::ProtoRequest) -> Self { @@ -1443,7 +1426,10 @@ impl DapCommand for EvaluateCommand { } } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(dap::EvaluateResponse { result: message.result.clone(), type_: message.evaluate_type.clone(), @@ -1456,10 +1442,7 @@ impl DapCommand for EvaluateCommand { }) } - fn response_to_proto( - _debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapEvaluateResponse { result: message.result, evaluate_type: message.type_, @@ -1495,10 +1478,10 @@ impl DapCommand for ThreadsCommand { type ProtoResponse = proto::DapThreadsResponse; const CACHEABLE: bool = true; - fn to_proto(&self, debug_client_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { + fn to_proto(&self, session_id: SessionId, upstream_project_id: u64) -> Self::ProtoRequest { proto::DapThreadsRequest { project_id: upstream_project_id, - client_id: debug_client_id.to_proto(), + session_id: session_id.to_proto(), } } @@ -1506,18 +1489,18 @@ impl DapCommand for ThreadsCommand { Self {} } - fn client_id_from_proto(request: &Self::ProtoRequest) -> SessionId { - SessionId::from_proto(request.client_id) + fn session_id_from_proto(request: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(request.session_id) } - fn response_from_proto(&self, message: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + message: ::Response, + ) -> Result { Ok(Vec::from_proto(message.threads)) } - fn response_to_proto( - _debug_client_id: SessionId, - message: Self::Response, - ) -> Self::ProtoResponse { + fn response_to_proto(_session_id: SessionId, message: Self::Response) -> Self::ProtoResponse { proto::DapThreadsResponse { threads: message.to_proto(), } @@ -1665,34 +1648,33 @@ impl LocalDapCommand for SetBreakpoints { Ok(message.breakpoints) } } -#[derive(Clone, Debug, Hash, PartialEq)] -pub(super) enum SetExceptionBreakpoints { - Plain { - filters: Vec, - }, - WithOptions { - filters: Vec, - }, + +#[derive(Clone, Debug)] +pub(super) struct SetExceptionBreakpoints { + pub filters: Vec, + pub filter_options: Vec, + pub exception_filters: Vec, } impl LocalDapCommand for SetExceptionBreakpoints { type Response = Vec; type DapRequest = dap::requests::SetExceptionBreakpoints; + fn is_supported(capabilities: &Capabilities) -> bool { + capabilities.exception_breakpoint_filters.is_some() + || capabilities + .supports_exception_filter_options + .is_some_and(|supported| supported) + || capabilities + .supports_exception_options + .is_some_and(|supported| supported) + } + fn to_dap(&self) -> ::Arguments { - match self { - SetExceptionBreakpoints::Plain { filters } => dap::SetExceptionBreakpointsArguments { - filters: filters.clone(), - exception_options: None, - filter_options: None, - }, - SetExceptionBreakpoints::WithOptions { filters } => { - dap::SetExceptionBreakpointsArguments { - filters: vec![], - filter_options: Some(filters.clone()), - exception_options: None, - } - } + dap::SetExceptionBreakpointsArguments { + filters: self.filters.clone(), + exception_options: Some(self.exception_filters.clone()), + filter_options: Some(self.filter_options.clone()), } } @@ -1704,6 +1686,70 @@ impl LocalDapCommand for SetExceptionBreakpoints { } } +impl DapCommand for SetExceptionBreakpoints { + type ProtoRequest = proto::DapSetExceptionBreakpointsRequest; + type ProtoResponse = proto::DapSetExceptionBreakpointsResponse; + + fn session_id_from_proto(message: &Self::ProtoRequest) -> SessionId { + SessionId::from_proto(message.session_id) + } + + fn from_proto(message: &Self::ProtoRequest) -> Self { + Self { + filters: message.filters.clone(), + filter_options: message + .filter_options + .clone() + .into_iter() + .map(ExceptionFilterOptions::from_proto) + .collect(), + exception_filters: message + .exception_options + .clone() + .into_iter() + .map(ExceptionOptions::from_proto) + .collect(), + } + } + + fn to_proto(&self, session_id: SessionId, project_id: u64) -> Self::ProtoRequest { + proto::DapSetExceptionBreakpointsRequest { + project_id, + session_id: session_id.to_proto(), + filters: self.filters.clone(), + exception_options: self + .exception_filters + .clone() + .into_iter() + .map(|filter| filter.to_proto()) + .collect(), + filter_options: self + .filter_options + .clone() + .into_iter() + .map(|filter| filter.to_proto()) + .collect(), + } + } + + fn response_to_proto(_: SessionId, response: Self::Response) -> Self::ProtoResponse { + proto::DapSetExceptionBreakpointsResponse { + breakpoints: response.to_proto(), + } + } + + fn response_from_proto( + &self, + response: ::Response, + ) -> Result { + Ok(response + .breakpoints + .into_iter() + .map(Breakpoint::from_proto) + .collect()) + } +} + #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub(super) struct LocationsCommand { pub(super) reference: u64, @@ -1733,7 +1779,7 @@ impl DapCommand for LocationsCommand { const CACHEABLE: bool = true; - fn client_id_from_proto(message: &Self::ProtoRequest) -> SessionId { + fn session_id_from_proto(message: &Self::ProtoRequest) -> SessionId { SessionId::from_proto(message.session_id) } @@ -1761,7 +1807,10 @@ impl DapCommand for LocationsCommand { } } - fn response_from_proto(&self, response: Self::ProtoResponse) -> Result { + fn response_from_proto( + &self, + response: ::Response, + ) -> Result { Ok(dap::LocationsResponse { source: response .source diff --git a/crates/project/src/debugger/dap_store.rs b/crates/project/src/debugger/dap_store.rs index be4964bbee2688..b3f909bb3fb5b7 100644 --- a/crates/project/src/debugger/dap_store.rs +++ b/crates/project/src/debugger/dap_store.rs @@ -69,7 +69,7 @@ pub enum DapStoreEvent { enum DapStoreMode { Local(LocalDapStore), Ssh(SshDapStore), - Collab, + Collab(CollabDapStore), } pub struct LocalDapStore { @@ -86,6 +86,11 @@ pub struct SshDapStore { upstream_project_id: u64, } +pub struct CollabDapStore { + upstream_client: AnyProtoClient, + project_id: u64, +} + pub struct DapStore { mode: DapStoreMode, downstream_client: Option<(AnyProtoClient, u64)>, @@ -110,6 +115,7 @@ impl DapStore { client.add_entity_request_handler(Self::handle_run_debug_locator); client.add_entity_request_handler(Self::handle_get_debug_adapter_binary); client.add_entity_message_handler(Self::handle_log_to_debug_console); + client.add_entity_message_handler(Self::handle_new_session); } #[expect(clippy::too_many_arguments)] @@ -151,13 +157,21 @@ impl DapStore { } pub fn new_collab( - _project_id: u64, - _upstream_client: AnyProtoClient, + project_id: u64, + upstream_client: AnyProtoClient, breakpoint_store: Entity, worktree_store: Entity, cx: &mut Context, ) -> Self { - Self::new(DapStoreMode::Collab, breakpoint_store, worktree_store, cx) + Self::new( + DapStoreMode::Collab(CollabDapStore { + upstream_client, + project_id, + }), + breakpoint_store, + worktree_store, + cx, + ) } fn new( @@ -281,8 +295,17 @@ impl DapStore { }) }) } - DapStoreMode::Collab => { - Task::ready(Err(anyhow!("Debugging is not yet supported via collab"))) + DapStoreMode::Collab(collab) => { + let request = collab + .upstream_client + .request(proto::GetDebugAdapterBinary { + session_id: session_id.to_proto(), + project_id: collab.project_id, + worktree_id: worktree.read(cx).id().to_proto(), + definition: Some(definition.to_proto()), + }); + + cx.background_spawn(async move { DebugAdapterBinary::from_proto(request.await?) }) } } } @@ -351,8 +374,13 @@ impl DapStore { DebugRequest::from_proto(response) }) } - DapStoreMode::Collab => { - Task::ready(Err(anyhow!("Debugging is not yet supported via collab"))) + DapStoreMode::Collab(collab) => { + let request = collab.upstream_client.request(proto::RunDebugLocators { + project_id: collab.project_id, + build_command: Some(build_command.to_proto()), + locator: locator_name.to_owned(), + }); + cx.background_spawn(async move { DebugRequest::from_proto(request.await?) }) } } } @@ -364,6 +392,13 @@ impl DapStore { } } + fn as_collab(&self) -> Option<&CollabDapStore> { + match &self.mode { + DapStoreMode::Collab(collab_dap_store) => Some(collab_dap_store), + _ => None, + } + } + pub fn new_session( &mut self, label: SharedString, @@ -382,6 +417,7 @@ impl DapStore { let session = Session::new( self.breakpoint_store.clone(), + self.downstream_client.clone(), session_id, parent_session, label, @@ -447,11 +483,9 @@ impl DapStore { &self, session_id: impl Borrow, ) -> Option> { - let session_id = session_id.borrow(); - let client = self.sessions.get(session_id).cloned(); - - client + self.sessions.get(session_id.borrow()).cloned() } + pub fn sessions(&self) -> impl Iterator> { self.sessions.values() } @@ -652,18 +686,22 @@ impl DapStore { }); } VariableLookupKind::Expression => { - let Ok(eval_task) = session.read_with(cx, |session, _| { - session.mode.request_dap(EvaluateCommand { - expression: inline_value_location.variable_name.clone(), - frame_id: Some(stack_frame_id), - source: None, - context: Some(EvaluateArgumentsContext::Variables), - }) + let Ok(eval_task) = session.update(cx, |session, cx| { + session.request( + EvaluateCommand { + expression: inline_value_location.variable_name.clone(), + frame_id: Some(stack_frame_id), + source: None, + context: Some(EvaluateArgumentsContext::Variables), + }, + |_, result, _| result.ok(), + cx, + ) }) else { continue; }; - if let Some(response) = eval_task.await.log_err() { + if let Some(response) = eval_task.await { inlay_hints.push(InlayHint { position, label: InlayHintLabel::String(format_value(response.result)), @@ -853,6 +891,49 @@ impl DapStore { }) }) } + + async fn handle_new_session( + this: Entity, + envelope: TypedEnvelope, + mut cx: AsyncApp, + ) -> Result<()> { + let session_id = SessionId::from_proto(envelope.payload.session_id); + let parent_session_id = envelope + .payload + .parent_session_id + .map(SessionId::from_proto); + + this.update(&mut cx, |this, cx| { + let Some(collab) = this.as_collab() else { + anyhow::bail!("expected that dap store is in collab mode"); + }; + + let parent_session = parent_session_id.and_then(|id| this.session_by_id(id)); + + if let Some(parent_session) = &parent_session { + parent_session.update(cx, |session, _| { + session.add_child_session_id(session_id); + }); + } + + let session = Session::new_remote( + session_id, + parent_session, + DebugAdapterName(envelope.payload.adapter_name.into()), + envelope.payload.label.into(), + this.breakpoint_store.clone(), + collab.upstream_client.clone(), + collab.project_id, + cx.background_executor().clone(), + cx, + ); + + this.sessions.insert(session_id, session); + cx.notify(); + + Ok(()) + })? + } } #[derive(Clone)] diff --git a/crates/project/src/debugger/session.rs b/crates/project/src/debugger/session.rs index b76200aee6e923..b271756a781530 100644 --- a/crates/project/src/debugger/session.rs +++ b/crates/project/src/debugger/session.rs @@ -1,5 +1,3 @@ -use crate::debugger::breakpoint_store::BreakpointSessionState; - use super::breakpoint_store::{ BreakpointStore, BreakpointStoreEvent, BreakpointUpdatedReason, SourceBreakpoint, }; @@ -12,10 +10,12 @@ use super::dap_command::{ TerminateThreadsCommand, ThreadsCommand, VariablesCommand, }; use super::dap_store::DapStore; +use crate::debugger::breakpoint_store::BreakpointSessionState; use anyhow::{Context as _, Result, anyhow}; use collections::{HashMap, HashSet, IndexMap}; use dap::adapters::{DebugAdapterBinary, DebugAdapterName}; use dap::messages::Response; +use dap::proto_conversions::ProtoConversion; use dap::requests::{Request, RunInTerminal, StartDebugging}; use dap::{ Capabilities, ContinueArguments, EvaluateArgumentsContext, Module, Source, StackFrameId, @@ -36,8 +36,7 @@ use gpui::{ App, AppContext, AsyncApp, BackgroundExecutor, Context, Entity, EventEmitter, SharedString, Task, WeakEntity, }; - -use rpc::ErrorExt; +use rpc::{AnyProtoClient, ErrorExt, proto}; use serde_json::Value; use smol::stream::StreamExt; use std::any::TypeId; @@ -137,6 +136,7 @@ pub struct Watcher { pub enum Mode { Building, Running(RunningMode), + Remote(RemoteMode), } #[derive(Clone)] @@ -151,6 +151,16 @@ pub struct RunningMode { messages_tx: UnboundedSender, } +#[derive(Clone)] +pub struct RemoteMode { + client: AnyProtoClient, + has_ever_stopped: bool, + upstream_project_id: u64, + executor: BackgroundExecutor, + is_building: bool, + is_started: bool, +} + fn client_source(abs_path: &Path) -> dap::Source { dap::Source { name: abs_path @@ -297,9 +307,9 @@ impl RunningMode { filters: Vec, supports_filter_options: bool, ) -> Task>> { - let arg = if supports_filter_options { - SetExceptionBreakpoints::WithOptions { - filters: filters + self.request(if supports_filter_options { + SetExceptionBreakpoints { + filter_options: filters .into_iter() .map(|filter| ExceptionFilterOptions { filter_id: filter.filter, @@ -307,13 +317,16 @@ impl RunningMode { mode: None, }) .collect(), + filters: Vec::new(), + exception_filters: Vec::new(), } } else { - SetExceptionBreakpoints::Plain { + SetExceptionBreakpoints { filters: filters.into_iter().map(|filter| filter.filter).collect(), + filter_options: Vec::new(), + exception_filters: Vec::new(), } - }; - self.request(arg) + }) } fn send_source_breakpoints( @@ -537,17 +550,52 @@ impl RunningMode { } } +impl RemoteMode { + pub fn new( + client: AnyProtoClient, + upstream_project_id: u64, + executor: BackgroundExecutor, + ) -> Self { + Self { + client, + executor, + upstream_project_id, + has_ever_stopped: false, + is_building: true, + is_started: false, + } + } + + pub fn request( + &self, + session_id: SessionId, + request: R, + ) -> Task> { + let request = Arc::new(request); + + let request_clone = request.clone(); + let client = self.client.clone(); + let project_id = self.upstream_project_id; + self.executor.spawn(async move { + let args = request_clone.to_proto(session_id, project_id); + let response = client.request(args).await?; + request.response_from_proto(response) + }) + } +} + impl Mode { - pub(super) fn request_dap(&self, request: R) -> Task> - where - ::Response: 'static, - ::Arguments: 'static + Send, - { + pub(super) fn request_dap( + &self, + session_id: SessionId, + request: R, + ) -> Task> { match self { Mode::Running(debug_adapter_client) => debug_adapter_client.request(request), Mode::Building => Task::ready(Err(anyhow!( "no adapter running to send request: {request:?}" ))), + Mode::Remote(remote_mode) => remote_mode.request(session_id, request), } } @@ -556,6 +604,7 @@ impl Mode { match self { Mode::Building => false, Mode::Running(running_mode) => running_mode.has_ever_stopped, + Mode::Remote(remote_mode) => remote_mode.has_ever_stopped, } } @@ -657,6 +706,7 @@ pub struct Session { is_session_terminated: bool, requests: HashMap>>>>, pub(crate) breakpoint_store: Entity, + upstream_client: Option<(AnyProtoClient, u64)>, ignore_breakpoints: bool, exception_breakpoints: BTreeMap, background_tasks: Vec>, @@ -772,6 +822,7 @@ impl EventEmitter for Session {} impl Session { pub(crate) fn new( breakpoint_store: Entity, + upstream_client: Option<(AnyProtoClient, u64)>, session_id: SessionId, parent_session: Option>, label: SharedString, @@ -804,7 +855,7 @@ impl Session { .detach(); // cx.on_app_quit(Self::on_app_quit).detach(); - let this = Self { + Self { mode: Mode::Building, id: session_id, child_session_ids: HashSet::default(), @@ -825,13 +876,59 @@ impl Session { is_session_terminated: false, ignore_breakpoints: false, breakpoint_store, + upstream_client, exception_breakpoints: Default::default(), label, adapter, task_context, - }; + } + }) + } - this + pub(crate) fn new_remote( + session_id: SessionId, + parent_session: Option>, + adapter: DebugAdapterName, + label: SharedString, + breakpoint_store: Entity, + client: AnyProtoClient, + upstream_project_id: u64, + executor: BackgroundExecutor, + cx: &mut App, + ) -> Entity { + cx.new(|_| Self { + mode: Mode::Remote(RemoteMode { + client, + has_ever_stopped: false, + upstream_project_id, + executor, + is_building: true, + is_started: false, + }), + id: session_id, + child_session_ids: HashSet::default(), + parent_session, + capabilities: Capabilities::default(), + watchers: HashMap::default(), + variables: Default::default(), + stack_frames: Default::default(), + thread_states: ThreadStates::default(), + output_token: OutputToken(0), + output: circular_buffer::CircularBuffer::boxed(), + requests: HashMap::default(), + modules: Vec::default(), + loaded_sources: Vec::default(), + threads: IndexMap::default(), + background_tasks: Vec::default(), + locations: Default::default(), + is_session_terminated: false, + ignore_breakpoints: false, + breakpoint_store, + upstream_client: None, + exception_breakpoints: Default::default(), + label, + adapter, + task_context: Default::default(), // TODO(debugger): fix this }) } @@ -841,7 +938,7 @@ impl Session { pub fn worktree(&self) -> Option> { match &self.mode { - Mode::Building => None, + Mode::Building | Mode::Remote(_) => None, Mode::Running(local_mode) => local_mode.worktree.upgrade(), } } @@ -856,7 +953,7 @@ impl Session { let (message_tx, mut message_rx) = futures::channel::mpsc::unbounded(); let (initialized_tx, initialized_rx) = futures::channel::oneshot::channel(); - let background_tasks = vec![cx.spawn(async move |this: WeakEntity, cx| { + self.background_tasks = vec![cx.spawn(async move |this: WeakEntity, cx| { let mut initialized_tx = Some(initialized_tx); while let Some(message) = message_rx.next().await { if let Message::Event(event) = message { @@ -886,13 +983,29 @@ impl Session { } } })]; - self.background_tasks = background_tasks; - let id = self.id; + + let session_id = self.id; let parent_session = self.parent_session.clone(); cx.spawn(async move |this, cx| { + let upstream_client = this.update(cx, |this, _| this.upstream_client.clone())?; + + if let Some((client, project_id)) = &upstream_client { + let _ = client.send(proto::DapNewSession { + project_id: *project_id, + session_id: session_id.to_proto(), + parent_session_id: parent_session.as_ref().and_then(|session| { + session + .update(cx, |session, _| session.session_id().to_proto()) + .ok() + }), + label: "python main".to_string(), + adapter_name: "Python".to_string(), + }); + } + let mode = RunningMode::new( - id, + session_id, parent_session, worktree.downgrade(), binary.clone(), @@ -900,11 +1013,23 @@ impl Session { cx, ) .await?; + this.update(cx, |this, cx| { this.mode = Mode::Running(mode); cx.emit(SessionStateEvent::Running); })?; + if let Some((client, project_id)) = upstream_client { + let _ = client.send(proto::DapSessionUpdated { + project_id, + session_id: session_id.to_proto(), + capabilities: Some(Capabilities::default().to_proto()), + building: false, + has_ever_stopped: false, + is_started: false, + }); + } + this.update(cx, |session, cx| session.request_initialize(cx))? .await?; @@ -994,7 +1119,7 @@ impl Session { pub fn binary(&self) -> Option<&DebugAdapterBinary> { match &self.mode { - Mode::Building => None, + Mode::Building | Mode::Remote(_) => None, Mode::Running(running_mode) => Some(&running_mode.binary), } } @@ -1042,24 +1167,37 @@ impl Session { match &self.mode { Mode::Building => false, Mode::Running(running) => running.is_started, + Mode::Remote(remote) => remote.is_started, } } pub fn is_building(&self) -> bool { - matches!(self.mode, Mode::Building) + match &self.mode { + Mode::Building => true, + Mode::Running(_) => false, + Mode::Remote(remote_mode) => remote_mode.is_building, + } + } + + pub fn is_running(&self) -> bool { + match &self.mode { + Mode::Building => false, + Mode::Running(_) => true, + Mode::Remote(remote_mode) => !remote_mode.is_building, + } } pub fn as_running_mut(&mut self) -> Option<&mut RunningMode> { match &mut self.mode { Mode::Running(local_mode) => Some(local_mode), - Mode::Building => None, + Mode::Building | Mode::Remote(_) => None, } } pub fn as_running(&self) -> Option<&RunningMode> { match &self.mode { Mode::Running(local_mode) => Some(local_mode), - Mode::Building => None, + Mode::Building | Mode::Remote(_) => None, } } @@ -1265,6 +1403,7 @@ impl Session { local_mode.initialize_sequence(&self.capabilities, initialize_rx, dap_store, cx) } Mode::Building => Task::ready(Err(anyhow!("cannot initialize, still building"))), + Mode::Remote(_) => Task::ready(Err(anyhow!("cannot initialize on remote side"))), } } @@ -1299,7 +1438,7 @@ impl Session { }) .detach(); } - Mode::Building => {} + Mode::Building | Mode::Remote(_) => {} } } @@ -1546,6 +1685,7 @@ impl Session { return; } + let session_id = self.session_id(); let request_map = self .requests .entry(std::any::TypeId::of::()) @@ -1555,6 +1695,7 @@ impl Session { let command = vacant.key().0.clone().as_any_arc().downcast::().unwrap(); let task = Self::request_inner::>( + session_id, &self.capabilities, &self.mode, command, @@ -1578,6 +1719,7 @@ impl Session { } fn request_inner( + session_id: SessionId, capabilities: &Capabilities, mode: &Mode, request: T, @@ -1604,7 +1746,7 @@ impl Session { }); } - let request = mode.request_dap(request); + let request = mode.request_dap(session_id, request); cx.spawn(async move |this, cx| { let result = request.await; this.update(cx, |this, cx| process_result(this, result, cx)) @@ -1613,7 +1755,7 @@ impl Session { }) } - fn request( + pub fn request( &self, request: T, process_result: impl FnOnce( @@ -1624,7 +1766,14 @@ impl Session { + 'static, cx: &mut Context, ) -> Task> { - Self::request_inner(&self.capabilities, &self.mode, request, process_result, cx) + Self::request_inner( + self.id, + &self.capabilities, + &self.mode, + request, + process_result, + cx, + ) } fn invalidate_command_type(&mut self) { @@ -1953,7 +2102,7 @@ impl Session { pub fn adapter_client(&self) -> Option> { match self.mode { Mode::Running(ref local) => Some(local.client.clone()), - Mode::Building => None, + Mode::Building | Mode::Remote(_) => None, } } @@ -2234,27 +2383,33 @@ impl Session { frame_id: u64, cx: &mut Context, ) -> Task> { - let request = self.mode.request_dap(EvaluateCommand { - expression: expression.to_string(), - context: Some(EvaluateArgumentsContext::Watch), - frame_id: Some(frame_id), - source: None, - }); + let request = self.request( + EvaluateCommand { + expression: expression.to_string(), + context: Some(EvaluateArgumentsContext::Watch), + frame_id: Some(frame_id), + source: None, + }, + |_, result, _| result.ok(), + cx, + ); cx.spawn(async move |this, cx| { - let response = request.await?; + let response = request.await; this.update(cx, |session, cx| { - session.watchers.insert( - expression.clone(), - Watcher { - expression, - value: response.result.into(), - variables_reference: response.variables_reference, - presentation_hint: response.presentation_hint, - }, - ); - cx.emit(SessionEvent::Watchers); + if let Some(response) = response { + session.watchers.insert( + expression.clone(), + Watcher { + expression, + value: response.result.into(), + variables_reference: response.variables_reference, + presentation_hint: response.presentation_hint, + }, + ); + cx.emit(SessionEvent::Watchers); + } }) }) } @@ -2353,18 +2508,23 @@ impl Session { location_reference: None, }; self.push_output(event, cx); - let request = self.mode.request_dap(EvaluateCommand { - expression, - context, - frame_id, - source, - }); + + let request = self.request( + EvaluateCommand { + expression, + context, + frame_id, + source, + }, + |_, result, _| result.ok(), + cx, + ); cx.spawn(async move |this, cx| { let response = request.await; this.update(cx, |this, cx| { - match response { - Ok(response) => { - let event = dap::OutputEvent { + if let Some(response) = response { + this.push_output( + dap::OutputEvent { category: None, output: format!("< {}", &response.result), group: None, @@ -2374,25 +2534,11 @@ impl Session { column: None, data: None, location_reference: None, - }; - this.push_output(event, cx); - } - Err(e) => { - let event = dap::OutputEvent { - category: None, - output: format!("{}", e), - group: None, - variables_reference: None, - source: None, - line: None, - column: None, - data: None, - location_reference: None, - }; - this.push_output(event, cx); - } - }; - cx.notify(); + }, + cx, + ); + cx.notify(); + } }) .ok(); }) diff --git a/crates/proto/proto/call.proto b/crates/proto/proto/call.proto index 5212f3b43f5e78..1a3e5fe2ef86d3 100644 --- a/crates/proto/proto/call.proto +++ b/crates/proto/proto/call.proto @@ -368,6 +368,7 @@ message View { Editor editor = 3; ChannelView channel_view = 4; ContextEditor context_editor = 5; + DebugSession debug_session = 7; } message Editor { @@ -390,6 +391,10 @@ message View { string context_id = 1; Editor editor = 2; } + + message DebugSession { + uint64 session_id = 1; + } } message ExcerptInsertion { diff --git a/crates/proto/proto/debugger.proto b/crates/proto/proto/debugger.proto index 3979265accaa07..7dcf97b8311b57 100644 --- a/crates/proto/proto/debugger.proto +++ b/crates/proto/proto/debugger.proto @@ -52,9 +52,9 @@ message ValueFormat { optional bool hex = 1; } -message VariablesRequest { +message DapVariablesRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 variables_reference = 3; optional VariablesArgumentsFilter filter = 4; optional uint64 start = 5; @@ -93,7 +93,7 @@ enum DapEvaluateContext { message DapEvaluateRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; string expression = 3; optional uint64 frame_id = 4; optional DapEvaluateContext context = 5; @@ -111,7 +111,7 @@ message DapEvaluateResponse { message DapCompletionRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; string query = 3; optional uint64 frame_id = 4; optional uint64 line = 5; @@ -153,13 +153,13 @@ message DapCompletionItem { } message DapCompletionResponse { - uint64 client_id = 1; + uint64 session_id = 1; repeated DapCompletionItem completions = 2; } message DapScopesRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 stack_frame_id = 3; } @@ -169,14 +169,14 @@ message DapScopesResponse { message DapSetVariableValueRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; string name = 3; string value = 4; uint64 variables_reference = 5; } message DapSetVariableValueResponse { - uint64 client_id = 1; + uint64 session_id = 1; string value = 2; optional string variable_type = 3; optional uint64 variables_reference = 4; @@ -187,13 +187,13 @@ message DapSetVariableValueResponse { message DapPauseRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 thread_id = 3; } message DapDisconnectRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; optional bool restart = 3; optional bool terminate_debuggee = 4; optional bool suspend_debuggee = 5; @@ -201,13 +201,13 @@ message DapDisconnectRequest { message DapTerminateThreadsRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; repeated uint64 thread_ids = 3; } message DapThreadsRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; } message DapThreadsResponse { @@ -216,19 +216,19 @@ message DapThreadsResponse { message DapTerminateRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; optional bool restart = 3; } message DapRestartRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; bytes raw_args = 3; } message DapRestartStackFrameRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 stack_frame_id = 3; } @@ -245,7 +245,7 @@ message IgnoreBreakpointState { message DapNextRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 thread_id = 3; optional bool single_thread = 4; optional SteppingGranularity granularity = 5; @@ -253,7 +253,7 @@ message DapNextRequest { message DapStepInRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 thread_id = 3; optional uint64 target_id = 4; optional bool single_thread = 5; @@ -262,7 +262,7 @@ message DapStepInRequest { message DapStepOutRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 thread_id = 3; optional bool single_thread = 4; optional SteppingGranularity granularity = 5; @@ -270,7 +270,7 @@ message DapStepOutRequest { message DapStepBackRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 thread_id = 3; optional bool single_thread = 4; optional SteppingGranularity granularity = 5; @@ -278,39 +278,39 @@ message DapStepBackRequest { message DapContinueRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 thread_id = 3; optional bool single_thread = 4; } message DapContinueResponse { - uint64 client_id = 1; + uint64 session_id = 1; optional bool all_threads_continued = 2; } message DapModulesRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; } message DapModulesResponse { - uint64 client_id = 1; + uint64 session_id = 1; repeated DapModule modules = 2; } message DapLoadedSourcesRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; } message DapLoadedSourcesResponse { - uint64 client_id = 1; + uint64 session_id = 1; repeated DapSource sources = 2; } message DapStackTraceRequest { uint64 project_id = 1; - uint64 client_id = 2; + uint64 session_id = 2; uint64 thread_id = 3; optional uint64 start_frame = 4; optional uint64 stack_trace_levels = 5; @@ -334,13 +334,25 @@ message DapStackFrame { optional DapStackPresentationHint presentation_hint = 11; } +message DapSetExceptionBreakpointsRequest { + uint64 project_id = 1; + uint64 session_id = 2; + repeated string filters = 3; + repeated ExceptionFilterOptions filter_options = 4; + repeated ExceptionOptions exception_options = 5; +} + +message DapSetExceptionBreakpointsResponse { + repeated DapBreakpoint breakpoints = 1; +} + message DebuggerLoadedSourceList { - uint64 client_id = 1; + uint64 session_id = 1; repeated DapSource sources = 2; } -message DapVariables { - uint64 client_id = 1; +message DapVariablesResponse { + uint64 session_id = 1; repeated DapVariable variables = 2; } @@ -393,6 +405,7 @@ enum DapOutputCategory { Stdout = 2; Stderr = 3; Unknown = 4; + Telemetry = 5; } enum DapOutputEventGroup { @@ -445,6 +458,49 @@ enum DapStackPresentationHint { Subtle = 2; StackUnknown = 3; } + +enum ExceptionBreakMode { + Never = 0; + Always = 1; + Unhandled = 2; + AlwaysUnhandled = 3; +} + +message ExceptionPathSegment { + optional bool negate = 1; + repeated string names = 2; +} + +message ExceptionOptions { + repeated ExceptionPathSegment path = 1; + ExceptionBreakMode break_mode = 2; +} + +message ExceptionFilterOptions { + string filter_id = 1; + optional string condition = 2; + optional string mode = 3; +} + +enum DapBreakpointReason { + Pending = 0; + Failed = 1; +} + +message DapBreakpoint { + optional int64 id = 1; + bool verified = 2; + optional string message = 3; + optional DapSource source = 4; + optional uint32 line = 5; + optional uint32 column = 6; + optional uint32 end_line = 7; + optional uint32 end_column = 8; + optional string instruction_reference = 9; + optional uint32 offset = 10; + optional DapBreakpointReason reason = 11; +} + message DapModule { DapModuleId id = 1; string name = 2; @@ -546,3 +602,94 @@ message LogToDebugConsole { uint64 session_id = 2; string message = 3; } + +message DapNewSession { + uint64 project_id = 1; + uint64 session_id = 2; + optional uint64 parent_session_id = 3; + string label = 4; + string adapter_name = 5; +} + +message DapSessionUpdated { + uint64 project_id = 1; + uint64 session_id = 2; + Capabilities capabilities = 3; + bool building = 4; + bool has_ever_stopped = 5; + bool is_started = 6; +} + +message Capabilities { + optional bool supports_configuration_done_request = 1; + optional bool supports_function_breakpoints = 2; + optional bool supports_conditional_breakpoints = 3; + optional bool supports_hit_conditional_breakpoints = 4; + optional bool supports_evaluate_for_hovers = 5; + repeated ExceptionBreakpointsFilter exception_breakpoint_filters = 6; + optional bool supports_step_back = 7; + optional bool supports_set_variable = 8; + optional bool supports_restart_frame = 9; + optional bool supports_goto_targets_request = 10; + optional bool supports_step_in_targets_request = 11; + optional bool supports_completions_request = 12; + repeated string completion_trigger_characters = 13; + optional bool supports_modules_request = 14; + repeated string additional_module_columns = 15; + repeated string supported_checksum_algorithms = 16; + optional bool supports_restart_request = 17; + optional bool supports_exception_options = 18; + optional bool supports_value_formatting_options = 19; + optional bool supports_exception_info_request = 20; + optional bool support_terminate_debuggee = 21; + optional bool support_suspend_debuggee = 22; + optional bool supports_delayed_stack_trace_loading = 23; + optional bool supports_loaded_sources_request = 24; + optional bool supports_log_points = 25; + optional bool supports_terminate_threads_request = 26; + optional bool supports_set_expression = 27; + optional bool supports_terminate_request = 28; + optional bool supports_data_breakpoints = 29; + optional bool supports_read_memory_request = 30; + optional bool supports_write_memory_request = 31; + optional bool supports_disassemble_request = 32; + optional bool supports_cancel_request = 33; + optional bool supports_breakpoint_locations_request = 34; + optional bool supports_clipboard_context = 35; + optional bool supports_stepping_granularity = 36; + optional bool supports_instruction_breakpoints = 37; + optional bool supports_exception_filter_options = 38; + optional bool supports_single_thread_execution_requests = 39; + optional bool supports_data_breakpoint_bytes = 40; + repeated BreakpointMode breakpoint_modes = 41; + optional bool supports_ansistyling = 42; +} + +message ExceptionBreakpointsFilter { + string filter = 1; + string label = 2; + optional string description = 3; + optional bool default_value = 4; + optional bool supports_condition = 5; + optional string condition_description = 6; +} + +enum BreakpointModeApplicability { + Source = 0; + Exception = 1; + Data = 2; + InstructionBreakpoint = 3; + BreakpointModeUnknown = 4; +} + +message BreakpointMode { + string mode = 1; + string label = 2; + optional string description = 3; + repeated BreakpointModeApplicability applies_to = 4; +} + +message InvalidateSessionRequest { + uint64 project_id = 1; + uint64 session_id = 2; +} diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index 31f929ec9054c1..fa5882cc96f6b9 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -396,8 +396,44 @@ message Envelope { GetDocumentColor get_document_color = 353; GetDocumentColorResponse get_document_color_response = 354; GetColorPresentation get_color_presentation = 355; - GetColorPresentationResponse get_color_presentation_response = 356; // current max - + GetColorPresentationResponse get_color_presentation_response = 356; + + DapNextRequest dap_next_request = 357; + DapStepInRequest dap_step_in_request = 358; + DapStepOutRequest dap_step_out_request = 359; + DapStepBackRequest dap_step_back_request = 360; + DapContinueRequest dap_continue_request = 361; + DapContinueResponse dap_continue_response = 362; + DapPauseRequest dap_pause_request = 363; + DapDisconnectRequest dap_disconnect_request = 364; + DapTerminateThreadsRequest dap_terminate_threads_request = 365; + DapTerminateRequest dap_terminate_request = 366; + DapRestartRequest dap_restart_request = 367; + DapVariablesRequest dap_variables_request = 368; + DapVariablesResponse dap_variables_response = 369; + DapSetVariableValueRequest dap_set_variable_value_request = 370; + DapSetVariableValueResponse dap_set_variable_value_response = 371; + DapRestartStackFrameRequest dap_restart_stack_frame_request = 372; + DapModulesRequest dap_modules_request = 373; + DapModulesResponse dap_modules_response = 374; + DapLoadedSourcesRequest dap_loaded_sources_request = 375; + DapLoadedSourcesResponse dap_loaded_sources_response = 376; + DapStackTraceRequest dap_stack_trace_request = 377; + DapStackTraceResponse dap_stack_trace_response = 378; + DapScopesRequest dap_scopes_request = 379; + DapScopesResponse dap_scopes_response = 380; + DapCompletionRequest dap_completion_request = 381; + DapCompletionResponse dap_completion_response = 382; + DapEvaluateRequest dap_evaluate_request = 383; + DapEvaluateResponse dap_evaluate_response = 384; + DapThreadsRequest dap_threads_request = 385; + DapThreadsResponse dap_threads_response = 386; + DapLocationsRequest dap_locations_request = 387; + DapLocationsResponse dap_locations_response = 388; + DapSetExceptionBreakpointsRequest dap_set_exception_breakpoints_request = 389; + DapSetExceptionBreakpointsResponse dap_set_exception_breakpoints_response = 390; + DapNewSession dap_new_session = 391; + DapSessionUpdated dap_session_updated = 392; // current max } reserved 87 to 88; diff --git a/crates/proto/src/proto.rs b/crates/proto/src/proto.rs index 918ac9e93596ce..f0bdaea77173f8 100644 --- a/crates/proto/src/proto.rs +++ b/crates/proto/src/proto.rs @@ -313,7 +313,43 @@ messages!( (LogToDebugConsole, Background), (GetDocumentDiagnostics, Background), (GetDocumentDiagnosticsResponse, Background), - (PullWorkspaceDiagnostics, Background) + (PullWorkspaceDiagnostics, Background), + (DapNextRequest, Background), + (DapStepInRequest, Background), + (DapStepOutRequest, Background), + (DapStepBackRequest, Background), + (DapContinueRequest, Background), + (DapContinueResponse, Background), + (DapPauseRequest, Background), + (DapDisconnectRequest, Background), + (DapTerminateRequest, Background), + (DapRestartRequest, Background), + (DapVariablesRequest, Background), + (DapVariablesResponse, Background), + (DapSetVariableValueRequest, Background), + (DapSetVariableValueResponse, Background), + (DapRestartStackFrameRequest, Background), + (DapModulesRequest, Background), + (DapModulesResponse, Background), + (DapLoadedSourcesRequest, Background), + (DapLoadedSourcesResponse, Background), + (DapStackTraceRequest, Background), + (DapStackTraceResponse, Background), + (DapScopesRequest, Background), + (DapScopesResponse, Background), + (DapCompletionRequest, Background), + (DapCompletionResponse, Background), + (DapEvaluateRequest, Background), + (DapEvaluateResponse, Background), + (DapThreadsRequest, Background), + (DapThreadsResponse, Background), + (DapLocationsRequest, Background), + (DapLocationsResponse, Background), + (DapSetExceptionBreakpointsRequest, Background), + (DapSetExceptionBreakpointsResponse, Background), + (DapTerminateThreadsRequest, Background), + (DapNewSession, Background), + (DapSessionUpdated, Background), ); request_messages!( @@ -479,7 +515,34 @@ request_messages!( (GetDebugAdapterBinary, DebugAdapterBinary), (RunDebugLocators, DebugRequest), (GetDocumentDiagnostics, GetDocumentDiagnosticsResponse), - (PullWorkspaceDiagnostics, Ack) + (PullWorkspaceDiagnostics, Ack), + (DapNextRequest, Ack), + (DapStepInRequest, Ack), + (DapStepOutRequest, Ack), + (DapStepBackRequest, Ack), + (DapContinueRequest, DapContinueResponse), + (DapPauseRequest, Ack), + (DapDisconnectRequest, Ack), + (DapTerminateRequest, Ack), + (DapRestartRequest, Ack), + (DapVariablesRequest, DapVariablesResponse), + (DapSetVariableValueRequest, DapSetVariableValueResponse), + (DapRestartStackFrameRequest, Ack), + (DapModulesRequest, DapModulesResponse), + (DapLoadedSourcesRequest, DapLoadedSourcesResponse), + (DapStackTraceRequest, DapStackTraceResponse), + (DapScopesRequest, DapScopesResponse), + (DapCompletionRequest, DapCompletionResponse), + (DapEvaluateRequest, DapEvaluateResponse), + (DapThreadsRequest, DapThreadsResponse), + (DapLocationsRequest, DapLocationsResponse), + ( + DapSetExceptionBreakpointsRequest, + DapSetExceptionBreakpointsResponse + ), + (DapTerminateThreadsRequest, Ack), + (DapNewSession, Ack), + (DapSessionUpdated, Ack), ); entity_messages!( @@ -609,7 +672,9 @@ entity_messages!( GetDebugAdapterBinary, LogToDebugConsole, GetDocumentDiagnostics, - PullWorkspaceDiagnostics + PullWorkspaceDiagnostics, + DapNewSession, + DapSessionUpdated, ); entity_messages!(