diff options
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r-- | cli/lsp/language_server.rs | 296 |
1 files changed, 173 insertions, 123 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 12fc70c8c..2fbc41b03 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -44,6 +44,7 @@ use super::analysis::ResolvedDependency; use super::capabilities; use super::completions; use super::config::Config; +use super::config::SETTINGS_SECTION; use super::diagnostics; use super::diagnostics::DiagnosticSource; use super::documents::DocumentCache; @@ -78,6 +79,7 @@ pub struct StateSnapshot { pub module_registries: registries::ModuleRegistry, pub performance: Performance, pub sources: Sources, + pub url_map: urls::LspUrlMap, } #[derive(Debug)] @@ -188,10 +190,6 @@ impl Inner { } } - fn enabled(&self) -> bool { - self.config.settings.enable - } - /// Searches assets, open documents and external sources for a line_index, /// which might be performed asynchronously, hydrating in memory caches for /// subsequent requests. @@ -293,6 +291,7 @@ impl Inner { module_registries: self.module_registries.clone(), performance: self.performance.clone(), sources: self.sources.clone(), + url_map: self.url_map.clone(), } } @@ -300,7 +299,10 @@ impl Inner { let mark = self.performance.mark("update_import_map"); let (maybe_import_map, maybe_root_uri) = { let config = &self.config; - (config.settings.import_map.clone(), config.root_uri.clone()) + ( + config.workspace_settings.import_map.clone(), + config.root_uri.clone(), + ) }; if let Some(import_map_str) = &maybe_import_map { info!("Updating import map from: \"{}\"", import_map_str); @@ -345,7 +347,8 @@ impl Inner { async fn update_registries(&mut self) -> Result<(), AnyError> { let mark = self.performance.mark("update_registries"); - for (registry, enabled) in self.config.settings.suggest.imports.hosts.iter() + for (registry, enabled) in + self.config.workspace_settings.suggest.imports.hosts.iter() { if *enabled { info!("Enabling auto complete registry for: {}", registry); @@ -376,13 +379,16 @@ impl Inner { })); let (maybe_config, maybe_root_uri) = { let config = &self.config; - if config.settings.unstable { + if config.workspace_settings.unstable { let unstable_libs = json!({ "lib": ["deno.ns", "deno.window", "deno.unstable"] }); tsconfig.merge(&unstable_libs); } - (config.settings.config.clone(), config.root_uri.clone()) + ( + config.workspace_settings.config.clone(), + config.root_uri.clone(), + ) }; if let Some(config_str) = &maybe_config { info!("Updating TypeScript configuration from: \"{}\"", config_str); @@ -491,7 +497,7 @@ impl Inner { let config = &mut self.config; config.root_uri = params.root_uri; if let Some(value) = params.initialization_options { - config.update(value)?; + config.update_workspace(value)?; } config.update_capabilities(¶ms.capabilities); } @@ -573,13 +579,35 @@ impl Inner { async fn did_open(&mut self, params: DidOpenTextDocumentParams) { let mark = self.performance.mark("did_open"); + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + + // we only query the individual resource file if the client supports it + if self.config.client_capabilities.workspace_configuration + && !self.config.contains(&specifier) + { + if let Ok(value) = self + .client + .configuration(vec![ConfigurationItem { + scope_uri: Some(params.text_document.uri.clone()), + section: Some(SETTINGS_SECTION.to_string()), + }]) + .await + { + if let Err(err) = self + .config + .update_specifier(specifier.clone(), value[0].clone()) + { + warn!("Error updating specifier configuration: {}", err); + } + } + } + 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 specifier = self.url_map.normalize_url(¶ms.text_document.uri); self.documents.open( specifier.clone(), params.text_document.version, @@ -635,56 +663,69 @@ impl Inner { params: DidChangeConfigurationParams, ) { let mark = self.performance.mark("did_change_configuration"); - let config = if self.config.client_capabilities.workspace_configuration { - self - .client - .configuration(vec![ConfigurationItem { - scope_uri: None, - section: Some("deno".to_string()), - }]) - .await - .map(|vec| vec.get(0).cloned()) - .unwrap_or_else(|err| { - error!("failed to fetch the extension settings {}", err); - None - }) - } else { - params - .settings - .as_object() - .map(|settings| settings.get("deno")) - .flatten() - .cloned() - }; - if let Some(config) = config { - if let Err(err) = self.config.update(config) { - error!("failed to update settings: {}", err); - } - if let Err(err) = self.update_import_map().await { - self - .client - .show_message(MessageType::Warning, err.to_string()) - .await; - } - if let Err(err) = self.update_registries().await { - self - .client - .show_message(MessageType::Warning, err.to_string()) - .await; - } - if let Err(err) = self.update_tsconfig().await { - self - .client - .show_message(MessageType::Warning, err.to_string()) - .await; + if self.config.client_capabilities.workspace_configuration { + let specifiers: Vec<ModuleSpecifier> = + self.config.specifier_settings.keys().cloned().collect(); + let mut snapshot = self.snapshot(); + let mut config_items = specifiers + .iter() + .map(|s| ConfigurationItem { + scope_uri: Some(snapshot.url_map.normalize_specifier(s).unwrap()), + section: Some(SETTINGS_SECTION.to_string()), + }) + .collect(); + let mut items = vec![ConfigurationItem { + scope_uri: None, + section: Some(SETTINGS_SECTION.to_string()), + }]; + items.append(&mut config_items); + if let Ok(configs) = self.client.configuration(items).await { + for (i, value) in configs.into_iter().enumerate() { + if let Err(err) = match i { + 0 => self.config.update_workspace(value), + _ => self + .config + .update_specifier(specifiers[i - 1].clone(), value), + } { + error!("failed to update settings: {}", err); + } + } } - if let Err(err) = self.diagnostics_server.update() { - error!("{}", err); + } else if let Some(config) = params + .settings + .as_object() + .map(|settings| settings.get(SETTINGS_SECTION)) + .flatten() + .cloned() + { + if let Err(err) = self.config.update_workspace(config) { + error!("failed to update settings: {}", err); } - } else { - error!("received empty extension settings from the client"); } + + if let Err(err) = self.update_import_map().await { + self + .client + .show_message(MessageType::Warning, err.to_string()) + .await; + } + if let Err(err) = self.update_registries().await { + self + .client + .show_message(MessageType::Warning, err.to_string()) + .await; + } + if let Err(err) = self.update_tsconfig().await { + self + .client + .show_message(MessageType::Warning, err.to_string()) + .await; + } + if let Err(err) = self.diagnostics_server.update() { + error!("{}", err); + } + self.performance.measure(mark); } @@ -719,14 +760,14 @@ impl Inner { } async fn document_symbol( - &self, + &mut self, params: DocumentSymbolParams, ) -> LspResult<Option<DocumentSymbolResponse>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("document_symbol"); - let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -817,14 +858,15 @@ impl Inner { } } - async fn hover(&self, params: HoverParams) -> LspResult<Option<Hover>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("hover"); + async fn hover(&mut self, params: HoverParams) -> LspResult<Option<Hover>> { let specifier = self .url_map .normalize_url(¶ms.text_document_position_params.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("hover"); + let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { line_index @@ -860,12 +902,12 @@ impl Inner { &mut self, params: CodeActionParams, ) -> LspResult<Option<CodeActionResponse>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("code_action"); - let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let fixable_diagnostics: Vec<&Diagnostic> = params .context .diagnostics @@ -1016,12 +1058,14 @@ impl Inner { &mut self, params: CodeLensParams, ) -> LspResult<Option<Vec<CodeLens>>> { - if !self.enabled() || !self.config.settings.enabled_code_lens() { + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + if !self.config.specifier_enabled(&specifier) + || !self.config.workspace_settings.enabled_code_lens() + { return Ok(None); } let mark = self.performance.mark("code_lens"); - let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let line_index = self.get_line_index_sync(&specifier).unwrap(); let navigation_tree = self.get_navigation_tree(&specifier).await.map_err(|err| { @@ -1037,7 +1081,7 @@ impl Inner { let mut code_lenses = cl.borrow_mut(); // TSC Implementations Code Lens - if self.config.settings.code_lens.implementations { + if self.config.workspace_settings.code_lens.implementations { let source = CodeLensSource::Implementations; match i.kind { tsc::ScriptElementKind::InterfaceElement => { @@ -1061,7 +1105,7 @@ impl Inner { } // TSC References Code Lens - if self.config.settings.code_lens.references { + if self.config.workspace_settings.code_lens.references { let source = CodeLensSource::References; if let Some(parent) = &mp { if parent.kind == tsc::ScriptElementKind::EnumElement { @@ -1070,7 +1114,12 @@ impl Inner { } match i.kind { tsc::ScriptElementKind::FunctionElement => { - if self.config.settings.code_lens.references_all_functions { + if self + .config + .workspace_settings + .code_lens + .references_all_functions + { code_lenses.push(i.to_code_lens( &line_index, &specifier, @@ -1317,16 +1366,17 @@ impl Inner { } async fn document_highlight( - &self, + &mut self, params: DocumentHighlightParams, ) -> LspResult<Option<Vec<DocumentHighlight>>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("document_highlight"); let specifier = self .url_map .normalize_url(¶ms.text_document_position_params.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + + let mark = self.performance.mark("document_highlight"); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { line_index @@ -1369,13 +1419,13 @@ impl Inner { &mut self, params: ReferenceParams, ) -> LspResult<Option<Vec<Location>>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("references"); let specifier = self .url_map .normalize_url(¶ms.text_document_position.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("references"); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { line_index @@ -1424,13 +1474,13 @@ impl Inner { &mut self, params: GotoDefinitionParams, ) -> LspResult<Option<GotoDefinitionResponse>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("goto_definition"); let specifier = self .url_map .normalize_url(¶ms.text_document_position_params.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("goto_definition"); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { line_index @@ -1464,16 +1514,16 @@ impl Inner { } async fn completion( - &self, + &mut self, params: CompletionParams, ) -> LspResult<Option<CompletionResponse>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("completion"); let specifier = self .url_map .normalize_url(¶ms.text_document_position.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("completion"); // Import specifiers are something wholly internal to Deno, so for // completions, we will use internal logic and if there are completions // for imports, we will return those and not send a message into tsc, where @@ -1526,7 +1576,7 @@ impl Inner { if let Some(completions) = maybe_completion_info { let results = completions.as_completion_response( &line_index, - &self.config.settings.suggest, + &self.config.workspace_settings.suggest, &specifier, position, ); @@ -1583,13 +1633,13 @@ impl Inner { &mut self, params: GotoImplementationParams, ) -> LspResult<Option<GotoImplementationResponse>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("goto_implementation"); let specifier = self .url_map .normalize_url(¶ms.text_document_position_params.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("goto_implementation"); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { line_index @@ -1630,14 +1680,14 @@ impl Inner { } async fn folding_range( - &self, + &mut self, params: FoldingRangeParams, ) -> LspResult<Option<Vec<FoldingRange>>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("folding_range"); - let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -1690,11 +1740,11 @@ impl Inner { &mut self, params: CallHierarchyIncomingCallsParams, ) -> LspResult<Option<Vec<CallHierarchyIncomingCall>>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.item.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("incoming_calls"); - let specifier = self.url_map.normalize_url(¶ms.item.uri); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -1744,11 +1794,11 @@ impl Inner { &mut self, params: CallHierarchyOutgoingCallsParams, ) -> LspResult<Option<Vec<CallHierarchyOutgoingCall>>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.item.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("outgoing_calls"); - let specifier = self.url_map.normalize_url(¶ms.item.uri); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -1799,13 +1849,13 @@ impl Inner { &mut self, params: CallHierarchyPrepareParams, ) -> LspResult<Option<Vec<CallHierarchyItem>>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("prepare_call_hierarchy"); let specifier = self .url_map .normalize_url(¶ms.text_document_position_params.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("prepare_call_hierarchy"); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -1876,13 +1926,13 @@ impl Inner { &mut self, params: RenameParams, ) -> LspResult<Option<WorkspaceEdit>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("rename"); let specifier = self .url_map .normalize_url(¶ms.text_document_position.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("rename"); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -1963,14 +2013,14 @@ impl Inner { } async fn selection_range( - &self, + &mut self, params: SelectionRangeParams, ) -> LspResult<Option<Vec<SelectionRange>>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("selection_range"); - let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -2005,14 +2055,14 @@ impl Inner { } async fn semantic_tokens_full( - &self, + &mut self, params: SemanticTokensParams, ) -> LspResult<Option<SemanticTokensResult>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("semantic_tokens_full"); - let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -2052,14 +2102,14 @@ impl Inner { } async fn semantic_tokens_range( - &self, + &mut self, params: SemanticTokensRangeParams, ) -> LspResult<Option<SemanticTokensRangeResult>> { - if !self.enabled() { + let specifier = self.url_map.normalize_url(¶ms.text_document.uri); + if !self.config.specifier_enabled(&specifier) { return Ok(None); } let mark = self.performance.mark("semantic_tokens_range"); - let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { @@ -2098,16 +2148,16 @@ impl Inner { } async fn signature_help( - &self, + &mut self, params: SignatureHelpParams, ) -> LspResult<Option<SignatureHelp>> { - if !self.enabled() { - return Ok(None); - } - let mark = self.performance.mark("signature_help"); let specifier = self .url_map .normalize_url(¶ms.text_document_position_params.text_document.uri); + if !self.config.specifier_enabled(&specifier) { + return Ok(None); + } + let mark = self.performance.mark("signature_help"); let line_index = if let Some(line_index) = self.get_line_index_sync(&specifier) { line_index |