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