diff options
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r-- | cli/lsp/language_server.rs | 100 |
1 files changed, 54 insertions, 46 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index a26bafa3f..731024677 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -41,6 +41,7 @@ use super::diagnostics::DiagnosticsServer; use super::documents::to_hover_text; use super::documents::to_lsp_range; use super::documents::AssetOrDocument; +use super::documents::Document; use super::documents::Documents; use super::documents::LanguageId; use super::logging::lsp_log; @@ -755,15 +756,8 @@ impl Inner { &mut self, specifier: &ModuleSpecifier, params: DidOpenTextDocumentParams, - ) { + ) -> Document { let mark = self.performance.mark("did_open", Some(¶ms)); - - if params.text_document.uri.scheme() == "deno" { - // we can ignore virtual text documents opening, as they don't need to - // be tracked in memory, as they are static assets that won't change - // already managed by the language service - return; - } let language_id = params .text_document @@ -787,17 +781,8 @@ impl Inner { content, ); - if document.is_diagnosable() { - self - .diagnostics_server - .invalidate(self.documents.dependents(specifier)) - .await; - if let Err(err) = self.diagnostics_server.update() { - error!("{}", err); - } - } - self.performance.measure(mark); + document } async fn did_change(&mut self, params: DidChangeTextDocumentParams) { @@ -812,11 +797,8 @@ impl Inner { if document.is_diagnosable() { self .diagnostics_server - .invalidate(self.documents.dependents(&specifier)) - .await; - if let Err(err) = self.diagnostics_server.update() { - error!("{}", err); - } + .invalidate(&self.documents.dependents(&specifier)); + self.send_diagnostics_update(); } } Err(err) => error!("{}", err), @@ -840,10 +822,8 @@ impl Inner { if self.is_diagnosable(&specifier) { let mut specifiers = self.documents.dependents(&specifier); specifiers.push(specifier.clone()); - self.diagnostics_server.invalidate(specifiers).await; - if let Err(err) = self.diagnostics_server.update() { - error!("{}", err); - } + self.diagnostics_server.invalidate(&specifiers); + self.send_diagnostics_update(); } self.performance.measure(mark); } @@ -887,13 +867,13 @@ impl Inner { if let Err(err) = self.update_tsconfig().await { self.client.show_message(MessageType::WARNING, err).await; } - if let Err(err) = self.diagnostics_server.update() { - error!("{}", err); - } + self.documents.update_config( self.maybe_import_map.clone(), self.maybe_config_file.as_ref(), ); + + self.send_diagnostics_update(); } async fn did_change_watched_files( @@ -936,10 +916,8 @@ impl Inner { self.maybe_import_map.clone(), self.maybe_config_file.as_ref(), ); - self.diagnostics_server.invalidate_all().await; - if let Err(err) = self.diagnostics_server.update() { - error!("Cannot update diagnostics: {}", err); - } + self.diagnostics_server.invalidate_all(); + self.send_diagnostics_update(); } self.performance.measure(mark); } @@ -1185,8 +1163,7 @@ impl Inner { let mut code_actions = CodeActionCollection::default(); let file_diagnostics = self .diagnostics_server - .get_ts_diagnostics(&specifier, asset_or_doc.document_lsp_version()) - .await; + .get_ts_diagnostics(&specifier, asset_or_doc.document_lsp_version()); for diagnostic in &fixable_diagnostics { match diagnostic.source.as_deref() { Some("deno-ts") => { @@ -2342,6 +2319,17 @@ impl Inner { self.performance.measure(mark); Ok(maybe_symbol_information) } + + fn send_diagnostics_update(&self) { + let snapshot = ( + self.snapshot(), + self.config.snapshot(), + self.maybe_lint_config.clone(), + ); + if let Err(err) = self.diagnostics_server.update(snapshot) { + error!("Cannot update diagnostics: {}", err); + } + } } #[lspower::async_trait] @@ -2351,7 +2339,7 @@ impl lspower::LanguageServer for LanguageServer { params: InitializeParams, ) -> LspResult<InitializeResult> { let mut language_server = self.0.lock().await; - language_server.diagnostics_server.start(self.0.clone()); + language_server.diagnostics_server.start(); language_server.initialize(params).await } @@ -2364,14 +2352,29 @@ impl lspower::LanguageServer for LanguageServer { } async fn did_open(&self, params: DidOpenTextDocumentParams) { + if params.text_document.uri.scheme() == "deno" { + // we can ignore virtual text documents opening, as they don't need to + // be tracked in memory, as they are static assets that won't change + // already managed by the language service + return; + } + let (client, uri, specifier, had_specifier_settings) = { let mut inner = self.0.lock().await; let client = inner.client.clone(); let uri = params.text_document.uri.clone(); let specifier = inner.url_map.normalize_url(&uri); - inner.did_open(&specifier, params).await; + let document = inner.did_open(&specifier, params).await; let has_specifier_settings = inner.config.has_specifier_settings(&specifier); + if document.is_diagnosable() { + let specifiers = inner.documents.dependents(&specifier); + inner.diagnostics_server.invalidate(&specifiers); + // don't send diagnotics yet if we don't have the specifier settings + if has_specifier_settings { + inner.send_diagnostics_update(); + } + } (client, uri, specifier, has_specifier_settings) }; @@ -2381,12 +2384,12 @@ impl lspower::LanguageServer for LanguageServer { let language_server = self.clone(); tokio::spawn(async move { let response = client.specifier_configuration(&uri).await; + let mut inner = language_server.0.lock().await; match response { Ok(specifier_settings) => { - // now update the config - let mut inner = language_server.0.lock().await; + // now update the config and send a diagnostics update inner.config.set_specifier_settings( - specifier, + specifier.clone(), uri, specifier_settings, ); @@ -2395,6 +2398,14 @@ impl lspower::LanguageServer for LanguageServer { error!("{}", err); } } + if inner + .documents + .get(&specifier) + .map(|d| d.is_diagnosable()) + .unwrap_or(false) + { + inner.send_diagnostics_update(); + } }); } } @@ -2722,12 +2733,9 @@ impl Inner { // now that we have dependencies loaded, we need to re-analyze them and // invalidate some diagnostics - self.diagnostics_server.invalidate(vec![referrer]).await; + self.diagnostics_server.invalidate(&[referrer]); + self.send_diagnostics_update(); - self.diagnostics_server.update().map_err(|err| { - error!("{}", err); - LspError::internal_error() - })?; self.performance.measure(mark); Ok(Some(json!(true))) } |