diff options
Diffstat (limited to 'crates/assists/src/assist_context.rs')
-rw-r--r-- | crates/assists/src/assist_context.rs | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index fcfe2d6ee..69499ea32 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs | |||
@@ -208,7 +208,7 @@ pub(crate) struct AssistBuilder { | |||
208 | edit: TextEditBuilder, | 208 | edit: TextEditBuilder, |
209 | file_id: FileId, | 209 | file_id: FileId, |
210 | is_snippet: bool, | 210 | is_snippet: bool, |
211 | change: SourceChange, | 211 | source_file_edits: Vec<SourceFileEdit>, |
212 | } | 212 | } |
213 | 213 | ||
214 | impl AssistBuilder { | 214 | impl AssistBuilder { |
@@ -217,20 +217,27 @@ impl AssistBuilder { | |||
217 | edit: TextEdit::builder(), | 217 | edit: TextEdit::builder(), |
218 | file_id, | 218 | file_id, |
219 | is_snippet: false, | 219 | is_snippet: false, |
220 | change: SourceChange::default(), | 220 | source_file_edits: Vec::default(), |
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
224 | pub(crate) fn edit_file(&mut self, file_id: FileId) { | 224 | pub(crate) fn edit_file(&mut self, file_id: FileId) { |
225 | self.commit(); | ||
225 | self.file_id = file_id; | 226 | self.file_id = file_id; |
226 | } | 227 | } |
227 | 228 | ||
228 | fn commit(&mut self) { | 229 | fn commit(&mut self) { |
229 | let edit = mem::take(&mut self.edit).finish(); | 230 | let edit = mem::take(&mut self.edit).finish(); |
230 | if !edit.is_empty() { | 231 | if !edit.is_empty() { |
231 | let new_edit = SourceFileEdit { file_id: self.file_id, edit }; | 232 | match self.source_file_edits.binary_search_by_key(&self.file_id, |edit| edit.file_id) { |
232 | assert!(!self.change.source_file_edits.iter().any(|it| it.file_id == new_edit.file_id)); | 233 | Ok(idx) => self.source_file_edits[idx] |
233 | self.change.source_file_edits.push(new_edit); | 234 | .edit |
235 | .union(edit) | ||
236 | .expect("overlapping edits for same file"), | ||
237 | Err(idx) => self | ||
238 | .source_file_edits | ||
239 | .insert(idx, SourceFileEdit { file_id: self.file_id, edit }), | ||
240 | } | ||
234 | } | 241 | } |
235 | } | 242 | } |
236 | 243 | ||
@@ -270,23 +277,18 @@ impl AssistBuilder { | |||
270 | algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) | 277 | algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) |
271 | } | 278 | } |
272 | pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) { | 279 | pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) { |
273 | let node = rewriter.rewrite_root().unwrap(); | 280 | if let Some(node) = rewriter.rewrite_root() { |
274 | let new = rewriter.rewrite(&node); | 281 | let new = rewriter.rewrite(&node); |
275 | algo::diff(&node, &new).into_text_edit(&mut self.edit); | 282 | algo::diff(&node, &new).into_text_edit(&mut self.edit); |
276 | } | 283 | } |
277 | |||
278 | // FIXME: kill this API | ||
279 | /// Get access to the raw `TextEditBuilder`. | ||
280 | pub(crate) fn text_edit_builder(&mut self) -> &mut TextEditBuilder { | ||
281 | &mut self.edit | ||
282 | } | 284 | } |
283 | 285 | ||
284 | fn finish(mut self) -> SourceChange { | 286 | fn finish(mut self) -> SourceChange { |
285 | self.commit(); | 287 | self.commit(); |
286 | let mut change = mem::take(&mut self.change); | 288 | SourceChange { |
287 | if self.is_snippet { | 289 | source_file_edits: mem::take(&mut self.source_file_edits), |
288 | change.is_snippet = true; | 290 | file_system_edits: Default::default(), |
291 | is_snippet: self.is_snippet, | ||
289 | } | 292 | } |
290 | change | ||
291 | } | 293 | } |
292 | } | 294 | } |