Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions crates/oxc_language_server/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,17 +247,18 @@ impl LanguageServer for Backend {
}
}

/// This method clears all diagnostics and the in-memory file system if dynamic formatting is enabled.
/// This method clears all diagnostics and the in-memory file system.
///
/// See: <https://microsoft.github.io/language-server-protocol/specifications/specification-current/#shutdown>
async fn shutdown(&self) -> Result<()> {
let mut clearing_diagnostics = Vec::new();
let mut removed_registrations = Vec::new();

for worker in &*self.workspace_workers.read().await {
let (uris, unregistrations) = worker.shutdown().await;
// shutdown each worker and collect the URIs to clear diagnostics.
// unregistering file watchers is not necessary, because the client will do it automatically on shutdown.
// some clients (`helix`) do not expect any requests after shutdown is sent.
let (uris, _) = worker.shutdown().await;
clearing_diagnostics.extend(uris);
removed_registrations.extend(unregistrations);
}

// only clear diagnostics when we are using push diagnostics
Expand All @@ -266,13 +267,6 @@ impl LanguageServer for Backend {
{
self.clear_diagnostics(clearing_diagnostics).await;
}

if self.capabilities.get().unwrap().dynamic_watchers
&& !removed_registrations.is_empty()
&& let Err(err) = self.client.unregister_capability(removed_registrations).await
{
warn!("sending unregisterCapability.didChangeWatchedFiles failed: {err}");
}
self.file_system.write().await.clear();

Ok(())
Expand Down
48 changes: 8 additions & 40 deletions crates/oxc_language_server/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,20 +278,6 @@ impl TestServer {
assert!(shutdown_result.is_ok());
assert_eq!(shutdown_result.id(), &Id::Number(id));
}

async fn shutdown_with_watchers(&mut self, id: i64) {
// shutdown request
self.send_request(shutdown_request(id)).await;

// watcher unregistration expected
acknowledge_unregistrations(self).await;

// shutdown response
let shutdown_result = self.recv_response().await;

assert!(shutdown_result.is_ok());
assert_eq!(shutdown_result.id(), &Id::Number(id));
}
}

fn initialize_request_workspace_folders(
Expand Down Expand Up @@ -716,24 +702,6 @@ mod test_suite {
// shutdown request
server.send_request(shutdown_request(2)).await;

// client/unregisterCapability request
let unregister_request = server.recv_notification().await;
assert_eq!(unregister_request.method(), "client/unregisterCapability");
assert_eq!(unregister_request.id(), Some(&Id::Number(1)));
assert_eq!(
unregister_request.params(),
Some(&json!({
"unregisterations": [
{
"id": format!("watcher-FakeTool-{WORKSPACE}"),
"method": "workspace/didChangeWatchedFiles",
}
]
}))
);
// Acknowledge the unregistration
server.send_ack(&Id::Number(1)).await;

// shutdown response
let shutdown_result = server.recv_response().await;

Expand Down Expand Up @@ -942,7 +910,7 @@ mod test_suite {

// new watcher registration expected
acknowledge_registrations(&mut server).await;
server.shutdown_with_watchers(4).await;
server.shutdown(4).await;
}

#[tokio::test]
Expand Down Expand Up @@ -1036,7 +1004,7 @@ mod test_suite {
// Since FakeToolBuilder does not know about "unknown.file", no diagnostics or registrations are expected
// Thus, no further requests or responses should occur

server.shutdown_with_watchers(3).await;
server.shutdown(3).await;
}

#[tokio::test]
Expand All @@ -1058,7 +1026,7 @@ mod test_suite {
// New watcher registration expected
acknowledge_registrations(&mut server).await;

server.shutdown_with_watchers(3).await;
server.shutdown(3).await;
}

#[tokio::test]
Expand Down Expand Up @@ -1093,7 +1061,7 @@ mod test_suite {
format!("Fake diagnostic for content: {content}")
);

server.shutdown_with_watchers(3).await;
server.shutdown(3).await;
}

#[tokio::test]
Expand All @@ -1117,7 +1085,7 @@ mod test_suite {
// Acknowledge the refresh request
acknowledge_diagnostic_refresh(&mut server).await;

server.shutdown_with_watchers(3).await;
server.shutdown(3).await;
}

#[tokio::test]
Expand All @@ -1135,7 +1103,7 @@ mod test_suite {

// When `null` is sent and the client does not support workspace configuration requests,
// no configuration changes occur, so no diagnostics or registrations are expected.
server.shutdown_with_watchers(3).await;
server.shutdown(3).await;
}

#[tokio::test]
Expand All @@ -1161,7 +1129,7 @@ mod test_suite {
// New watcher registration expected
acknowledge_registrations(&mut server).await;

server.shutdown_with_watchers(3).await;
server.shutdown(3).await;
}

#[tokio::test]
Expand All @@ -1186,7 +1154,7 @@ mod test_suite {
// New watcher registration expected
acknowledge_registrations(&mut server).await;

server.shutdown_with_watchers(3).await;
server.shutdown(3).await;
}

#[tokio::test]
Expand Down
Loading