summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2024-05-29 21:31:09 +0100
committerGitHub <noreply@github.com>2024-05-29 21:31:09 +0100
commit3d3722507e1964cba66161e3e2e7b538bc23f29c (patch)
tree29cf6f83f1ee97a2a9477c45d1572ba9078104f4 /cli
parent3c3076a84ce84f7f9b5db5f476db8ee878eb603b (diff)
perf(repl): don't walk workspace in repl language server (#24037)
Diffstat (limited to 'cli')
-rw-r--r--cli/lsp/config.rs126
-rw-r--r--cli/lsp/documents.rs2
-rw-r--r--cli/lsp/language_server.rs32
-rw-r--r--cli/lsp/tsc.rs6
4 files changed, 86 insertions, 80 deletions
diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs
index 43b8a5fb7..364999cff 100644
--- a/cli/lsp/config.rs
+++ b/cli/lsp/config.rs
@@ -31,6 +31,7 @@ use deno_runtime::fs_util::specifier_to_file_path;
use deno_runtime::permissions::PermissionsContainer;
use import_map::ImportMap;
use lsp::Url;
+use lsp_types::ClientCapabilities;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::collections::HashMap;
@@ -40,21 +41,6 @@ use tower_lsp::lsp_types as lsp;
pub const SETTINGS_SECTION: &str = "deno";
-#[derive(Debug, Clone, Default)]
-pub struct ClientCapabilities {
- pub code_action_disabled_support: bool,
- pub line_folding_only: bool,
- pub snippet_support: bool,
- pub status_notification: bool,
- /// The client provides the `experimental.testingApi` capability, which is
- /// built around VSCode's testing API. It indicates that the server should
- /// send notifications about tests discovered in modules.
- pub testing_api: bool,
- pub workspace_configuration: bool,
- pub workspace_did_change_watched_files: bool,
- pub workspace_will_rename_files: bool,
-}
-
fn is_true() -> bool {
true
}
@@ -975,57 +961,73 @@ impl Config {
&self.settings.unscoped.internal_inspect
}
- pub fn update_capabilities(
+ pub fn set_client_capabilities(
&mut self,
- capabilities: &lsp::ClientCapabilities,
+ client_capabilities: ClientCapabilities,
) {
- if let Some(experimental) = &capabilities.experimental {
- self.client_capabilities.status_notification = experimental
- .get("statusNotification")
- .and_then(|it| it.as_bool())
- == Some(true);
- self.client_capabilities.testing_api =
- experimental.get("testingApi").and_then(|it| it.as_bool())
- == Some(true);
- }
+ self.client_capabilities = client_capabilities;
+ }
- if let Some(workspace) = &capabilities.workspace {
- self.client_capabilities.workspace_configuration =
- workspace.configuration.unwrap_or(false);
- self.client_capabilities.workspace_did_change_watched_files = workspace
- .did_change_watched_files
- .and_then(|it| it.dynamic_registration)
- .unwrap_or(false);
- if let Some(file_operations) = &workspace.file_operations {
- if let Some(true) = file_operations.dynamic_registration {
- self.client_capabilities.workspace_will_rename_files =
- file_operations.will_rename.unwrap_or(false);
- }
- }
- }
+ pub fn workspace_capable(&self) -> bool {
+ self.client_capabilities.workspace.is_some()
+ }
- if let Some(text_document) = &capabilities.text_document {
- self.client_capabilities.line_folding_only = text_document
- .folding_range
- .as_ref()
- .and_then(|it| it.line_folding_only)
- .unwrap_or(false);
- self.client_capabilities.code_action_disabled_support = text_document
- .code_action
- .as_ref()
- .and_then(|it| it.disabled_support)
- .unwrap_or(false);
- self.client_capabilities.snippet_support =
- if let Some(completion) = &text_document.completion {
- completion
- .completion_item
- .as_ref()
- .and_then(|it| it.snippet_support)
- .unwrap_or(false)
- } else {
- false
- };
- }
+ pub fn workspace_configuration_capable(&self) -> bool {
+ (|| self.client_capabilities.workspace.as_ref()?.configuration)()
+ .unwrap_or(false)
+ }
+
+ pub fn did_change_watched_files_capable(&self) -> bool {
+ (|| {
+ let workspace = self.client_capabilities.workspace.as_ref()?;
+ let did_change_watched_files =
+ workspace.did_change_watched_files.as_ref()?;
+ did_change_watched_files.dynamic_registration
+ })()
+ .unwrap_or(false)
+ }
+
+ pub fn will_rename_files_capable(&self) -> bool {
+ (|| {
+ let workspace = self.client_capabilities.workspace.as_ref()?;
+ let file_operations = workspace.file_operations.as_ref()?;
+ file_operations.dynamic_registration.filter(|d| *d)?;
+ file_operations.will_rename
+ })()
+ .unwrap_or(false)
+ }
+
+ pub fn line_folding_only_capable(&self) -> bool {
+ (|| {
+ let text_document = self.client_capabilities.text_document.as_ref()?;
+ text_document.folding_range.as_ref()?.line_folding_only
+ })()
+ .unwrap_or(false)
+ }
+
+ pub fn code_action_disabled_capable(&self) -> bool {
+ (|| {
+ let text_document = self.client_capabilities.text_document.as_ref()?;
+ text_document.code_action.as_ref()?.disabled_support
+ })()
+ .unwrap_or(false)
+ }
+
+ pub fn snippet_support_capable(&self) -> bool {
+ (|| {
+ let text_document = self.client_capabilities.text_document.as_ref()?;
+ let completion = text_document.completion.as_ref()?;
+ completion.completion_item.as_ref()?.snippet_support
+ })()
+ .unwrap_or(false)
+ }
+
+ pub fn testing_api_capable(&self) -> bool {
+ (|| {
+ let experimental = self.client_capabilities.experimental.as_ref()?;
+ experimental.get("testingApi")?.as_bool()
+ })()
+ .unwrap_or(false)
}
}
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs
index 5a94daed7..7cf839a69 100644
--- a/cli/lsp/documents.rs
+++ b/cli/lsp/documents.rs
@@ -226,7 +226,7 @@ fn get_maybe_test_module_fut(
maybe_parsed_source: Option<&ParsedSourceResult>,
config: &Config,
) -> Option<TestModuleFut> {
- if !config.client_capabilities.testing_api {
+ if !config.testing_api_capable() {
return None;
}
let parsed_source = maybe_parsed_source?.as_ref().ok()?.clone();
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index 5f79bca32..f0f730946 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -439,7 +439,7 @@ impl LanguageServer {
(
inner.client.clone(),
inner.config.workspace_folders.clone(),
- inner.config.client_capabilities.workspace_configuration,
+ inner.config.workspace_configuration_capable(),
)
};
if capable {
@@ -769,7 +769,7 @@ impl Inner {
vec![],
);
}
- self.config.update_capabilities(&params.capabilities);
+ self.config.set_client_capabilities(params.capabilities);
}
self.diagnostics_server.start();
@@ -802,6 +802,10 @@ impl Inner {
}
fn walk_workspace(config: &Config) -> (BTreeSet<ModuleSpecifier>, bool) {
+ if !config.workspace_capable() {
+ log::debug!("Skipped workspace walk due to client incapability.");
+ return (Default::default(), false);
+ }
let mut workspace_files = Default::default();
let entry_limit = 1000;
let mut pending = VecDeque::new();
@@ -1664,10 +1668,10 @@ impl Inner {
.map(CodeActionOrCommand::CodeAction),
);
- let code_action_disabled_support =
- self.config.client_capabilities.code_action_disabled_support;
+ let code_action_disabled_capable =
+ self.config.code_action_disabled_capable();
let actions: Vec<CodeActionOrCommand> = all_actions.into_iter().filter(|ca| {
- code_action_disabled_support
+ code_action_disabled_capable
|| matches!(ca, CodeActionOrCommand::CodeAction(ca) if ca.disabled.is_none())
}).collect();
let response = if actions.is_empty() {
@@ -2318,7 +2322,7 @@ impl Inner {
span.to_folding_range(
asset_or_doc.line_index(),
asset_or_doc.text().as_bytes(),
- self.config.client_capabilities.line_folding_only,
+ self.config.line_folding_only_capable(),
)
})
.collect::<Vec<FoldingRange>>(),
@@ -2887,11 +2891,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
inner.refresh_documents_config().await;
inner.task_queue.start(self.clone());
self.init_flag.raise();
- if inner
- .config
- .client_capabilities
- .workspace_did_change_watched_files
- {
+ if inner.config.did_change_watched_files_capable() {
// we are going to watch all the JSON files in the workspace, and the
// notification handler will pick up any of the changes of those files we
// are interested in.
@@ -2909,7 +2909,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
register_options: Some(serde_json::to_value(options).unwrap()),
});
}
- if inner.config.client_capabilities.workspace_will_rename_files {
+ if inner.config.will_rename_files_capable() {
let options = FileOperationRegistrationOptions {
filters: vec![FileOperationFilter {
scheme: Some("file".to_string()),
@@ -2927,7 +2927,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
});
}
- if inner.config.client_capabilities.testing_api {
+ if inner.config.testing_api_capable() {
let test_server = testing::TestServer::new(
inner.client.clone(),
inner.performance.clone(),
@@ -3051,7 +3051,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
};
self.refresh_configuration().await;
let mut inner = self.inner.write().await;
- if !inner.config.client_capabilities.workspace_configuration {
+ if !inner.config.workspace_configuration_capable() {
let config = params.settings.as_object().map(|settings| {
let deno =
serde_json::to_value(settings.get(SETTINGS_SECTION)).unwrap();
@@ -3726,6 +3726,10 @@ mod tests {
temp_dir.uri().join("root2/").unwrap(),
temp_dir.uri().join("root3/").unwrap(),
]);
+ config.set_client_capabilities(ClientCapabilities {
+ workspace: Some(Default::default()),
+ ..Default::default()
+ });
config.set_workspace_settings(
Default::default(),
vec![
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs
index ebd3fc973..76a33a532 100644
--- a/cli/lsp/tsc.rs
+++ b/cli/lsp/tsc.rs
@@ -4679,7 +4679,7 @@ impl UserPreferences {
// TODO(nayeemrmn): Investigate why we use `Index` here.
import_module_specifier_ending: Some(ImportModuleSpecifierEnding::Index),
include_completions_with_snippet_text: Some(
- config.client_capabilities.snippet_support,
+ config.snippet_support_capable(),
),
provide_refactor_not_applicable_reason: Some(true),
quote_preference: Some(fmt_config.into()),
@@ -4717,7 +4717,7 @@ impl UserPreferences {
include_completions_with_class_member_snippets: Some(
language_settings.suggest.enabled
&& language_settings.suggest.class_member_snippets.enabled
- && config.client_capabilities.snippet_support,
+ && config.snippet_support_capable(),
),
include_completions_with_insert_text: Some(
language_settings.suggest.enabled,
@@ -4728,7 +4728,7 @@ impl UserPreferences {
.suggest
.object_literal_method_snippets
.enabled
- && config.client_capabilities.snippet_support,
+ && config.snippet_support_capable(),
),
import_module_specifier_preference: Some(
language_settings.preferences.import_module_specifier,