aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/assist_context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/assist_context.rs')
-rw-r--r--crates/assists/src/assist_context.rs38
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
214impl AssistBuilder { 214impl 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}