mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-11 21:13:02 +00:00
Merge pull request #1247 from zed-industries/ignore-non-created-progress-tokens
Ignore tokens that were not created via `WorkDoneProgressCreate`
This commit is contained in:
commit
a53de67e6f
3 changed files with 72 additions and 40 deletions
|
@ -2995,6 +2995,7 @@ async fn test_language_server_statuses(
|
|||
.unwrap();
|
||||
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
fake_language_server.start_progress("the-token").await;
|
||||
fake_language_server.notify::<lsp::notification::Progress>(lsp::ProgressParams {
|
||||
token: lsp::NumberOrString::String("the-token".to_string()),
|
||||
value: lsp::ProgressParamsValue::WorkDone(lsp::WorkDoneProgress::Report(
|
||||
|
|
|
@ -655,6 +655,14 @@ impl FakeLanguageServer {
|
|||
self.server.notify::<T>(params).ok();
|
||||
}
|
||||
|
||||
pub async fn request<T>(&self, params: T::Params) -> Result<T::Result>
|
||||
where
|
||||
T: request::Request,
|
||||
T::Result: 'static + Send,
|
||||
{
|
||||
self.server.request::<T>(params).await
|
||||
}
|
||||
|
||||
pub async fn receive_notification<T: notification::Notification>(&mut self) -> T::Params {
|
||||
self.try_receive_notification::<T>().await.unwrap()
|
||||
}
|
||||
|
@ -708,14 +716,20 @@ impl FakeLanguageServer {
|
|||
self.server.remove_request_handler::<T>();
|
||||
}
|
||||
|
||||
pub async fn start_progress(&mut self, token: impl Into<String>) {
|
||||
pub async fn start_progress(&self, token: impl Into<String>) {
|
||||
let token = token.into();
|
||||
self.request::<request::WorkDoneProgressCreate>(WorkDoneProgressCreateParams {
|
||||
token: NumberOrString::String(token.clone()),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
self.notify::<notification::Progress>(ProgressParams {
|
||||
token: NumberOrString::String(token.into()),
|
||||
token: NumberOrString::String(token),
|
||||
value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(Default::default())),
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn end_progress(&mut self, token: impl Into<String>) {
|
||||
pub fn end_progress(&self, token: impl Into<String>) {
|
||||
self.notify::<notification::Progress>(ProgressParams {
|
||||
token: NumberOrString::String(token.into()),
|
||||
value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(Default::default())),
|
||||
|
|
|
@ -178,7 +178,8 @@ pub enum Event {
|
|||
pub struct LanguageServerStatus {
|
||||
pub name: String,
|
||||
pub pending_work: BTreeMap<String, LanguageServerProgress>,
|
||||
pub pending_diagnostic_updates: isize,
|
||||
pub has_pending_diagnostic_updates: bool,
|
||||
progress_tokens: HashSet<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
|
@ -546,7 +547,8 @@ impl Project {
|
|||
LanguageServerStatus {
|
||||
name: server.name,
|
||||
pending_work: Default::default(),
|
||||
pending_diagnostic_updates: 0,
|
||||
has_pending_diagnostic_updates: false,
|
||||
progress_tokens: Default::default(),
|
||||
},
|
||||
)
|
||||
})
|
||||
|
@ -2025,8 +2027,23 @@ impl Project {
|
|||
// avoid stalling any language server like `gopls` which waits for a response
|
||||
// to these requests when initializing.
|
||||
language_server
|
||||
.on_request::<lsp::request::WorkDoneProgressCreate, _, _>(|_, _| async {
|
||||
Ok(())
|
||||
.on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
|
||||
let this = this.downgrade();
|
||||
move |params, mut cx| async move {
|
||||
if let Some(this) = this.upgrade(&cx) {
|
||||
this.update(&mut cx, |this, _| {
|
||||
if let Some(status) =
|
||||
this.language_server_statuses.get_mut(&server_id)
|
||||
{
|
||||
if let lsp::NumberOrString::String(token) = params.token
|
||||
{
|
||||
status.progress_tokens.insert(token);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
language_server
|
||||
|
@ -2079,7 +2096,8 @@ impl Project {
|
|||
LanguageServerStatus {
|
||||
name: language_server.name().to_string(),
|
||||
pending_work: Default::default(),
|
||||
pending_diagnostic_updates: 0,
|
||||
has_pending_diagnostic_updates: false,
|
||||
progress_tokens: Default::default(),
|
||||
},
|
||||
);
|
||||
language_server
|
||||
|
@ -2291,19 +2309,22 @@ impl Project {
|
|||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !language_server_status.progress_tokens.contains(&token) {
|
||||
return;
|
||||
}
|
||||
|
||||
match progress {
|
||||
lsp::WorkDoneProgress::Begin(report) => {
|
||||
if Some(token.as_str()) == disk_based_diagnostics_progress_token {
|
||||
language_server_status.pending_diagnostic_updates += 1;
|
||||
if language_server_status.pending_diagnostic_updates == 1 {
|
||||
self.disk_based_diagnostics_started(server_id, cx);
|
||||
self.broadcast_language_server_update(
|
||||
server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
|
||||
proto::LspDiskBasedDiagnosticsUpdating {},
|
||||
),
|
||||
);
|
||||
}
|
||||
language_server_status.has_pending_diagnostic_updates = true;
|
||||
self.disk_based_diagnostics_started(server_id, cx);
|
||||
self.broadcast_language_server_update(
|
||||
server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
|
||||
proto::LspDiskBasedDiagnosticsUpdating {},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
self.on_lsp_work_start(
|
||||
server_id,
|
||||
|
@ -2350,17 +2371,17 @@ impl Project {
|
|||
}
|
||||
}
|
||||
lsp::WorkDoneProgress::End(_) => {
|
||||
language_server_status.progress_tokens.remove(&token);
|
||||
|
||||
if Some(token.as_str()) == disk_based_diagnostics_progress_token {
|
||||
language_server_status.pending_diagnostic_updates -= 1;
|
||||
if language_server_status.pending_diagnostic_updates == 0 {
|
||||
self.disk_based_diagnostics_finished(server_id, cx);
|
||||
self.broadcast_language_server_update(
|
||||
server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
|
||||
proto::LspDiskBasedDiagnosticsUpdated {},
|
||||
),
|
||||
);
|
||||
}
|
||||
language_server_status.has_pending_diagnostic_updates = false;
|
||||
self.disk_based_diagnostics_finished(server_id, cx);
|
||||
self.broadcast_language_server_update(
|
||||
server_id,
|
||||
proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
|
||||
proto::LspDiskBasedDiagnosticsUpdated {},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
self.on_lsp_work_end(server_id, token.clone(), cx);
|
||||
self.broadcast_language_server_update(
|
||||
|
@ -4216,7 +4237,7 @@ impl Project {
|
|||
self.language_server_statuses
|
||||
.iter()
|
||||
.filter_map(|(id, status)| {
|
||||
if status.pending_diagnostic_updates > 0 {
|
||||
if status.has_pending_diagnostic_updates {
|
||||
Some(*id)
|
||||
} else {
|
||||
None
|
||||
|
@ -4616,7 +4637,8 @@ impl Project {
|
|||
LanguageServerStatus {
|
||||
name: server.name,
|
||||
pending_work: Default::default(),
|
||||
pending_diagnostic_updates: 0,
|
||||
has_pending_diagnostic_updates: false,
|
||||
progress_tokens: Default::default(),
|
||||
},
|
||||
);
|
||||
cx.notify();
|
||||
|
@ -6431,7 +6453,7 @@ mod tests {
|
|||
|
||||
let mut events = subscribe(&project, cx);
|
||||
|
||||
let mut fake_server = fake_servers.next().await.unwrap();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
fake_server.start_progress(progress_token).await;
|
||||
assert_eq!(
|
||||
events.next().await.unwrap(),
|
||||
|
@ -6440,10 +6462,6 @@ mod tests {
|
|||
}
|
||||
);
|
||||
|
||||
fake_server.start_progress(progress_token).await;
|
||||
fake_server.end_progress(progress_token).await;
|
||||
fake_server.start_progress(progress_token).await;
|
||||
|
||||
fake_server.notify::<lsp::notification::PublishDiagnostics>(
|
||||
lsp::PublishDiagnosticsParams {
|
||||
uri: Url::from_file_path("/dir/a.rs").unwrap(),
|
||||
|
@ -6464,8 +6482,7 @@ mod tests {
|
|||
}
|
||||
);
|
||||
|
||||
fake_server.end_progress(progress_token).await;
|
||||
fake_server.end_progress(progress_token).await;
|
||||
fake_server.end_progress(progress_token);
|
||||
assert_eq!(
|
||||
events.next().await.unwrap(),
|
||||
Event::DiskBasedDiagnosticsFinished {
|
||||
|
@ -6555,7 +6572,7 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
// Simulate diagnostics starting to update.
|
||||
let mut fake_server = fake_servers.next().await.unwrap();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
fake_server.start_progress(progress_token).await;
|
||||
|
||||
// Restart the server before the diagnostics finish updating.
|
||||
|
@ -6565,7 +6582,7 @@ mod tests {
|
|||
let mut events = subscribe(&project, cx);
|
||||
|
||||
// Simulate the newly started server sending more diagnostics.
|
||||
let mut fake_server = fake_servers.next().await.unwrap();
|
||||
let fake_server = fake_servers.next().await.unwrap();
|
||||
fake_server.start_progress(progress_token).await;
|
||||
assert_eq!(
|
||||
events.next().await.unwrap(),
|
||||
|
@ -6584,7 +6601,7 @@ mod tests {
|
|||
|
||||
// All diagnostics are considered done, despite the old server's diagnostic
|
||||
// task never completing.
|
||||
fake_server.end_progress(progress_token).await;
|
||||
fake_server.end_progress(progress_token);
|
||||
assert_eq!(
|
||||
events.next().await.unwrap(),
|
||||
Event::DiskBasedDiagnosticsFinished {
|
||||
|
|
Loading…
Reference in a new issue