aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-11-10 17:20:01 +0000
committerAleksey Kladov <[email protected]>2020-11-10 17:48:46 +0000
commit7d2eb000b078143e9fa6225d00ef52fc7c606fdf (patch)
tree580d90bd250ffcd4b1c66570e5601761e58d1057 /crates
parentada5a88f8fd0a79af7ad6e0411acc1cce9ef32d5 (diff)
Switch to upstream protocol for resolving code action
Note that we have to maintain custom implementation on the client side: I don't see how to marry bulitin resolve support with groups and snippets.
Diffstat (limited to 'crates')
-rw-r--r--crates/rust-analyzer/src/caps.rs6
-rw-r--r--crates/rust-analyzer/src/config.rs11
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt2
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt2
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt2
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt2
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs2
-rw-r--r--crates/rust-analyzer/src/handlers.rs23
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs35
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
-rw-r--r--crates/rust-analyzer/src/to_proto.rs26
11 files changed, 67 insertions, 46 deletions
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index ff1ae9575..9a8870053 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -16,8 +16,6 @@ use serde_json::json;
16use crate::semantic_tokens; 16use crate::semantic_tokens;
17 17
18pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities { 18pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
19 let code_action_provider = code_action_capabilities(client_caps);
20
21 ServerCapabilities { 19 ServerCapabilities {
22 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { 20 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
23 open_close: Some(true), 21 open_close: Some(true),
@@ -49,7 +47,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
49 document_highlight_provider: Some(OneOf::Left(true)), 47 document_highlight_provider: Some(OneOf::Left(true)),
50 document_symbol_provider: Some(OneOf::Left(true)), 48 document_symbol_provider: Some(OneOf::Left(true)),
51 workspace_symbol_provider: Some(OneOf::Left(true)), 49 workspace_symbol_provider: Some(OneOf::Left(true)),
52 code_action_provider: Some(code_action_provider), 50 code_action_provider: Some(code_action_capabilities(client_caps)),
53 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), 51 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
54 document_formatting_provider: Some(OneOf::Left(true)), 52 document_formatting_provider: Some(OneOf::Left(true)),
55 document_range_formatting_provider: None, 53 document_range_formatting_provider: None,
@@ -113,7 +111,7 @@ fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProvi
113 CodeActionKind::REFACTOR_INLINE, 111 CodeActionKind::REFACTOR_INLINE,
114 CodeActionKind::REFACTOR_REWRITE, 112 CodeActionKind::REFACTOR_REWRITE,
115 ]), 113 ]),
116 resolve_provider: None, 114 resolve_provider: Some(true),
117 work_done_progress_options: Default::default(), 115 work_done_progress_options: Default::default(),
118 }) 116 })
119 }) 117 })
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 2ed6a0d82..9cc14fe82 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -144,7 +144,7 @@ pub struct ClientCapsConfig {
144 pub code_action_literals: bool, 144 pub code_action_literals: bool,
145 pub work_done_progress: bool, 145 pub work_done_progress: bool,
146 pub code_action_group: bool, 146 pub code_action_group: bool,
147 pub resolve_code_action: bool, 147 pub code_action_resolve: bool,
148 pub hover_actions: bool, 148 pub hover_actions: bool,
149 pub status_notification: bool, 149 pub status_notification: bool,
150 pub signature_help_label_offsets: bool, 150 pub signature_help_label_offsets: bool,
@@ -383,6 +383,14 @@ impl Config {
383 } 383 }
384 } 384 }
385 } 385 }
386
387 if let Some(code_action) = &doc_caps.code_action {
388 if let Some(resolve_support) = &code_action.resolve_support {
389 if resolve_support.properties.iter().any(|it| it == "edit") {
390 self.client_caps.code_action_resolve = true;
391 }
392 }
393 }
386 } 394 }
387 395
388 if let Some(window_caps) = caps.window.as_ref() { 396 if let Some(window_caps) = caps.window.as_ref() {
@@ -400,7 +408,6 @@ impl Config {
400 self.assist.allow_snippets(snippet_text_edit); 408 self.assist.allow_snippets(snippet_text_edit);
401 409
402 self.client_caps.code_action_group = get_bool("codeActionGroup"); 410 self.client_caps.code_action_group = get_bool("codeActionGroup");
403 self.client_caps.resolve_code_action = get_bool("resolveCodeAction");
404 self.client_caps.hover_actions = get_bool("hoverActions"); 411 self.client_caps.hover_actions = get_bool("hoverActions");
405 self.client_caps.status_notification = get_bool("statusNotification"); 412 self.client_caps.status_notification = get_bool("statusNotification");
406 } 413 }
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
index 8dc53391e..a8d85f008 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
@@ -36,7 +36,6 @@
36 fixes: [ 36 fixes: [
37 CodeAction { 37 CodeAction {
38 title: "consider prefixing with an underscore", 38 title: "consider prefixing with an underscore",
39 id: None,
40 group: None, 39 group: None,
41 kind: Some( 40 kind: Some(
42 CodeActionKind( 41 CodeActionKind(
@@ -70,6 +69,7 @@
70 is_preferred: Some( 69 is_preferred: Some(
71 true, 70 true,
72 ), 71 ),
72 data: None,
73 }, 73 },
74 ], 74 ],
75 }, 75 },
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
index c8703194c..0b8937376 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
@@ -36,7 +36,6 @@
36 fixes: [ 36 fixes: [
37 CodeAction { 37 CodeAction {
38 title: "consider prefixing with an underscore", 38 title: "consider prefixing with an underscore",
39 id: None,
40 group: None, 39 group: None,
41 kind: Some( 40 kind: Some(
42 CodeActionKind( 41 CodeActionKind(
@@ -70,6 +69,7 @@
70 is_preferred: Some( 69 is_preferred: Some(
71 true, 70 true,
72 ), 71 ),
72 data: None,
73 }, 73 },
74 ], 74 ],
75 }, 75 },
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
index dc93227ad..7fa9dee62 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
@@ -36,7 +36,6 @@
36 fixes: [ 36 fixes: [
37 CodeAction { 37 CodeAction {
38 title: "consider prefixing with an underscore", 38 title: "consider prefixing with an underscore",
39 id: None,
40 group: None, 39 group: None,
41 kind: Some( 40 kind: Some(
42 CodeActionKind( 41 CodeActionKind(
@@ -70,6 +69,7 @@
70 is_preferred: Some( 69 is_preferred: Some(
71 true, 70 true,
72 ), 71 ),
72 data: None,
73 }, 73 },
74 ], 74 ],
75 }, 75 },
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
index 81f752672..3c97b2084 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
@@ -51,7 +51,6 @@
51 fixes: [ 51 fixes: [
52 CodeAction { 52 CodeAction {
53 title: "return the expression directly", 53 title: "return the expression directly",
54 id: None,
55 group: None, 54 group: None,
56 kind: Some( 55 kind: Some(
57 CodeActionKind( 56 CodeActionKind(
@@ -98,6 +97,7 @@
98 is_preferred: Some( 97 is_preferred: Some(
99 true, 98 true,
100 ), 99 ),
100 data: None,
101 }, 101 },
102 ], 102 ],
103 }, 103 },
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index b949577c1..15145415b 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -110,7 +110,6 @@ fn map_rust_child_diagnostic(
110 } else { 110 } else {
111 MappedRustChildDiagnostic::SuggestedFix(lsp_ext::CodeAction { 111 MappedRustChildDiagnostic::SuggestedFix(lsp_ext::CodeAction {
112 title: rd.message.clone(), 112 title: rd.message.clone(),
113 id: None,
114 group: None, 113 group: None,
115 kind: Some(lsp_types::CodeActionKind::QUICKFIX), 114 kind: Some(lsp_types::CodeActionKind::QUICKFIX),
116 edit: Some(lsp_ext::SnippetWorkspaceEdit { 115 edit: Some(lsp_ext::SnippetWorkspaceEdit {
@@ -119,6 +118,7 @@ fn map_rust_child_diagnostic(
119 document_changes: None, 118 document_changes: None,
120 }), 119 }),
121 is_preferred: Some(true), 120 is_preferred: Some(true),
121 data: None,
122 }) 122 })
123 } 123 }
124} 124}
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 049c583a4..95659b0db 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -806,11 +806,11 @@ fn handle_fixes(
806 let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?; 806 let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?;
807 let action = lsp_ext::CodeAction { 807 let action = lsp_ext::CodeAction {
808 title: fix.label.to_string(), 808 title: fix.label.to_string(),
809 id: None,
810 group: None, 809 group: None,
811 kind: Some(CodeActionKind::QUICKFIX), 810 kind: Some(CodeActionKind::QUICKFIX),
812 edit: Some(edit), 811 edit: Some(edit),
813 is_preferred: Some(false), 812 is_preferred: Some(false),
813 data: None,
814 }; 814 };
815 res.push(action); 815 res.push(action);
816 } 816 }
@@ -852,11 +852,11 @@ pub(crate) fn handle_code_action(
852 852
853 handle_fixes(&snap, &params, &mut res)?; 853 handle_fixes(&snap, &params, &mut res)?;
854 854
855 if snap.config.client_caps.resolve_code_action { 855 if snap.config.client_caps.code_action_resolve {
856 for (index, assist) in 856 for (index, assist) in
857 snap.analysis.unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate() 857 snap.analysis.unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate()
858 { 858 {
859 res.push(to_proto::unresolved_code_action(&snap, assist, index)?); 859 res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?);
860 } 860 }
861 } else { 861 } else {
862 for assist in snap.analysis.resolved_assists(&snap.config.assist, frange)?.into_iter() { 862 for assist in snap.analysis.resolved_assists(&snap.config.assist, frange)?.into_iter() {
@@ -867,11 +867,16 @@ pub(crate) fn handle_code_action(
867 Ok(Some(res)) 867 Ok(Some(res))
868} 868}
869 869
870pub(crate) fn handle_resolve_code_action( 870pub(crate) fn handle_code_action_resolve(
871 mut snap: GlobalStateSnapshot, 871 mut snap: GlobalStateSnapshot,
872 params: lsp_ext::ResolveCodeActionParams, 872 mut code_action: lsp_ext::CodeAction,
873) -> Result<Option<lsp_ext::SnippetWorkspaceEdit>> { 873) -> Result<lsp_ext::CodeAction> {
874 let _p = profile::span("handle_resolve_code_action"); 874 let _p = profile::span("handle_code_action_resolve");
875 let params = match code_action.data.take() {
876 Some(it) => it,
877 None => Err("can't resolve code action without data")?,
878 };
879
875 let file_id = from_proto::file_id(&snap, &params.code_action_params.text_document.uri)?; 880 let file_id = from_proto::file_id(&snap, &params.code_action_params.text_document.uri)?;
876 let line_index = snap.analysis.file_line_index(file_id)?; 881 let line_index = snap.analysis.file_line_index(file_id)?;
877 let range = from_proto::text_range(&line_index, params.code_action_params.range); 882 let range = from_proto::text_range(&line_index, params.code_action_params.range);
@@ -888,7 +893,9 @@ pub(crate) fn handle_resolve_code_action(
888 let index = index.parse::<usize>().unwrap(); 893 let index = index.parse::<usize>().unwrap();
889 let assist = &assists[index]; 894 let assist = &assists[index];
890 assert!(assist.assist.id.0 == id); 895 assert!(assist.assist.id.0 == id);
891 Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit) 896 let edit = to_proto::resolved_code_action(&snap, assist.clone())?.edit;
897 code_action.edit = edit;
898 Ok(code_action)
892} 899}
893 900
894pub(crate) fn handle_code_lens( 901pub(crate) fn handle_code_lens(
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index f31f8d900..a7c3028e4 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -113,22 +113,6 @@ pub struct JoinLinesParams {
113 pub ranges: Vec<Range>, 113 pub ranges: Vec<Range>,
114} 114}
115 115
116pub enum ResolveCodeActionRequest {}
117
118impl Request for ResolveCodeActionRequest {
119 type Params = ResolveCodeActionParams;
120 type Result = Option<SnippetWorkspaceEdit>;
121 const METHOD: &'static str = "experimental/resolveCodeAction";
122}
123
124/// Params for the ResolveCodeActionRequest
125#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
126#[serde(rename_all = "camelCase")]
127pub struct ResolveCodeActionParams {
128 pub code_action_params: lsp_types::CodeActionParams,
129 pub id: String,
130}
131
132pub enum OnEnter {} 116pub enum OnEnter {}
133 117
134impl Request for OnEnter { 118impl Request for OnEnter {
@@ -265,13 +249,18 @@ impl Request for CodeActionRequest {
265 const METHOD: &'static str = "textDocument/codeAction"; 249 const METHOD: &'static str = "textDocument/codeAction";
266} 250}
267 251
252pub enum CodeActionResolveRequest {}
253impl Request for CodeActionResolveRequest {
254 type Params = CodeAction;
255 type Result = CodeAction;
256 const METHOD: &'static str = "codeAction/resolve";
257}
258
268#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] 259#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
269#[serde(rename_all = "camelCase")] 260#[serde(rename_all = "camelCase")]
270pub struct CodeAction { 261pub struct CodeAction {
271 pub title: String, 262 pub title: String,
272 #[serde(skip_serializing_if = "Option::is_none")] 263 #[serde(skip_serializing_if = "Option::is_none")]
273 pub id: Option<String>,
274 #[serde(skip_serializing_if = "Option::is_none")]
275 pub group: Option<String>, 264 pub group: Option<String>,
276 #[serde(skip_serializing_if = "Option::is_none")] 265 #[serde(skip_serializing_if = "Option::is_none")]
277 pub kind: Option<CodeActionKind>, 266 pub kind: Option<CodeActionKind>,
@@ -282,6 +271,16 @@ pub struct CodeAction {
282 pub edit: Option<SnippetWorkspaceEdit>, 271 pub edit: Option<SnippetWorkspaceEdit>,
283 #[serde(skip_serializing_if = "Option::is_none")] 272 #[serde(skip_serializing_if = "Option::is_none")]
284 pub is_preferred: Option<bool>, 273 pub is_preferred: Option<bool>,
274
275 #[serde(skip_serializing_if = "Option::is_none")]
276 pub data: Option<CodeActionData>,
277}
278
279#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
280#[serde(rename_all = "camelCase")]
281pub struct CodeActionData {
282 pub code_action_params: lsp_types::CodeActionParams,
283 pub id: String,
285} 284}
286 285
287#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] 286#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index d504572a8..6e6cac42e 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -435,7 +435,7 @@ impl GlobalState {
435 .on::<lsp_ext::Runnables>(handlers::handle_runnables) 435 .on::<lsp_ext::Runnables>(handlers::handle_runnables)
436 .on::<lsp_ext::InlayHints>(handlers::handle_inlay_hints) 436 .on::<lsp_ext::InlayHints>(handlers::handle_inlay_hints)
437 .on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action) 437 .on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)
438 .on::<lsp_ext::ResolveCodeActionRequest>(handlers::handle_resolve_code_action) 438 .on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
439 .on::<lsp_ext::HoverRequest>(handlers::handle_hover) 439 .on::<lsp_ext::HoverRequest>(handlers::handle_hover)
440 .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs) 440 .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
441 .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting) 441 .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index f8ecd8e83..4bdf4bf0f 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -735,16 +735,20 @@ pub(crate) fn code_action_kind(kind: AssistKind) -> lsp_types::CodeActionKind {
735 735
736pub(crate) fn unresolved_code_action( 736pub(crate) fn unresolved_code_action(
737 snap: &GlobalStateSnapshot, 737 snap: &GlobalStateSnapshot,
738 code_action_params: lsp_types::CodeActionParams,
738 assist: Assist, 739 assist: Assist,
739 index: usize, 740 index: usize,
740) -> Result<lsp_ext::CodeAction> { 741) -> Result<lsp_ext::CodeAction> {
741 let res = lsp_ext::CodeAction { 742 let res = lsp_ext::CodeAction {
742 title: assist.label.to_string(), 743 title: assist.label.to_string(),
743 id: Some(format!("{}:{}", assist.id.0, index.to_string())),
744 group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), 744 group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
745 kind: Some(code_action_kind(assist.id.1)), 745 kind: Some(code_action_kind(assist.id.1)),
746 edit: None, 746 edit: None,
747 is_preferred: None, 747 is_preferred: None,
748 data: Some(lsp_ext::CodeActionData {
749 id: format!("{}:{}", assist.id.0, index.to_string()),
750 code_action_params,
751 }),
748 }; 752 };
749 Ok(res) 753 Ok(res)
750} 754}
@@ -754,13 +758,19 @@ pub(crate) fn resolved_code_action(
754 assist: ResolvedAssist, 758 assist: ResolvedAssist,
755) -> Result<lsp_ext::CodeAction> { 759) -> Result<lsp_ext::CodeAction> {
756 let change = assist.source_change; 760 let change = assist.source_change;
757 unresolved_code_action(snap, assist.assist, 0).and_then(|it| { 761 let res = lsp_ext::CodeAction {
758 Ok(lsp_ext::CodeAction { 762 edit: Some(snippet_workspace_edit(snap, change)?),
759 id: None, 763 title: assist.assist.label.to_string(),
760 edit: Some(snippet_workspace_edit(snap, change)?), 764 group: assist
761 ..it 765 .assist
762 }) 766 .group
763 }) 767 .filter(|_| snap.config.client_caps.code_action_group)
768 .map(|gr| gr.0),
769 kind: Some(code_action_kind(assist.assist.id.1)),
770 is_preferred: None,
771 data: None,
772 };
773 Ok(res)
764} 774}
765 775
766pub(crate) fn runnable( 776pub(crate) fn runnable(