diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-08 23:03:20 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-08 23:03:20 +0100 |
commit | 733ef3163c7423d8307d2df4503c08870b5a35b7 (patch) | |
tree | b78e0b408ab7a91660e701188fc66a5f2eadac1d /crates/ra_assists/src/assist_context.rs | |
parent | 3999bbba1bba45ae9d577506c6414f741e1fe80a (diff) | |
parent | 38fa4d17fb9622044ee0f0bc50d6c71d5aa46dd1 (diff) |
Merge #4804
4804: Simplify API r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_assists/src/assist_context.rs')
-rw-r--r-- | crates/ra_assists/src/assist_context.rs | 99 |
1 files changed, 27 insertions, 72 deletions
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs index 1925db8b2..edd8255f4 100644 --- a/crates/ra_assists/src/assist_context.rs +++ b/crates/ra_assists/src/assist_context.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | //! See `AssistContext` | 1 | //! See `AssistContext` |
2 | 2 | ||
3 | use std::mem; | ||
4 | |||
3 | use algo::find_covering_element; | 5 | use algo::find_covering_element; |
4 | use hir::Semantics; | 6 | use hir::Semantics; |
5 | use ra_db::{FileId, FileRange}; | 7 | use ra_db::{FileId, FileRange}; |
@@ -19,7 +21,6 @@ use crate::{ | |||
19 | assist_config::{AssistConfig, SnippetCap}, | 21 | assist_config::{AssistConfig, SnippetCap}, |
20 | Assist, AssistId, GroupLabel, ResolvedAssist, | 22 | Assist, AssistId, GroupLabel, ResolvedAssist, |
21 | }; | 23 | }; |
22 | use rustc_hash::FxHashMap; | ||
23 | 24 | ||
24 | /// `AssistContext` allows to apply an assist or check if it could be applied. | 25 | /// `AssistContext` allows to apply an assist or check if it could be applied. |
25 | /// | 26 | /// |
@@ -139,16 +140,6 @@ impl Assists { | |||
139 | let label = Assist::new(id, label.into(), None, target); | 140 | let label = Assist::new(id, label.into(), None, target); |
140 | self.add_impl(label, f) | 141 | self.add_impl(label, f) |
141 | } | 142 | } |
142 | pub(crate) fn add_in_multiple_files( | ||
143 | &mut self, | ||
144 | id: AssistId, | ||
145 | label: impl Into<String>, | ||
146 | target: TextRange, | ||
147 | f: impl FnOnce(&mut AssistDirector), | ||
148 | ) -> Option<()> { | ||
149 | let label = Assist::new(id, label.into(), None, target); | ||
150 | self.add_impl_multiple_files(label, f) | ||
151 | } | ||
152 | pub(crate) fn add_group( | 143 | pub(crate) fn add_group( |
153 | &mut self, | 144 | &mut self, |
154 | group: &GroupLabel, | 145 | group: &GroupLabel, |
@@ -173,31 +164,6 @@ impl Assists { | |||
173 | Some(()) | 164 | Some(()) |
174 | } | 165 | } |
175 | 166 | ||
176 | fn add_impl_multiple_files( | ||
177 | &mut self, | ||
178 | label: Assist, | ||
179 | f: impl FnOnce(&mut AssistDirector), | ||
180 | ) -> Option<()> { | ||
181 | if !self.resolve { | ||
182 | self.buf.push((label, None)); | ||
183 | return None; | ||
184 | } | ||
185 | let mut director = AssistDirector::default(); | ||
186 | f(&mut director); | ||
187 | let changes = director.finish(); | ||
188 | let file_edits: Vec<SourceFileEdit> = | ||
189 | changes.into_iter().map(|mut change| change.source_file_edits.pop().unwrap()).collect(); | ||
190 | |||
191 | let source_change = SourceChange { | ||
192 | source_file_edits: file_edits, | ||
193 | file_system_edits: vec![], | ||
194 | is_snippet: false, | ||
195 | }; | ||
196 | |||
197 | self.buf.push((label, Some(source_change))); | ||
198 | Some(()) | ||
199 | } | ||
200 | |||
201 | fn finish(mut self) -> Vec<(Assist, Option<SourceChange>)> { | 167 | fn finish(mut self) -> Vec<(Assist, Option<SourceChange>)> { |
202 | self.buf.sort_by_key(|(label, _edit)| label.target.len()); | 168 | self.buf.sort_by_key(|(label, _edit)| label.target.len()); |
203 | self.buf | 169 | self.buf |
@@ -206,13 +172,32 @@ impl Assists { | |||
206 | 172 | ||
207 | pub(crate) struct AssistBuilder { | 173 | pub(crate) struct AssistBuilder { |
208 | edit: TextEditBuilder, | 174 | edit: TextEditBuilder, |
209 | file: FileId, | 175 | file_id: FileId, |
210 | is_snippet: bool, | 176 | is_snippet: bool, |
177 | edits: Vec<SourceFileEdit>, | ||
211 | } | 178 | } |
212 | 179 | ||
213 | impl AssistBuilder { | 180 | impl AssistBuilder { |
214 | pub(crate) fn new(file: FileId) -> AssistBuilder { | 181 | pub(crate) fn new(file_id: FileId) -> AssistBuilder { |
215 | AssistBuilder { edit: TextEditBuilder::default(), file, is_snippet: false } | 182 | AssistBuilder { |
183 | edit: TextEditBuilder::default(), | ||
184 | file_id, | ||
185 | is_snippet: false, | ||
186 | edits: Vec::new(), | ||
187 | } | ||
188 | } | ||
189 | |||
190 | pub(crate) fn edit_file(&mut self, file_id: FileId) { | ||
191 | self.file_id = file_id; | ||
192 | } | ||
193 | |||
194 | fn commit(&mut self) { | ||
195 | let edit = mem::take(&mut self.edit).finish(); | ||
196 | if !edit.is_empty() { | ||
197 | let new_edit = SourceFileEdit { file_id: self.file_id, edit }; | ||
198 | assert!(!self.edits.iter().any(|it| it.file_id == new_edit.file_id)); | ||
199 | self.edits.push(new_edit); | ||
200 | } | ||
216 | } | 201 | } |
217 | 202 | ||
218 | /// Remove specified `range` of text. | 203 | /// Remove specified `range` of text. |
@@ -270,48 +255,18 @@ impl AssistBuilder { | |||
270 | algo::diff(&node, &new).into_text_edit(&mut self.edit) | 255 | algo::diff(&node, &new).into_text_edit(&mut self.edit) |
271 | } | 256 | } |
272 | 257 | ||
273 | // FIXME: better API | ||
274 | pub(crate) fn set_file(&mut self, assist_file: FileId) { | ||
275 | self.file = assist_file; | ||
276 | } | ||
277 | |||
278 | // FIXME: kill this API | 258 | // FIXME: kill this API |
279 | /// Get access to the raw `TextEditBuilder`. | 259 | /// Get access to the raw `TextEditBuilder`. |
280 | pub(crate) fn text_edit_builder(&mut self) -> &mut TextEditBuilder { | 260 | pub(crate) fn text_edit_builder(&mut self) -> &mut TextEditBuilder { |
281 | &mut self.edit | 261 | &mut self.edit |
282 | } | 262 | } |
283 | 263 | ||
284 | fn finish(self) -> SourceChange { | 264 | fn finish(mut self) -> SourceChange { |
285 | let edit = self.edit.finish(); | 265 | self.commit(); |
286 | let source_file_edit = SourceFileEdit { file_id: self.file, edit }; | 266 | let mut res: SourceChange = mem::take(&mut self.edits).into(); |
287 | let mut res: SourceChange = source_file_edit.into(); | ||
288 | if self.is_snippet { | 267 | if self.is_snippet { |
289 | res.is_snippet = true; | 268 | res.is_snippet = true; |
290 | } | 269 | } |
291 | res | 270 | res |
292 | } | 271 | } |
293 | } | 272 | } |
294 | |||
295 | pub(crate) struct AssistDirector { | ||
296 | builders: FxHashMap<FileId, AssistBuilder>, | ||
297 | } | ||
298 | |||
299 | impl AssistDirector { | ||
300 | pub(crate) fn perform(&mut self, file_id: FileId, f: impl FnOnce(&mut AssistBuilder)) { | ||
301 | let mut builder = self.builders.entry(file_id).or_insert(AssistBuilder::new(file_id)); | ||
302 | f(&mut builder); | ||
303 | } | ||
304 | |||
305 | fn finish(self) -> Vec<SourceChange> { | ||
306 | self.builders | ||
307 | .into_iter() | ||
308 | .map(|(_, builder)| builder.finish()) | ||
309 | .collect::<Vec<SourceChange>>() | ||
310 | } | ||
311 | } | ||
312 | |||
313 | impl Default for AssistDirector { | ||
314 | fn default() -> Self { | ||
315 | AssistDirector { builders: FxHashMap::default() } | ||
316 | } | ||
317 | } | ||