From 8251a343aa7ba96e6c97905f68c0ee90db240c14 Mon Sep 17 00:00:00 2001 From: IWANABETHATGUY Date: Mon, 27 Nov 2023 12:20:50 +0800 Subject: [PATCH] fix(oxc_vscode): vscode extension - check on file change (not on file save) (#1525) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Closed https://github.com/oxc-project/oxc/issues/1518 [录屏 2023年11月24日 12时08分14秒.webm](https://github.com/oxc-project/oxc/assets/17974631/6ff42edf-b837-466a-a9fa-a1d1244dfd45) --- editors/vscode/server/src/linter.rs | 26 +++++++++++++++++++------- editors/vscode/server/src/main.rs | 13 ++++++++----- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/editors/vscode/server/src/linter.rs b/editors/vscode/server/src/linter.rs index f757c2c5a..048c6bcd4 100644 --- a/editors/vscode/server/src/linter.rs +++ b/editors/vscode/server/src/linter.rs @@ -155,10 +155,14 @@ impl IsolatedLintHandler { Self::process_diagnostics(&rx_error) } - pub fn run_single(&self, path: &Path) -> Option> { + pub fn run_single( + &self, + path: &Path, + content: Option, + ) -> Option> { if Self::is_wanted_ext(path) { Some( - Self::lint_path(&self.linter, path, Arc::clone(&self.plugin)).map_or( + Self::lint_path(&self.linter, path, Arc::clone(&self.plugin), content).map_or( vec![], |(p, errors)| { errors.into_iter().map(|e| e.into_diagnostic_report(&p)).collect() @@ -201,7 +205,7 @@ impl IsolatedLintHandler { let linter = Arc::clone(&linter); let plugin = Arc::clone(&plugin); rayon::spawn(move || { - if let Some(diagnostics) = Self::lint_path(&linter, &path, plugin) { + if let Some(diagnostics) = Self::lint_path(&linter, &path, plugin, None) { tx_error.send(diagnostics).unwrap(); } drop(tx_error); @@ -228,9 +232,12 @@ impl IsolatedLintHandler { linter: &Linter, path: &Path, plugin: Plugin, + source_text: Option, ) -> Option<(PathBuf, Vec)> { - let source_text = - fs::read_to_string(path).unwrap_or_else(|_| panic!("Failed to read {path:?}")); + let source_text = source_text.unwrap_or_else(|| { + fs::read_to_string(path).unwrap_or_else(|_| panic!("Failed to read {path:?}")) + }); + let allocator = Allocator::default(); let source_type = SourceType::from_path(path).unwrap_or_else(|_| panic!("Incorrect {path:?}")); @@ -379,7 +386,12 @@ impl ServerLinter { .run_full() } - pub fn run_single(&self, root_uri: &Url, uri: &Url) -> Option> { + pub fn run_single( + &self, + root_uri: &Url, + uri: &Url, + content: Option, + ) -> Option> { let options = LintOptions { paths: vec![root_uri.to_file_path().unwrap()], ignore_path: "node_modules".into(), @@ -393,6 +405,6 @@ impl ServerLinter { Arc::clone(&self.linter), Arc::clone(&self.plugin), ) - .run_single(&uri.to_file_path().unwrap()) + .run_single(&uri.to_file_path().unwrap(), content) } } diff --git a/editors/vscode/server/src/main.rs b/editors/vscode/server/src/main.rs index 589925823..b3f28c13f 100644 --- a/editors/vscode/server/src/main.rs +++ b/editors/vscode/server/src/main.rs @@ -79,15 +79,18 @@ impl LanguageServer for Backend { async fn did_save(&self, params: DidSaveTextDocumentParams) { debug!("oxc server did save"); - self.handle_file_update(params.text_document.uri).await; + self.handle_file_update(params.text_document.uri, None).await; } + /// When the document changed, it may not be written to disk, so we should + /// get the file context from the language client async fn did_change(&self, params: DidChangeTextDocumentParams) { - self.handle_file_update(params.text_document.uri).await; + let content = params.content_changes.first().map(|c| c.text.clone()); + self.handle_file_update(params.text_document.uri, content).await; } async fn did_open(&self, params: DidOpenTextDocumentParams) { - self.handle_file_update(params.text_document.uri).await; + self.handle_file_update(params.text_document.uri, None).await; } async fn code_action(&self, params: CodeActionParams) -> Result> { @@ -156,10 +159,10 @@ impl Backend { .await; } - async fn handle_file_update(&self, uri: Url) { + async fn handle_file_update(&self, uri: Url, content: Option) { if let Some(Some(root_uri)) = self.root_uri.get() { self.server_linter.make_plugin(root_uri); - if let Some(diagnostics) = self.server_linter.run_single(root_uri, &uri) { + if let Some(diagnostics) = self.server_linter.run_single(root_uri, &uri, content) { self.client .publish_diagnostics( uri.clone(),