Finish merge
This commit is contained in:
@@ -108,11 +108,7 @@ impl NewSessionModal {
|
||||
return;
|
||||
};
|
||||
let config = self.debug_config(cx, debugger);
|
||||
|
||||
let _ = self.debug_panel.update(cx, |panel, cx| {
|
||||
panel.past_debug_definition = Some(config.clone());
|
||||
panel.start_session(config, window, cx)
|
||||
});
|
||||
let workspace = self.workspace.clone();
|
||||
|
||||
let task_contexts = workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
@@ -120,7 +116,7 @@ impl NewSessionModal {
|
||||
})
|
||||
.ok();
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let task_context = if let Some(task) = task_contexts {
|
||||
task.await
|
||||
.active_worktree_context
|
||||
@@ -128,9 +124,8 @@ impl NewSessionModal {
|
||||
} else {
|
||||
task::TaskContext::default()
|
||||
};
|
||||
let project = workspace.update(cx, |workspace, _| workspace.project().clone())?;
|
||||
|
||||
let task = project.update(cx, |this, cx| {
|
||||
workspace.update_in(cx, |this, window, cx| {
|
||||
let template = DebugTaskTemplate {
|
||||
locator: None,
|
||||
definition: config.clone(),
|
||||
@@ -140,23 +135,18 @@ impl NewSessionModal {
|
||||
.resolve_task("debug_task", &task_context)
|
||||
.and_then(|resolved_task| resolved_task.resolved_debug_adapter_config())
|
||||
{
|
||||
this.start_debug_session(debug_config.definition, cx)
|
||||
this.start_debug_session(debug_config.definition, window, cx)
|
||||
} else {
|
||||
this.start_debug_session(config, cx)
|
||||
this.start_debug_session(config, window, cx)
|
||||
}
|
||||
})?;
|
||||
let spawn_result = task.await;
|
||||
if spawn_result.is_ok() {
|
||||
this.update(cx, |_, cx| {
|
||||
cx.emit(DismissEvent);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
spawn_result?;
|
||||
this.update(cx, |_, cx| {
|
||||
cx.emit(DismissEvent);
|
||||
})
|
||||
.ok();
|
||||
anyhow::Result::<_, anyhow::Error>::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_attach_picker(
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
terminals::{SshCommand, wrap_for_ssh},
|
||||
worktree_store::WorktreeStore,
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Result, anyhow, bail};
|
||||
use async_trait::async_trait;
|
||||
use collections::HashMap;
|
||||
use dap::{
|
||||
@@ -95,14 +95,12 @@ pub struct LocalDapStore {
|
||||
|
||||
pub struct SshDapStore {
|
||||
upstream_client: AnyProtoClient,
|
||||
ssh_client: Entity<SshRemoteClient>,
|
||||
upstream_project_id: u64,
|
||||
}
|
||||
|
||||
pub struct DapStore {
|
||||
mode: DapStoreMode,
|
||||
downstream_client: Option<(AnyProtoClient, u64)>,
|
||||
worktree_store: Entity<WorktreeStore>,
|
||||
breakpoint_store: Entity<BreakpointStore>,
|
||||
sessions: BTreeMap<SessionId, Entity<Session>>,
|
||||
next_session_id: u32,
|
||||
@@ -208,7 +206,6 @@ impl DapStore {
|
||||
start_debugging_tx,
|
||||
next_session_id: 0,
|
||||
downstream_client: None,
|
||||
worktree_store,
|
||||
breakpoint_store,
|
||||
sessions: Default::default(),
|
||||
}
|
||||
@@ -324,70 +321,23 @@ impl DapStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_remote_client(
|
||||
&mut self,
|
||||
definition: DebugTaskDefinition,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let DapStoreMode::Ssh(remote) = &self.mode {
|
||||
self.sessions.insert(
|
||||
session_id,
|
||||
cx.new(|_| {
|
||||
debugger::session::Session::remote(
|
||||
session_id,
|
||||
remote.upstream_client.clone(),
|
||||
remote.upstream_project_id,
|
||||
ignore.unwrap_or(false),
|
||||
)
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
debug_assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_debug_locator(
|
||||
&mut self,
|
||||
template: DebugTaskTemplate,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<DebugTaskDefinition>> {
|
||||
let Some(locator_name) = template.locator else {
|
||||
return Task::ready(Ok(template.definition));
|
||||
};
|
||||
|
||||
match &self.mode {
|
||||
DapStoreMode::Local(local) => {
|
||||
if let Some(locator) = local.locators.get(&locator_name).cloned() {
|
||||
cx.background_spawn(
|
||||
async move { locator.run_locator(template.definition).await },
|
||||
)
|
||||
} else {
|
||||
Task::ready(Err(anyhow!("Couldn't find locator {}", locator_name)))
|
||||
}
|
||||
}
|
||||
DapStoreMode::Ssh(ssh) => {
|
||||
let request = ssh.upstream_client.request(proto::RunDebugLocator {
|
||||
project_id: ssh.upstream_project_id,
|
||||
locator: locator_name,
|
||||
task: Some(template.definition.to_proto()),
|
||||
});
|
||||
cx.background_spawn(async move {
|
||||
let response = request.await?;
|
||||
DebugTaskDefinition::from_proto(response)
|
||||
})
|
||||
}
|
||||
DapStoreMode::Collab => {
|
||||
Task::ready(Err(anyhow!("Debugging is not yet supported via collab")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn as_local(&self) -> Option<&LocalDapStore> {
|
||||
match &self.mode {
|
||||
DapStoreMode::Local(local_dap_store) => Some(local_dap_store),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
// pub fn add_remote_client(&mut self, definition: DebugTaskDefinition, cx: &mut Context<Self>) {
|
||||
// if let DapStoreMode::Ssh(remote) = &self.mode {
|
||||
// self.sessions.insert(
|
||||
// session_id,
|
||||
// cx.new(|_| {
|
||||
// debugger::session::Session::remote(
|
||||
// session_id,
|
||||
// remote.upstream_client.clone(),
|
||||
// remote.upstream_project_id,
|
||||
// ignore.unwrap_or(false),
|
||||
// )
|
||||
// }),
|
||||
// );
|
||||
// } else {
|
||||
// debug_assert!(false);
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn start_session(
|
||||
&mut self,
|
||||
@@ -395,7 +345,11 @@ impl DapStore {
|
||||
parent_session: Option<Entity<Session>>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Result<Entity<Session>> {
|
||||
let Some(worktree) = self.worktree_store.read(cx).visible_worktrees(cx).next() else {
|
||||
let Some(local) = self.as_local() else {
|
||||
bail!("Can't start a session from non local dap store");
|
||||
};
|
||||
|
||||
let Some(worktree) = local.worktree_store.read(cx).visible_worktrees(cx).next() else {
|
||||
return Err(anyhow!("Failed to find a worktree"));
|
||||
};
|
||||
let session_id = SessionId(util::post_inc(&mut self.next_session_id));
|
||||
@@ -939,142 +893,6 @@ impl DapStore {
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_run_debug_locator(
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::RunDebugLocator>,
|
||||
mut cx: AsyncApp,
|
||||
) -> Result<proto::DebugTaskDefinition> {
|
||||
let template = DebugTaskTemplate {
|
||||
locator: Some(envelope.payload.locator),
|
||||
definition: DebugTaskDefinition::from_proto(
|
||||
envelope
|
||||
.payload
|
||||
.task
|
||||
.ok_or_else(|| anyhow!("missing definition"))?,
|
||||
)?,
|
||||
};
|
||||
let definition = this
|
||||
.update(&mut cx, |this, cx| this.run_debug_locator(template, cx))?
|
||||
.await?;
|
||||
Ok(definition.to_proto())
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
async fn handle_get_debug_adapter_binary(
|
||||
this: Entity<Self>,
|
||||
envelope: TypedEnvelope<proto::GetDebugAdapterBinary>,
|
||||
mut cx: AsyncApp,
|
||||
) -> Result<proto::DebugAdapterBinary> {
|
||||
let definition = DebugTaskDefinition::from_proto(
|
||||
envelope
|
||||
.payload
|
||||
.task
|
||||
.ok_or_else(|| anyhow!("missing definition"))?,
|
||||
)?;
|
||||
let binary = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.get_debug_adapter_binary(definition, cx)
|
||||
})?
|
||||
.await?;
|
||||
Ok(binary.to_proto())
|
||||
}
|
||||
=======
|
||||
// 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();
|
||||
})?;
|
||||
let seq_result = async || {
|
||||
session
|
||||
.update(cx, |session, cx| session.request_initialize(cx))?
|
||||
.await?;
|
||||
|
||||
session
|
||||
.update(cx, |session, cx| {
|
||||
session.initialize_sequence(initialized_rx, this.clone(), cx)
|
||||
})?
|
||||
.await
|
||||
};
|
||||
match seq_result().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);
|
||||
}
|
||||
}
|
||||
|
||||
this.update(cx, |_, cx| {
|
||||
cx.subscribe(
|
||||
&session,
|
||||
move |this: &mut DapStore, session, event: &SessionStateEvent, cx| match event {
|
||||
SessionStateEvent::Shutdown => {
|
||||
this.shutdown_session(session_id, cx).detach_and_log_err(cx);
|
||||
}
|
||||
SessionStateEvent::Restart => {
|
||||
let mut curr_session = session;
|
||||
while let Some(parent_id) = curr_session.read(cx).parent_id() {
|
||||
if let Some(parent_session) = this.sessions.get(&parent_id).cloned() {
|
||||
curr_session = parent_session;
|
||||
} else {
|
||||
log::error!("Failed to get parent session from parent session id");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let Some((config, binary)) = curr_session.read_with(cx, |session, _| {
|
||||
session
|
||||
.configuration()
|
||||
.map(|config| (config, session.root_binary().clone()))
|
||||
}) else {
|
||||
log::error!("Failed to get debug config from session");
|
||||
return;
|
||||
};
|
||||
|
||||
let session_id = curr_session.read(cx).session_id();
|
||||
|
||||
let task = curr_session.update(cx, |session, cx| session.shutdown(cx));
|
||||
|
||||
let worktree = worktree.clone();
|
||||
cx.spawn(async move |this, cx| {
|
||||
task.await;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.sessions.remove(&session_id);
|
||||
this.new_session(
|
||||
binary.as_ref().clone(),
|
||||
config,
|
||||
worktree,
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
})?
|
||||
.1
|
||||
.await?;
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
cx.emit(DapStoreEvent::DebugSessionInitialized(session_id));
|
||||
})?;
|
||||
|
||||
Ok(session)
|
||||
});
|
||||
task
|
||||
>>>>>>> origin/main
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DapAdapterDelegate {
|
||||
fs: Arc<dyn Fs>,
|
||||
|
||||
@@ -153,12 +153,17 @@ impl LocalMode {
|
||||
binary: DebugAdapterBinary,
|
||||
messages_tx: futures::channel::mpsc::UnboundedSender<Message>,
|
||||
cx: AsyncApp,
|
||||
<<<<<<< HEAD
|
||||
) -> Result<Self> {
|
||||
let message_handler = Box::new(move |message| {
|
||||
messages_tx.unbounded_send(message).ok();
|
||||
});
|
||||
|
||||
let root_binary = if let Some(parent_session) = parent_session.as_ref() {
|
||||
Some(parent_session.read_with(&cx, |session, _| session.root_binary().clone())?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let client = Arc::new(
|
||||
if let Some(client) = parent_session
|
||||
.and_then(|session| cx.update(|cx| session.read(cx).adapter_client()).ok())
|
||||
@@ -169,58 +174,18 @@ impl LocalMode {
|
||||
.await?
|
||||
} else {
|
||||
DebugAdapterClient::start(session_id, binary.clone(), message_handler, cx.clone())
|
||||
=======
|
||||
) -> Task<Result<Self>> {
|
||||
cx.spawn(async move |cx| {
|
||||
let message_handler = Box::new(move |message| {
|
||||
messages_tx.unbounded_send(message).ok();
|
||||
});
|
||||
|
||||
let root_binary = if let Some(parent_session) = parent_session.as_ref() {
|
||||
Some(parent_session.read_with(cx, |session, _| session.root_binary().clone())?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let client = Arc::new(
|
||||
if let Some(client) = parent_session
|
||||
.and_then(|session| cx.update(|cx| session.read(cx).adapter_client()).ok())
|
||||
.flatten()
|
||||
{
|
||||
client
|
||||
.reconnect(session_id, binary.clone(), message_handler, cx.clone())
|
||||
.await?
|
||||
} else {
|
||||
DebugAdapterClient::start(
|
||||
session_id,
|
||||
binary.clone(),
|
||||
message_handler,
|
||||
cx.clone(),
|
||||
)
|
||||
>>>>>>> origin/main
|
||||
.await
|
||||
.with_context(|| "Failed to start communication with debug adapter")?
|
||||
},
|
||||
);
|
||||
|
||||
<<<<<<< HEAD
|
||||
Ok(Self {
|
||||
client,
|
||||
breakpoint_store,
|
||||
worktree,
|
||||
tmp_breakpoint: None,
|
||||
root_binary,
|
||||
binary,
|
||||
=======
|
||||
Ok(Self {
|
||||
client,
|
||||
breakpoint_store,
|
||||
worktree,
|
||||
tmp_breakpoint: None,
|
||||
definition: config,
|
||||
root_binary,
|
||||
binary,
|
||||
})
|
||||
>>>>>>> origin/main
|
||||
})
|
||||
}
|
||||
|
||||
@@ -857,13 +822,16 @@ impl Session {
|
||||
}
|
||||
|
||||
pub(crate) fn root_binary(&self) -> Arc<DebugAdapterBinary> {
|
||||
let Mode::Local(local_mode) = &self.mode else {
|
||||
panic!("Session is not local");
|
||||
};
|
||||
local_mode
|
||||
.root_binary
|
||||
.clone()
|
||||
.unwrap_or_else(|| Arc::new(local_mode.binary.clone()))
|
||||
match &self.mode {
|
||||
Mode::Building => {
|
||||
// todo(debugger): Implement root_binary for building mode
|
||||
unimplemented!()
|
||||
}
|
||||
Mode::Running(running) => running
|
||||
.root_binary
|
||||
.clone()
|
||||
.unwrap_or_else(|| Arc::new(running.binary.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn binary(&self) -> &DebugAdapterBinary {
|
||||
|
||||
@@ -39,41 +39,6 @@ pub fn intercept_debug_sessions<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn start_debug_session_with<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
|
||||
project: &Entity<Project>,
|
||||
cx: &mut gpui::TestAppContext,
|
||||
config: DebugTaskDefinition,
|
||||
configure: T,
|
||||
) -> Task<Result<Entity<Session>>> {
|
||||
let subscription = intercept_debug_sessions(cx, configure);
|
||||
let task = project.update(cx, |project, cx| project.start_debug_session(config, cx));
|
||||
cx.spawn(async move |_| {
|
||||
let result = task.await;
|
||||
drop(subscription);
|
||||
result
|
||||
})
|
||||
}
|
||||
|
||||
pub fn start_debug_session<T: Fn(&Arc<DebugAdapterClient>) + 'static>(
|
||||
project: &Entity<Project>,
|
||||
cx: &mut gpui::TestAppContext,
|
||||
configure: T,
|
||||
) -> Task<Result<Entity<Session>>> {
|
||||
start_debug_session_with(
|
||||
project,
|
||||
cx,
|
||||
DebugTaskDefinition {
|
||||
adapter: "fake-adapter".to_string(),
|
||||
request: DebugRequest::Launch(Default::default()),
|
||||
label: "test".to_string(),
|
||||
initialize_args: None,
|
||||
tcp_connection: None,
|
||||
stop_on_entry: None,
|
||||
},
|
||||
configure,
|
||||
)
|
||||
}
|
||||
|
||||
fn register_default_handlers(session: &Session, client: &Arc<DebugAdapterClient>, cx: &mut App) {
|
||||
client.on_request::<dap::requests::Initialize, _>(move |_, _| Ok(Default::default()));
|
||||
let paths = session
|
||||
|
||||
Reference in New Issue
Block a user