diff options
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 38 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lsp_ext.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 4 | ||||
-rw-r--r-- | docs/dev/lsp-extensions.md | 3 |
4 files changed, 29 insertions, 18 deletions
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 0fd03bbaa..f6e40f872 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -1058,41 +1058,44 @@ pub(crate) fn handle_code_action_resolve( | |||
1058 | .only | 1058 | .only |
1059 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); | 1059 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); |
1060 | 1060 | ||
1061 | let assist_kind: AssistKind = match params.kind.parse() { | 1061 | let (assist_index, assist_resolve) = match parse_action_id(¶ms.id) { |
1062 | Ok(kind) => kind, | 1062 | Ok(parsed_data) => parsed_data, |
1063 | Err(e) => { | 1063 | Err(e) => { |
1064 | return Err(LspError::new( | 1064 | return Err(LspError::new( |
1065 | ErrorCode::InvalidParams as i32, | 1065 | ErrorCode::InvalidParams as i32, |
1066 | format!("For the assist to resolve, failed to parse the kind: {}", e), | 1066 | format!("Failed to parse action id string '{}': {}", params.id, e), |
1067 | ) | 1067 | ) |
1068 | .into()) | 1068 | .into()) |
1069 | } | 1069 | } |
1070 | }; | 1070 | }; |
1071 | 1071 | ||
1072 | let expected_assist_id = assist_resolve.assist_id.clone(); | ||
1073 | let expected_kind = assist_resolve.assist_kind; | ||
1074 | |||
1072 | let assists = snap.analysis.assists_with_fixes( | 1075 | let assists = snap.analysis.assists_with_fixes( |
1073 | &assists_config, | 1076 | &assists_config, |
1074 | &snap.config.diagnostics(), | 1077 | &snap.config.diagnostics(), |
1075 | AssistResolveStrategy::Single(SingleResolve { assist_id: params.id.clone(), assist_kind }), | 1078 | AssistResolveStrategy::Single(assist_resolve), |
1076 | frange, | 1079 | frange, |
1077 | )?; | 1080 | )?; |
1078 | 1081 | ||
1079 | let assist = match assists.get(params.index) { | 1082 | let assist = match assists.get(assist_index) { |
1080 | Some(assist) => assist, | 1083 | Some(assist) => assist, |
1081 | None => return Err(LspError::new( | 1084 | None => return Err(LspError::new( |
1082 | ErrorCode::InvalidParams as i32, | 1085 | ErrorCode::InvalidParams as i32, |
1083 | format!( | 1086 | format!( |
1084 | "Failed to find the assist for index {} provided by the resolve request. Expected assist id: {:?}", | 1087 | "Failed to find the assist for index {} provided by the resolve request. Resolve request assist id: {}", |
1085 | params.index, params.id, | 1088 | assist_index, params.id, |
1086 | ), | 1089 | ), |
1087 | ) | 1090 | ) |
1088 | .into()) | 1091 | .into()) |
1089 | }; | 1092 | }; |
1090 | if assist.id.0 != params.id || assist.id.1 != assist_kind { | 1093 | if assist.id.0 != expected_assist_id || assist.id.1 != expected_kind { |
1091 | return Err(LspError::new( | 1094 | return Err(LspError::new( |
1092 | ErrorCode::InvalidParams as i32, | 1095 | ErrorCode::InvalidParams as i32, |
1093 | format!( | 1096 | format!( |
1094 | "Failed to find exactly the same assist at index {} for the resolve parameters given. Expected id and kind: {}, {:?}, actual id: {:?}.", | 1097 | "Mismatching assist at index {} for the resolve parameters given. Resolve request assist id: {}, actual id: {:?}.", |
1095 | params.index, params.id, assist_kind, assist.id | 1098 | assist_index, params.id, assist.id |
1096 | ), | 1099 | ), |
1097 | ) | 1100 | ) |
1098 | .into()); | 1101 | .into()); |
@@ -1102,6 +1105,21 @@ pub(crate) fn handle_code_action_resolve( | |||
1102 | Ok(code_action) | 1105 | Ok(code_action) |
1103 | } | 1106 | } |
1104 | 1107 | ||
1108 | fn parse_action_id(action_id: &str) -> Result<(usize, SingleResolve), String> { | ||
1109 | let id_parts = action_id.split(':').collect_vec(); | ||
1110 | match id_parts.as_slice() { | ||
1111 | &[assist_id_string, assist_kind_string, index_string] => { | ||
1112 | let assist_kind: AssistKind = assist_kind_string.parse()?; | ||
1113 | let index: usize = match index_string.parse() { | ||
1114 | Ok(index) => index, | ||
1115 | Err(e) => return Err(format!("Incorrect index string: {}", e)), | ||
1116 | }; | ||
1117 | Ok((index, SingleResolve { assist_id: assist_id_string.to_string(), assist_kind })) | ||
1118 | } | ||
1119 | _ => Err("Action id contains incorrect number of segments".to_string()), | ||
1120 | } | ||
1121 | } | ||
1122 | |||
1105 | pub(crate) fn handle_code_lens( | 1123 | pub(crate) fn handle_code_lens( |
1106 | snap: GlobalStateSnapshot, | 1124 | snap: GlobalStateSnapshot, |
1107 | params: lsp_types::CodeLensParams, | 1125 | params: lsp_types::CodeLensParams, |
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 292aedc9c..b8835a534 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs | |||
@@ -303,8 +303,6 @@ pub struct CodeAction { | |||
303 | pub struct CodeActionData { | 303 | pub struct CodeActionData { |
304 | pub code_action_params: lsp_types::CodeActionParams, | 304 | pub code_action_params: lsp_types::CodeActionParams, |
305 | pub id: String, | 305 | pub id: String, |
306 | pub kind: String, | ||
307 | pub index: usize, | ||
308 | } | 306 | } |
309 | 307 | ||
310 | #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] | 308 | #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 62e16680b..1d27aa7b3 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -897,10 +897,8 @@ pub(crate) fn code_action( | |||
897 | (Some(it), _) => res.edit = Some(snippet_workspace_edit(snap, it)?), | 897 | (Some(it), _) => res.edit = Some(snippet_workspace_edit(snap, it)?), |
898 | (None, Some((index, code_action_params))) => { | 898 | (None, Some((index, code_action_params))) => { |
899 | res.data = Some(lsp_ext::CodeActionData { | 899 | res.data = Some(lsp_ext::CodeActionData { |
900 | id: assist.id.0.to_string(), | 900 | id: format!("{}:{}:{}", assist.id.0, assist.id.1.name(), index), |
901 | code_action_params, | 901 | code_action_params, |
902 | kind: assist.id.1.name().to_string(), | ||
903 | index, | ||
904 | }); | 902 | }); |
905 | } | 903 | } |
906 | (None, None) => { | 904 | (None, None) => { |
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index e2ea695f2..f0f981802 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md | |||
@@ -81,7 +81,6 @@ If this capability is set, `CodeAction` returned from the server contain an addi | |||
81 | interface CodeAction { | 81 | interface CodeAction { |
82 | title: string; | 82 | title: string; |
83 | group?: string; | 83 | group?: string; |
84 | data?: string; | ||
85 | ... | 84 | ... |
86 | } | 85 | } |
87 | ``` | 86 | ``` |
@@ -102,8 +101,6 @@ The set of actions `[ { title: "foo" }, { group: "frobnicate", title: "bar" }, { | |||
102 | 101 | ||
103 | Alternatively, selecting `frobnicate` could present a user with an additional menu to choose between `bar` and `baz`. | 102 | Alternatively, selecting `frobnicate` could present a user with an additional menu to choose between `bar` and `baz`. |
104 | 103 | ||
105 | `data` field contains optional json data for deferred resolve of the action data that's slow to compute in the original request. | ||
106 | |||
107 | ### Example | 104 | ### Example |
108 | 105 | ||
109 | ```rust | 106 | ```rust |