Skip to content

Commit 135cee6

Browse files
committed
fix(oxlint/lsp): run diagnostics after delayed worker initialization (#16244)
When the Client does not a configuration object in the `initialize` request, we delay the workspace worker start until we request later the configuration inside the `initialized` notification. In the time, the client could already send `document/didOpen` notification, we should check here if we have already something in the file system. - close oxc-project/oxc-zed#31 - close #15374
1 parent 99e6723 commit 135cee6

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

crates/oxc_language_server/src/backend.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ use crate::{
3939
/// - Editor sends `textDocument/didOpen`, `textDocument/didChange`, `textDocument/didSave`, and `textDocument/didClose` notifications.
4040
/// - Editor sends `shutdown` request when the user closes the editor.
4141
/// - Editor sends `exit` notification and the server exits.
42+
///
43+
/// Because `initialized` is a notification, the client will not wait for a response from the server.
44+
/// Therefore, the server must be able to handle requests and notifications that may arrive directly after `initialized` notification,
45+
/// such as `textDocument/didOpen`.
4246
pub struct Backend {
4347
// The LSP client to communicate with the editor or IDE.
4448
client: Client,
@@ -191,10 +195,30 @@ impl LanguageServer for Backend {
191195
vec![serde_json::Value::Null; needed_configurations.len()]
192196
};
193197

198+
let known_files = self.file_system.read().await.keys();
199+
let mut new_diagnostics = Vec::new();
200+
194201
for (index, worker) in needed_configurations.values().enumerate() {
202+
// get the configuration from the response and start the worker
195203
let configuration = configurations.get(index).unwrap_or(&serde_json::Value::Null);
196-
197204
worker.start_worker(configuration.clone(), &self.tool_builders).await;
205+
206+
// run diagnostics for all known files in the workspace of the worker.
207+
// This is necessary because the worker was not started before.
208+
for uri in &known_files {
209+
if !worker.is_responsible_for_uri(uri) {
210+
continue;
211+
}
212+
let content = self.file_system.read().await.get(uri);
213+
if let Some(diagnostics) = worker.run_diagnostic(uri, content.as_deref()).await
214+
{
215+
new_diagnostics.push((uri.to_string(), diagnostics));
216+
}
217+
}
218+
}
219+
220+
if !new_diagnostics.is_empty() {
221+
self.publish_all_diagnostics(&new_diagnostics).await;
198222
}
199223
}
200224

crates/oxc_language_server/src/file_system.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ impl LSPFileSystem {
2323
pub fn remove(&self, uri: &Uri) {
2424
self.files.pin().remove(uri);
2525
}
26+
27+
pub fn keys(&self) -> Vec<Uri> {
28+
self.files.pin().keys().cloned().collect()
29+
}
2630
}

0 commit comments

Comments
 (0)