aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/references
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/references')
-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 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
8use hir::{Module, ModuleDef, ModuleSource, Semantics}; 8use hir::{Module, ModuleDef, ModuleSource, Semantics};
9use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange, SourceDatabaseExt};
10use ide_db::{ 9use 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};
14use syntax::{ 15use syntax::{
@@ -20,8 +21,8 @@ use test_utils::mark;
20use text_edit::TextEdit; 21use text_edit::TextEdit;
21 22
22use crate::{ 23use 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
27type RenameResult<T> = Result<T, RenameError>; 28type 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
176fn source_edit_from_reference( 177fn 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
211fn edit_text_range_for_record_field_expr_or_pat( 219fn 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)))