diff options
Diffstat (limited to 'crates/ide/src/references')
-rw-r--r-- | crates/ide/src/references/rename.rs | 100 |
1 files changed, 52 insertions, 48 deletions
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 3db08e84c..c3ae568c2 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -5,9 +5,10 @@ use std::{ | |||
5 | }; | 5 | }; |
6 | 6 | ||
7 | use hir::{Module, ModuleDef, ModuleSource, Semantics}; | 7 | use hir::{Module, ModuleDef, ModuleSource, Semantics}; |
8 | use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange, SourceDatabaseExt}; | ||
9 | use ide_db::{ | 8 | use ide_db::{ |
9 | base_db::{AnchoredPathBuf, FileId, FileRange, SourceDatabaseExt}, | ||
10 | defs::{Definition, NameClass, NameRefClass}, | 10 | defs::{Definition, NameClass, NameRefClass}, |
11 | search::FileReference, | ||
11 | RootDatabase, | 12 | RootDatabase, |
12 | }; | 13 | }; |
13 | use syntax::{ | 14 | use syntax::{ |
@@ -19,8 +20,8 @@ use test_utils::mark; | |||
19 | use text_edit::TextEdit; | 20 | use text_edit::TextEdit; |
20 | 21 | ||
21 | use crate::{ | 22 | use crate::{ |
22 | FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, ReferenceSearchResult, | 23 | FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange, |
23 | SourceChange, SourceFileEdit, TextRange, TextSize, | 24 | SourceFileEdit, TextRange, TextSize, |
24 | }; | 25 | }; |
25 | 26 | ||
26 | type RenameResult<T> = Result<T, RenameError>; | 27 | type RenameResult<T> = Result<T, RenameError>; |
@@ -170,39 +171,46 @@ fn find_all_refs( | |||
170 | .ok_or_else(|| format_err!("No references found at position")) | 171 | .ok_or_else(|| format_err!("No references found at position")) |
171 | } | 172 | } |
172 | 173 | ||
173 | fn source_edit_from_reference( | 174 | fn source_edit_from_references( |
174 | sema: &Semantics<RootDatabase>, | 175 | sema: &Semantics<RootDatabase>, |
175 | reference: Reference, | 176 | file_id: FileId, |
177 | references: &[FileReference], | ||
176 | new_name: &str, | 178 | new_name: &str, |
177 | ) -> SourceFileEdit { | 179 | ) -> SourceFileEdit { |
178 | let mut replacement_text = String::new(); | 180 | let mut edit = TextEdit::builder(); |
179 | let range = match reference.kind { | 181 | for reference in references { |
180 | ReferenceKind::FieldShorthandForField => { | 182 | let mut replacement_text = String::new(); |
181 | mark::hit!(test_rename_struct_field_for_shorthand); | 183 | let range = match reference.kind { |
182 | replacement_text.push_str(new_name); | 184 | ReferenceKind::FieldShorthandForField => { |
183 | replacement_text.push_str(": "); | 185 | mark::hit!(test_rename_struct_field_for_shorthand); |
184 | TextRange::new(reference.file_range.range.start(), reference.file_range.range.start()) | 186 | replacement_text.push_str(new_name); |
185 | } | 187 | replacement_text.push_str(": "); |
186 | ReferenceKind::FieldShorthandForLocal => { | 188 | TextRange::new(reference.range.start(), reference.range.start()) |
187 | mark::hit!(test_rename_local_for_field_shorthand); | 189 | } |
188 | replacement_text.push_str(": "); | 190 | ReferenceKind::FieldShorthandForLocal => { |
189 | replacement_text.push_str(new_name); | 191 | mark::hit!(test_rename_local_for_field_shorthand); |
190 | TextRange::new(reference.file_range.range.end(), reference.file_range.range.end()) | 192 | replacement_text.push_str(": "); |
191 | } | 193 | replacement_text.push_str(new_name); |
192 | ReferenceKind::RecordFieldExprOrPat => { | 194 | TextRange::new(reference.range.end(), reference.range.end()) |
193 | mark::hit!(test_rename_field_expr_pat); | 195 | } |
194 | replacement_text.push_str(new_name); | 196 | ReferenceKind::RecordFieldExprOrPat => { |
195 | edit_text_range_for_record_field_expr_or_pat(sema, reference.file_range, new_name) | 197 | mark::hit!(test_rename_field_expr_pat); |
196 | } | 198 | replacement_text.push_str(new_name); |
197 | _ => { | 199 | edit_text_range_for_record_field_expr_or_pat( |
198 | replacement_text.push_str(new_name); | 200 | sema, |
199 | reference.file_range.range | 201 | FileRange { file_id, range: reference.range }, |
200 | } | 202 | new_name, |
201 | }; | 203 | ) |
202 | SourceFileEdit { | 204 | } |
203 | file_id: reference.file_range.file_id, | 205 | _ => { |
204 | edit: TextEdit::replace(range, replacement_text), | 206 | replacement_text.push_str(new_name); |
207 | reference.range | ||
208 | } | ||
209 | }; | ||
210 | edit.replace(range, replacement_text); | ||
205 | } | 211 | } |
212 | |||
213 | SourceFileEdit { file_id, edit: edit.finish() } | ||
206 | } | 214 | } |
207 | 215 | ||
208 | fn edit_text_range_for_record_field_expr_or_pat( | 216 | fn edit_text_range_for_record_field_expr_or_pat( |
@@ -273,10 +281,9 @@ fn rename_mod( | |||
273 | } | 281 | } |
274 | 282 | ||
275 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; | 283 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; |
276 | let ref_edits = refs | 284 | let ref_edits = refs.references().iter().map(|(&file_id, references)| { |
277 | .references | 285 | source_edit_from_references(sema, file_id, references, new_name) |
278 | .into_iter() | 286 | }); |
279 | .map(|reference| source_edit_from_reference(sema, reference, new_name)); | ||
280 | source_file_edits.extend(ref_edits); | 287 | source_file_edits.extend(ref_edits); |
281 | 288 | ||
282 | Ok(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits))) | 289 | Ok(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits))) |
@@ -328,17 +335,12 @@ fn rename_to_self( | |||
328 | 335 | ||
329 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; | 336 | let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; |
330 | 337 | ||
331 | let (param_ref, usages): (Vec<Reference>, Vec<Reference>) = refs | 338 | let mut edits = refs |
332 | .into_iter() | 339 | .references() |
333 | .partition(|reference| param_range.intersect(reference.file_range.range).is_some()); | 340 | .iter() |
334 | 341 | .map(|(&file_id, references)| { | |
335 | if param_ref.is_empty() { | 342 | source_edit_from_references(sema, file_id, references, "self") |
336 | bail!("Parameter to rename not found"); | 343 | }) |
337 | } | ||
338 | |||
339 | let mut edits = usages | ||
340 | .into_iter() | ||
341 | .map(|reference| source_edit_from_reference(sema, reference, "self")) | ||
342 | .collect::<Vec<_>>(); | 344 | .collect::<Vec<_>>(); |
343 | 345 | ||
344 | edits.push(SourceFileEdit { | 346 | edits.push(SourceFileEdit { |
@@ -464,7 +466,9 @@ fn rename_reference( | |||
464 | 466 | ||
465 | let edit = refs | 467 | let edit = refs |
466 | .into_iter() | 468 | .into_iter() |
467 | .map(|reference| source_edit_from_reference(sema, reference, new_name)) | 469 | .map(|(file_id, references)| { |
470 | source_edit_from_references(sema, file_id, &references, new_name) | ||
471 | }) | ||
468 | .collect::<Vec<_>>(); | 472 | .collect::<Vec<_>>(); |
469 | 473 | ||
470 | Ok(RangeInfo::new(range, SourceChange::from(edit))) | 474 | Ok(RangeInfo::new(range, SourceChange::from(edit))) |