Skip to content
Closed
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
4 changes: 2 additions & 2 deletions crates/oxc_language_server/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ impl LanguageServer for Backend {
let mut removed_registrations = Vec::new();

for worker in &*self.workspace_workers.read().await {
let (uris, unregistrations) = worker.shutdown().await;
let (uris, unregistrations) = worker.shutdown(&*self.file_system.read().await).await;
clearing_diagnostics.extend(uris);
removed_registrations.extend(unregistrations);
}
Expand Down Expand Up @@ -439,7 +439,7 @@ impl LanguageServer for Backend {
else {
continue;
};
let (uris, unregistrations) = worker.shutdown().await;
let (uris, unregistrations) = worker.shutdown(&*self.file_system.read().await).await;
cleared_diagnostics.extend(uris);
removed_registrations.extend(unregistrations);
workers.remove(index);
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_language_server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::backend::Backend;
pub use crate::formatter::ServerFormatterBuilder;
#[cfg(feature = "linter")]
pub use crate::linter::ServerLinterBuilder;
pub use crate::tool::{Tool, ToolBuilder, ToolRestartChanges, ToolShutdownChanges};
pub use crate::tool::{Tool, ToolBuilder, ToolRestartChanges};

pub type ConcurrentHashMap<K, V> = papaya::HashMap<K, V, FxBuildHasher>;

Expand Down
10 changes: 1 addition & 9 deletions crates/oxc_language_server/src/linter/server_linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::{
isolated_lint_handler::{IsolatedLintHandler, IsolatedLintHandlerOptions},
options::{LintOptions as LSPLintOptions, Run, UnusedDisableDirectives},
},
tool::{Tool, ToolBuilder, ToolRestartChanges, ToolShutdownChanges},
tool::{Tool, ToolBuilder, ToolRestartChanges},
utils::normalize_path,
};

Expand Down Expand Up @@ -310,10 +310,6 @@ impl Tool for ServerLinter {
"linter"
}

fn shutdown(&self) -> ToolShutdownChanges {
ToolShutdownChanges { uris_to_clear_diagnostics: Some(self.get_cached_uris()) }
}

/// # Panics
/// Panics if the root URI cannot be converted to a file path.
fn handle_configuration_change(
Expand Down Expand Up @@ -552,10 +548,6 @@ impl ServerLinter {
}
}

fn get_cached_uris(&self) -> Vec<Uri> {
self.code_actions.pin().keys().cloned().collect()
}

fn get_code_actions_for_uri(&self, uri: &Uri) -> Option<Vec<LinterCodeAction>> {
if let Some(cached_code_actions) = self.code_actions.pin().get(uri) {
cached_code_actions.clone()
Expand Down
70 changes: 54 additions & 16 deletions crates/oxc_language_server/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,20 @@ impl TestServer {
assert_eq!(shutdown_result.id(), &Id::Number(id));
}

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

// diagnostics clear expected
acknowledge_publish_diagnostics(self).await;

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

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;
Expand Down Expand Up @@ -375,6 +389,16 @@ async fn acknowledge_unregistrations(server: &mut TestServer) {
server.send_ack(unregister_request.id().unwrap()).await;
}

async fn acknowledge_publish_diagnostics(server: &mut TestServer) {
let diagnostic_request = server.recv_notification().await;
assert_eq!(diagnostic_request.method(), "textDocument/publishDiagnostics");

if let Some(id) = diagnostic_request.id() {
// Acknowledge the diagnostics
server.send_ack(id).await;
}
}

async fn response_to_configuration(
server: &mut TestServer,
configurations: Vec<serde_json::Value>,
Expand Down Expand Up @@ -481,11 +505,12 @@ mod test_suite {
use crate::{
backend::Backend,
tests::{
FAKE_COMMAND, FakeToolBuilder, TestServer, WORKSPACE, acknowledge_registrations,
acknowledge_unregistrations, code_action, did_change, did_change_configuration,
did_change_watched_files, did_close, did_open, did_save, execute_command_request,
initialize_request, initialized_notification, response_to_configuration,
shutdown_request, test_configuration_request, workspace_folders_changed,
FAKE_COMMAND, FakeToolBuilder, TestServer, WORKSPACE, acknowledge_publish_diagnostics,
acknowledge_registrations, acknowledge_unregistrations, code_action, did_change,
did_change_configuration, did_change_watched_files, did_close, did_open, did_save,
execute_command_request, initialize_request, initialized_notification,
response_to_configuration, shutdown_request, test_configuration_request,
workspace_folders_changed,
},
};

Expand Down Expand Up @@ -1051,7 +1076,7 @@ mod test_suite {
assert!(response.id() == &Id::Number(3));
assert!(response.result().is_some_and(|result| *result == Value::Null));

server.shutdown(4).await;
server.shutdown_with_diagnostics_clear(4).await;
}

#[tokio::test]
Expand All @@ -1076,7 +1101,7 @@ mod test_suite {
assert_eq!(actions.len(), 1);
assert_eq!(actions[0]["title"], "Code Action title");

server.shutdown(4).await;
server.shutdown_with_diagnostics_clear(4).await;
}

#[tokio::test]
Expand All @@ -1102,7 +1127,12 @@ mod test_suite {
format!("Fake diagnostic for content: {content}")
);

server.shutdown(4).await;
if let Some(id) = diagnostic_response.id() {
// Acknowledge the diagnostics
server.send_ack(id).await;
}

server.shutdown_with_diagnostics_clear(4).await;
}

#[tokio::test]
Expand All @@ -1116,8 +1146,8 @@ mod test_suite {
let file = format!("{WORKSPACE}/diagnostics.config");
let content = "new text";
server.send_request(did_open(&file, "old text")).await;
let diagnostic_response = server.recv_notification().await;
assert_eq!(diagnostic_response.method(), "textDocument/publishDiagnostics");

acknowledge_publish_diagnostics(&mut server).await;

server.send_request(did_change(&file, content)).await;

Expand All @@ -1132,7 +1162,12 @@ mod test_suite {
format!("Fake diagnostic for content: {content}")
);

server.shutdown(4).await;
if let Some(id) = diagnostic_response.id() {
// Acknowledge the diagnostics
server.send_ack(id).await;
}

server.shutdown_with_diagnostics_clear(4).await;
}

#[tokio::test]
Expand All @@ -1146,13 +1181,11 @@ mod test_suite {
let file = format!("{WORKSPACE}/diagnostics.config");
let content = "new text";
server.send_request(did_open(&file, "old text")).await;
let diagnostic_response = server.recv_notification().await;
assert_eq!(diagnostic_response.method(), "textDocument/publishDiagnostics");
acknowledge_publish_diagnostics(&mut server).await;

server.send_request(did_change(&file, content)).await;

let diagnostic_response = server.recv_notification().await;
assert_eq!(diagnostic_response.method(), "textDocument/publishDiagnostics");
acknowledge_publish_diagnostics(&mut server).await;

server.send_request(did_save(&file, content)).await;

Expand All @@ -1167,6 +1200,11 @@ mod test_suite {
format!("Fake diagnostic for content: {content}")
);

server.shutdown(4).await;
if let Some(id) = diagnostic_response.id() {
// Acknowledge the diagnostics
server.send_ack(id).await;
}

server.shutdown_with_diagnostics_clear(4).await;
}
}
9 changes: 2 additions & 7 deletions crates/oxc_language_server/src/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ pub trait Tool: Send + Sync {
}

/// Shutdown the tool and return any necessary changes to be made after shutdown.
fn shutdown(&self) -> ToolShutdownChanges {
ToolShutdownChanges { uris_to_clear_diagnostics: None }
fn shutdown(&self) {
// Default implementation does nothing.
}
}

Expand All @@ -133,8 +133,3 @@ pub struct ToolRestartChanges {
/// Old patterns will be automatically unregistered
pub watch_patterns: Option<Vec<Pattern>>,
}

pub struct ToolShutdownChanges {
/// The URIs that need to have their diagnostics removed after the tool shutdown
pub uris_to_clear_diagnostics: Option<Vec<Uri>>,
}
13 changes: 7 additions & 6 deletions crates/oxc_language_server/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,25 @@ impl WorkspaceWorker {
/// This includes clearing diagnostics and unregistering file watchers.
pub async fn shutdown(
&self,
fs: &LSPFileSystem,
) -> (
// The URIs that need to have their diagnostics removed after shutdown
Vec<Uri>,
// Watchers that need to be unregistered
Vec<Unregistration>,
) {
let mut uris_to_clear_diagnostics = Vec::new();
let mut watchers_to_unregister = Vec::new();
for tool in self.tools.read().await.iter() {
let shutdown_changes = tool.shutdown();
if let Some(uris) = shutdown_changes.uris_to_clear_diagnostics {
uris_to_clear_diagnostics.extend(uris);
}
tool.shutdown();

watchers_to_unregister
.push(unregistration_tool_watcher_id(tool.name(), &self.root_uri));
}

(uris_to_clear_diagnostics, watchers_to_unregister)
(
fs.keys().into_iter().filter(|uri| self.is_responsible_for_uri(uri)).collect(),
watchers_to_unregister,
)
}

/// Get code actions or commands for the given range.
Expand Down
Loading