debugger: Remove fake adapter and un-gate GDB (#27557)
This is a clean-up PR in anticipation of introduction of Debugger Registry. I wanna get rid of DebugAdapterKind (or rather, it being an enum). Release Notes: - N/A --------- Co-authored-by: Anthony Eid <hello@anthonyeid.me> Co-authored-by: Anthony <anthony@zed.dev>
This commit is contained in:
parent
56eb650f09
commit
4839195003
53 changed files with 1315 additions and 924 deletions
|
@ -20,10 +20,9 @@ use dap::{
|
|||
Completions, Evaluate, Request as _, RunInTerminal, SetExpression, SetVariable,
|
||||
StartDebugging,
|
||||
},
|
||||
Capabilities, CompletionItem, CompletionsArguments, ErrorResponse, EvaluateArguments,
|
||||
EvaluateArgumentsContext, EvaluateResponse, RunInTerminalRequestArguments,
|
||||
Capabilities, CompletionItem, CompletionsArguments, DapRegistry, ErrorResponse,
|
||||
EvaluateArguments, EvaluateArgumentsContext, EvaluateResponse, RunInTerminalRequestArguments,
|
||||
SetExpressionArguments, SetVariableArguments, Source, StartDebuggingRequestArguments,
|
||||
StartDebuggingRequestArgumentsRequest,
|
||||
};
|
||||
use fs::Fs;
|
||||
use futures::{
|
||||
|
@ -51,7 +50,7 @@ use std::{
|
|||
sync::{atomic::Ordering::SeqCst, Arc},
|
||||
};
|
||||
use std::{collections::VecDeque, sync::atomic::AtomicU32};
|
||||
use task::{AttachConfig, DebugAdapterConfig, DebugRequestType};
|
||||
use task::{DebugAdapterConfig, DebugRequestDisposition};
|
||||
use util::ResultExt as _;
|
||||
use worktree::Worktree;
|
||||
|
||||
|
@ -89,6 +88,7 @@ pub struct LocalDapStore {
|
|||
worktree_store: Entity<WorktreeStore>,
|
||||
environment: Entity<ProjectEnvironment>,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
debug_adapters: Arc<DapRegistry>,
|
||||
toolchain_store: Arc<dyn LanguageToolchainStore>,
|
||||
start_debugging_tx: futures::channel::mpsc::UnboundedSender<(SessionId, Message)>,
|
||||
_start_debugging_task: Task<()>,
|
||||
|
@ -138,6 +138,7 @@ impl DapStore {
|
|||
node_runtime: NodeRuntime,
|
||||
fs: Arc<dyn Fs>,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
debug_adapters: Arc<DapRegistry>,
|
||||
environment: Entity<ProjectEnvironment>,
|
||||
toolchain_store: Arc<dyn LanguageToolchainStore>,
|
||||
breakpoint_store: Entity<BreakpointStore>,
|
||||
|
@ -178,6 +179,7 @@ impl DapStore {
|
|||
worktree_store,
|
||||
toolchain_store,
|
||||
language_registry,
|
||||
debug_adapters,
|
||||
start_debugging_tx,
|
||||
_start_debugging_task,
|
||||
next_session_id: Default::default(),
|
||||
|
@ -364,52 +366,63 @@ impl DapStore {
|
|||
config,
|
||||
local_store.start_debugging_tx.clone(),
|
||||
initialized_tx,
|
||||
local_store.debug_adapters.clone(),
|
||||
cx,
|
||||
);
|
||||
|
||||
let task = cx.spawn(async move |this, cx| {
|
||||
let session = match start_client_task.await {
|
||||
Ok(session) => session,
|
||||
Err(error) => {
|
||||
this.update(cx, |_, cx| {
|
||||
cx.emit(DapStoreEvent::Notification(error.to_string()));
|
||||
})
|
||||
.log_err();
|
||||
let task = create_new_session(session_id, initialized_rx, start_client_task, cx);
|
||||
(session_id, task)
|
||||
}
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn new_fake_session(
|
||||
&mut self,
|
||||
config: DebugAdapterConfig,
|
||||
worktree: &Entity<Worktree>,
|
||||
parent_session: Option<Entity<Session>>,
|
||||
caps: Capabilities,
|
||||
fails: bool,
|
||||
cx: &mut Context<Self>,
|
||||
) -> (SessionId, Task<Result<Entity<Session>>>) {
|
||||
let Some(local_store) = self.as_local() else {
|
||||
unimplemented!("Starting session on remote side");
|
||||
};
|
||||
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
let delegate = DapAdapterDelegate::new(
|
||||
local_store.fs.clone(),
|
||||
worktree.read(cx).id(),
|
||||
local_store.node_runtime.clone(),
|
||||
local_store.http_client.clone(),
|
||||
local_store.language_registry.clone(),
|
||||
local_store.toolchain_store.clone(),
|
||||
local_store.environment.update(cx, |env, cx| {
|
||||
let worktree = worktree.read(cx);
|
||||
env.get_environment(Some(worktree.id()), Some(worktree.abs_path()), cx)
|
||||
}),
|
||||
);
|
||||
let session_id = local_store.next_session_id();
|
||||
|
||||
// we have to insert the session early, so we can handle reverse requests
|
||||
// that need the session to be available
|
||||
this.update(cx, |store, cx| {
|
||||
store.sessions.insert(session_id, session.clone());
|
||||
cx.emit(DapStoreEvent::DebugClientStarted(session_id));
|
||||
cx.notify();
|
||||
})?;
|
||||
if let Some(session) = &parent_session {
|
||||
session.update(cx, |session, _| {
|
||||
session.add_child_session_id(session_id);
|
||||
});
|
||||
}
|
||||
|
||||
match session
|
||||
.update(cx, |session, cx| {
|
||||
session.initialize_sequence(initialized_rx, cx)
|
||||
})?
|
||||
.await
|
||||
{
|
||||
Ok(_) => {}
|
||||
Err(error) => {
|
||||
this.update(cx, |this, cx| {
|
||||
cx.emit(DapStoreEvent::Notification(error.to_string()));
|
||||
let (initialized_tx, initialized_rx) = oneshot::channel();
|
||||
|
||||
this.shutdown_session(session_id, cx)
|
||||
})?
|
||||
.await
|
||||
.log_err();
|
||||
let start_client_task = Session::fake(
|
||||
self.breakpoint_store.clone(),
|
||||
session_id,
|
||||
parent_session,
|
||||
delegate,
|
||||
config,
|
||||
local_store.start_debugging_tx.clone(),
|
||||
initialized_tx,
|
||||
caps,
|
||||
fails,
|
||||
cx,
|
||||
);
|
||||
|
||||
return Err(error);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(session)
|
||||
});
|
||||
let task = create_new_session(session_id, initialized_rx, start_client_task, cx);
|
||||
(session_id, task)
|
||||
}
|
||||
|
||||
|
@ -431,7 +444,6 @@ impl DapStore {
|
|||
request.arguments.unwrap_or_default(),
|
||||
)
|
||||
.expect("To parse StartDebuggingRequestArguments");
|
||||
|
||||
let worktree = local_store
|
||||
.worktree_store
|
||||
.update(cx, |this, _| this.worktrees().next())
|
||||
|
@ -441,25 +453,30 @@ impl DapStore {
|
|||
unreachable!("there must be a config for local sessions");
|
||||
};
|
||||
|
||||
let (_, new_session_task) = self.new_session(
|
||||
DebugAdapterConfig {
|
||||
label: config.label,
|
||||
kind: config.kind,
|
||||
request: match &args.request {
|
||||
StartDebuggingRequestArgumentsRequest::Launch => DebugRequestType::Launch,
|
||||
StartDebuggingRequestArgumentsRequest::Attach => {
|
||||
DebugRequestType::Attach(AttachConfig::default())
|
||||
}
|
||||
},
|
||||
program: config.program,
|
||||
cwd: config.cwd,
|
||||
initialize_args: Some(args.configuration),
|
||||
supports_attach: config.supports_attach,
|
||||
},
|
||||
&worktree,
|
||||
Some(parent_session.clone()),
|
||||
cx,
|
||||
);
|
||||
let debug_config = DebugAdapterConfig {
|
||||
label: config.label,
|
||||
adapter: config.adapter,
|
||||
request: DebugRequestDisposition::ReverseRequest(args),
|
||||
initialize_args: config.initialize_args.clone(),
|
||||
tcp_connection: config.tcp_connection.clone(),
|
||||
};
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
let new_session_task = {
|
||||
let caps = parent_session.read(cx).capabilities.clone();
|
||||
self.new_fake_session(
|
||||
debug_config,
|
||||
&worktree,
|
||||
Some(parent_session.clone()),
|
||||
caps,
|
||||
false,
|
||||
cx,
|
||||
)
|
||||
.1
|
||||
};
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
let new_session_task = self
|
||||
.new_session(debug_config, &worktree, Some(parent_session.clone()), cx)
|
||||
.1;
|
||||
|
||||
let request_seq = request.seq;
|
||||
cx.spawn(async move |_, cx| {
|
||||
|
@ -830,6 +847,58 @@ impl DapStore {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_new_session(
|
||||
session_id: SessionId,
|
||||
initialized_rx: oneshot::Receiver<()>,
|
||||
start_client_task: Task<Result<Entity<Session>, anyhow::Error>>,
|
||||
cx: &mut Context<'_, DapStore>,
|
||||
) -> Task<Result<Entity<Session>>> {
|
||||
let task = cx.spawn(async move |this, cx| {
|
||||
let session = match start_client_task.await {
|
||||
Ok(session) => session,
|
||||
Err(error) => {
|
||||
this.update(cx, |_, cx| {
|
||||
cx.emit(DapStoreEvent::Notification(error.to_string()));
|
||||
})
|
||||
.log_err();
|
||||
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
|
||||
// we have to insert the session early, so we can handle reverse requests
|
||||
// that need the session to be available
|
||||
this.update(cx, |store, cx| {
|
||||
store.sessions.insert(session_id, session.clone());
|
||||
cx.emit(DapStoreEvent::DebugClientStarted(session_id));
|
||||
cx.notify();
|
||||
})?;
|
||||
|
||||
match session
|
||||
.update(cx, |session, cx| {
|
||||
session.initialize_sequence(initialized_rx, cx)
|
||||
})?
|
||||
.await
|
||||
{
|
||||
Ok(_) => {}
|
||||
Err(error) => {
|
||||
this.update(cx, |this, cx| {
|
||||
cx.emit(DapStoreEvent::Notification(error.to_string()));
|
||||
|
||||
this.shutdown_session(session_id, cx)
|
||||
})?
|
||||
.await
|
||||
.log_err();
|
||||
|
||||
return Err(error);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(session)
|
||||
});
|
||||
task
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DapAdapterDelegate {
|
||||
fs: Arc<dyn Fs>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue