aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/references/rename.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/references/rename.rs')
-rw-r--r--crates/ide/src/references/rename.rs100
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
7use hir::{Module, ModuleDef, ModuleSource, Semantics}; 7use hir::{Module, ModuleDef, ModuleSource, Semantics};
8use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange, SourceDatabaseExt};
9use ide_db::{ 8use 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};
13use syntax::{ 14use syntax::{
@@ -19,8 +20,8 @@ use test_utils::mark;
19use text_edit::TextEdit; 20use text_edit::TextEdit;
20 21
21use crate::{ 22use 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
26type RenameResult<T> = Result<T, RenameError>; 27type 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
173fn source_edit_from_reference( 174fn 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
208fn edit_text_range_for_record_field_expr_or_pat( 216fn 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)))