diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2021-08-10 09:56:34 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-10 09:56:34 +1000 |
commit | f7e416bc7fbb8b1bc17e180d5aeb2e4f00256bea (patch) | |
tree | 517ef875abed324587167c6001ac25be050dd7da | |
parent | 2db381eba9768acf855219ec9560e20a62659994 (diff) |
feat(lsp): support clients which do not support disabled code actions (#11612)
Closes: #11610
-rw-r--r-- | cli/lsp/config.rs | 8 | ||||
-rw-r--r-- | cli/lsp/language_server.rs | 13 | ||||
-rw-r--r-- | cli/tests/integration/lsp_tests.rs | 48 | ||||
-rw-r--r-- | cli/tests/lsp/code_action_params_refactor.json | 6 | ||||
-rw-r--r-- | cli/tests/lsp/code_action_response_no_disabled.json | 22 | ||||
-rw-r--r-- | cli/tests/lsp/code_action_response_refactor.json | 130 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params.json | 4 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_bad_config_option.json | 4 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_ca_no_disabled.json | 64 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_code_lens_test.json | 4 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_code_lens_test_disabled.json | 4 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_did_config_change.json | 4 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_disabled.json | 4 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_registry.json | 4 | ||||
-rw-r--r-- | cli/tests/lsp/initialize_params_unstable.json | 4 |
15 files changed, 253 insertions, 70 deletions
diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index a58a8d1ae..ff3d73f0f 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -24,10 +24,11 @@ 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 status_notification: bool, pub workspace_configuration: bool, pub workspace_did_change_watched_files: bool, - pub line_folding_only: bool, } fn is_true() -> bool { @@ -395,6 +396,11 @@ impl Config { .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); } } diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 8d672e251..9fbe6be5d 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1298,11 +1298,18 @@ impl Inner { .map(CodeActionOrCommand::CodeAction), ); - let response = if !all_actions.is_empty() { - Some(all_actions) - } else { + let code_action_disabled_support = + self.config.client_capabilities.code_action_disabled_support; + let actions: Vec<CodeActionOrCommand> = all_actions.into_iter().filter(|ca| { + code_action_disabled_support + || matches!(ca, CodeActionOrCommand::CodeAction(ca) if ca.disabled.is_none()) + }).collect(); + let response = if actions.is_empty() { None + } else { + Some(actions) }; + self.performance.measure(mark); Ok(response) } diff --git a/cli/tests/integration/lsp_tests.rs b/cli/tests/integration/lsp_tests.rs index a27ebec45..518dfe850 100644 --- a/cli/tests/integration/lsp_tests.rs +++ b/cli/tests/integration/lsp_tests.rs @@ -2155,6 +2155,54 @@ fn lsp_code_actions_refactor() { } #[test] +fn lsp_code_actions_refactor_no_disabled_support() { + let mut client = init("initialize_params_ca_no_disabled.json"); + did_open( + &mut client, + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "interface A {\n a: string;\n}\n\ninterface B {\n b: string;\n}\n\nclass AB implements A, B {\n a = \"a\";\n b = \"b\";\n}\n\nnew AB().a;\n" + } + }), + ); + let (maybe_res, maybe_err) = client + .write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 14, + "character": 0 + } + }, + "context": { + "diagnostics": [], + "only": [ + "refactor" + ] + } + }), + ) + .unwrap(); + assert!(maybe_err.is_none()); + assert_eq!( + maybe_res, + Some(load_fixture("code_action_response_no_disabled.json")) + ); + shutdown(&mut client); +} + +#[test] fn lsp_code_actions_deadlock() { let mut client = init("initialize_params.json"); client diff --git a/cli/tests/lsp/code_action_params_refactor.json b/cli/tests/lsp/code_action_params_refactor.json index 9fe359498..121c400ed 100644 --- a/cli/tests/lsp/code_action_params_refactor.json +++ b/cli/tests/lsp/code_action_params_refactor.json @@ -5,11 +5,11 @@ "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, "context": { diff --git a/cli/tests/lsp/code_action_response_no_disabled.json b/cli/tests/lsp/code_action_response_no_disabled.json new file mode 100644 index 000000000..c69bd1120 --- /dev/null +++ b/cli/tests/lsp/code_action_response_no_disabled.json @@ -0,0 +1,22 @@ +[ + { + "title": "Move to a new file", + "kind": "refactor.move.newFile", + "isPreferred": false, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 14, + "character": 0 + } + }, + "refactorName": "Move to a new file", + "actionName": "Move to a new file" + } + } +] diff --git a/cli/tests/lsp/code_action_response_refactor.json b/cli/tests/lsp/code_action_response_refactor.json index 87f354e37..a9fbd2827 100644 --- a/cli/tests/lsp/code_action_response_refactor.json +++ b/cli/tests/lsp/code_action_response_refactor.json @@ -1,139 +1,136 @@ [ { - "title": "Extract to type alias", - "kind": "refactor.extract.type", - "isPreferred": true, + "title": "Extract to function in global scope", + "kind": "refactor.extract.function", + "isPreferred": false, "data": { "specifier": "file:///a/file.ts", "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, - "refactorName": "Extract type", - "actionName": "Extract to type alias" + "refactorName": "Extract Symbol", + "actionName": "function_scope_0" } }, { - "title": "Extract to interface", - "kind": "refactor.extract.interface", - "isPreferred": true, + "title": "Extract to constant in enclosing scope", + "kind": "refactor.extract.constant", + "isPreferred": false, "data": { "specifier": "file:///a/file.ts", "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, - "refactorName": "Extract type", - "actionName": "Extract to interface" + "refactorName": "Extract Symbol", + "actionName": "constant_scope_0" } }, { - "title": "Extract function", - "kind": "refactor.extract.function", + "title": "Move to a new file", + "kind": "refactor.move.newFile", "isPreferred": false, - "disabled": { - "reason": "Statement or expression expected." - }, "data": { "specifier": "file:///a/file.ts", "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, - "refactorName": "Extract Symbol", - "actionName": "Extract Function" + "refactorName": "Move to a new file", + "actionName": "Move to a new file" } }, { - "title": "Extract constant", - "kind": "refactor.extract.constant", + "title": "Convert default export to named export", + "kind": "refactor.rewrite.export.named", "isPreferred": false, "disabled": { - "reason": "Statement or expression expected." + "reason": "This file already has a default export" }, "data": { "specifier": "file:///a/file.ts", "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, - "refactorName": "Extract Symbol", - "actionName": "Extract Constant" + "refactorName": "Convert export", + "actionName": "Convert default export to named export" } }, { - "title": "Convert default export to named export", - "kind": "refactor.rewrite.export.named", + "title": "Convert named export to default export", + "kind": "refactor.rewrite.export.default", "isPreferred": false, "disabled": { - "reason": "Could not find export statement" + "reason": "This file already has a default export" }, "data": { "specifier": "file:///a/file.ts", "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, "refactorName": "Convert export", - "actionName": "Convert default export to named export" + "actionName": "Convert named export to default export" } }, { - "title": "Convert named export to default export", - "kind": "refactor.rewrite.export.default", + "title": "Convert namespace import to named imports", + "kind": "refactor.rewrite.import.named", "isPreferred": false, "disabled": { - "reason": "Could not find export statement" + "reason": "Selection is not an import declaration." }, "data": { "specifier": "file:///a/file.ts", "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, - "refactorName": "Convert export", - "actionName": "Convert named export to default export" + "refactorName": "Convert import", + "actionName": "Convert namespace import to named imports" } }, { - "title": "Convert namespace import to named imports", - "kind": "refactor.rewrite.import.named", + "title": "Convert named imports to namespace import", + "kind": "refactor.rewrite.import.namespace", "isPreferred": false, "disabled": { "reason": "Selection is not an import declaration." @@ -143,15 +140,38 @@ "range": { "start": { "line": 0, - "character": 7 + "character": 0 }, "end": { - "line": 0, - "character": 33 + "line": 1, + "character": 0 } }, "refactorName": "Convert import", - "actionName": "Convert namespace import to named imports" + "actionName": "Convert named imports to namespace import" + } + }, + { + "title": "Convert to optional chain expression", + "kind": "refactor.rewrite.expression.optionalChain", + "isPreferred": false, + "disabled": { + "reason": "Could not find convertible access expression" + }, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 1, + "character": 0 + } + }, + "refactorName": "Convert to optional chain expression", + "actionName": "Convert to optional chain expression" } } ] diff --git a/cli/tests/lsp/initialize_params.json b/cli/tests/lsp/initialize_params.json index 27711efd0..3b99be4f0 100644 --- a/cli/tests/lsp/initialize_params.json +++ b/cli/tests/lsp/initialize_params.json @@ -33,12 +33,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" diff --git a/cli/tests/lsp/initialize_params_bad_config_option.json b/cli/tests/lsp/initialize_params_bad_config_option.json index cfe40acec..053cb70f3 100644 --- a/cli/tests/lsp/initialize_params_bad_config_option.json +++ b/cli/tests/lsp/initialize_params_bad_config_option.json @@ -33,12 +33,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" diff --git a/cli/tests/lsp/initialize_params_ca_no_disabled.json b/cli/tests/lsp/initialize_params_ca_no_disabled.json new file mode 100644 index 000000000..3df87aded --- /dev/null +++ b/cli/tests/lsp/initialize_params_ca_no_disabled.json @@ -0,0 +1,64 @@ +{ + "processId": 0, + "clientInfo": { + "name": "test-harness", + "version": "1.0.0" + }, + "rootUri": null, + "initializationOptions": { + "enable": true, + "cache": null, + "codeLens": { + "implementations": true, + "references": true, + "test": true + }, + "config": "", + "importMap": null, + "lint": true, + "suggest": { + "autoImports": true, + "completeFunctionCalls": false, + "names": true, + "paths": true, + "imports": { + "hosts": {} + } + }, + "unstable": false + }, + "capabilities": { + "textDocument": { + "codeAction": { + "codeActionLiteralSupport": { + "codeActionKind": { + "valueSet": [ + "quickfix", + "refactor" + ] + } + }, + "isPreferredSupport": true, + "dataSupport": true, + "resolveSupport": { + "properties": [ + "edit" + ] + } + }, + "foldingRange": { + "lineFoldingOnly": true + }, + "synchronization": { + "dynamicRegistration": true, + "willSave": true, + "willSaveWaitUntil": true, + "didSave": true + } + }, + "workspace": { + "configuration": true, + "workspaceFolders": true + } + } +} diff --git a/cli/tests/lsp/initialize_params_code_lens_test.json b/cli/tests/lsp/initialize_params_code_lens_test.json index fb803c04f..bdd01bfca 100644 --- a/cli/tests/lsp/initialize_params_code_lens_test.json +++ b/cli/tests/lsp/initialize_params_code_lens_test.json @@ -27,12 +27,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" diff --git a/cli/tests/lsp/initialize_params_code_lens_test_disabled.json b/cli/tests/lsp/initialize_params_code_lens_test_disabled.json index c4d5e42f8..1d18934ae 100644 --- a/cli/tests/lsp/initialize_params_code_lens_test_disabled.json +++ b/cli/tests/lsp/initialize_params_code_lens_test_disabled.json @@ -32,12 +32,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" diff --git a/cli/tests/lsp/initialize_params_did_config_change.json b/cli/tests/lsp/initialize_params_did_config_change.json index b5cec8499..870ad6e0f 100644 --- a/cli/tests/lsp/initialize_params_did_config_change.json +++ b/cli/tests/lsp/initialize_params_did_config_change.json @@ -33,12 +33,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" diff --git a/cli/tests/lsp/initialize_params_disabled.json b/cli/tests/lsp/initialize_params_disabled.json index 349cc6ae3..879b1181c 100644 --- a/cli/tests/lsp/initialize_params_disabled.json +++ b/cli/tests/lsp/initialize_params_disabled.json @@ -31,12 +31,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" diff --git a/cli/tests/lsp/initialize_params_registry.json b/cli/tests/lsp/initialize_params_registry.json index e98a62f7f..67559ebb3 100644 --- a/cli/tests/lsp/initialize_params_registry.json +++ b/cli/tests/lsp/initialize_params_registry.json @@ -33,12 +33,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" diff --git a/cli/tests/lsp/initialize_params_unstable.json b/cli/tests/lsp/initialize_params_unstable.json index e18b6ba8b..104db16f2 100644 --- a/cli/tests/lsp/initialize_params_unstable.json +++ b/cli/tests/lsp/initialize_params_unstable.json @@ -31,12 +31,14 @@ "codeActionLiteralSupport": { "codeActionKind": { "valueSet": [ - "quickfix" + "quickfix", + "refactor" ] } }, "isPreferredSupport": true, "dataSupport": true, + "disabledSupport": true, "resolveSupport": { "properties": [ "edit" |