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.rs239
1 files changed, 105 insertions, 134 deletions
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index c3ae568c2..039efb26f 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -21,7 +21,7 @@ use text_edit::TextEdit;
21 21
22use crate::{ 22use crate::{
23 FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange, 23 FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange,
24 SourceFileEdit, TextRange, TextSize, 24 TextRange, TextSize,
25}; 25};
26 26
27type RenameResult<T> = Result<T, RenameError>; 27type RenameResult<T> = Result<T, RenameError>;
@@ -58,7 +58,7 @@ pub(crate) fn prepare_rename(
58 rename_self_to_param(&sema, position, self_token, "dummy") 58 rename_self_to_param(&sema, position, self_token, "dummy")
59 } else { 59 } else {
60 let RangeInfo { range, .. } = find_all_refs(&sema, position)?; 60 let RangeInfo { range, .. } = find_all_refs(&sema, position)?;
61 Ok(RangeInfo::new(range, SourceChange::from(vec![]))) 61 Ok(RangeInfo::new(range, SourceChange::default()))
62 } 62 }
63 .map(|info| RangeInfo::new(info.range, ())) 63 .map(|info| RangeInfo::new(info.range, ()))
64} 64}
@@ -176,7 +176,7 @@ fn source_edit_from_references(
176 file_id: FileId, 176 file_id: FileId,
177 references: &[FileReference], 177 references: &[FileReference],
178 new_name: &str, 178 new_name: &str,
179) -> SourceFileEdit { 179) -> (FileId, TextEdit) {
180 let mut edit = TextEdit::builder(); 180 let mut edit = TextEdit::builder();
181 for reference in references { 181 for reference in references {
182 let mut replacement_text = String::new(); 182 let mut replacement_text = String::new();
@@ -209,8 +209,7 @@ fn source_edit_from_references(
209 }; 209 };
210 edit.replace(range, replacement_text); 210 edit.replace(range, replacement_text);
211 } 211 }
212 212 (file_id, edit.finish())
213 SourceFileEdit { file_id, edit: edit.finish() }
214} 213}
215 214
216fn edit_text_range_for_record_field_expr_or_pat( 215fn edit_text_range_for_record_field_expr_or_pat(
@@ -250,8 +249,8 @@ fn rename_mod(
250 if IdentifierKind::Ident != check_identifier(new_name)? { 249 if IdentifierKind::Ident != check_identifier(new_name)? {
251 bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); 250 bail!("Invalid name `{0}`: cannot rename module to {0}", new_name);
252 } 251 }
253 let mut source_file_edits = Vec::new(); 252
254 let mut file_system_edits = Vec::new(); 253 let mut source_change = SourceChange::default();
255 254
256 let src = module.definition_source(sema.db); 255 let src = module.definition_source(sema.db);
257 let file_id = src.file_id.original_file(sema.db); 256 let file_id = src.file_id.original_file(sema.db);
@@ -265,7 +264,7 @@ fn rename_mod(
265 }; 264 };
266 let dst = AnchoredPathBuf { anchor: file_id, path }; 265 let dst = AnchoredPathBuf { anchor: file_id, path };
267 let move_file = FileSystemEdit::MoveFile { src: file_id, dst }; 266 let move_file = FileSystemEdit::MoveFile { src: file_id, dst };
268 file_system_edits.push(move_file); 267 source_change.push_file_system_edit(move_file);
269 } 268 }
270 ModuleSource::Module(..) => {} 269 ModuleSource::Module(..) => {}
271 } 270 }
@@ -273,20 +272,19 @@ fn rename_mod(
273 if let Some(src) = module.declaration_source(sema.db) { 272 if let Some(src) = module.declaration_source(sema.db) {
274 let file_id = src.file_id.original_file(sema.db); 273 let file_id = src.file_id.original_file(sema.db);
275 let name = src.value.name().unwrap(); 274 let name = src.value.name().unwrap();
276 let edit = SourceFileEdit { 275 source_change.insert_source_edit(
277 file_id, 276 file_id,
278 edit: TextEdit::replace(name.syntax().text_range(), new_name.into()), 277 TextEdit::replace(name.syntax().text_range(), new_name.into()),
279 }; 278 );
280 source_file_edits.push(edit);
281 } 279 }
282 280
283 let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; 281 let RangeInfo { range, info: refs } = find_all_refs(sema, position)?;
284 let ref_edits = refs.references().iter().map(|(&file_id, references)| { 282 let ref_edits = refs.references().iter().map(|(&file_id, references)| {
285 source_edit_from_references(sema, file_id, references, new_name) 283 source_edit_from_references(sema, file_id, references, new_name)
286 }); 284 });
287 source_file_edits.extend(ref_edits); 285 source_change.extend(ref_edits);
288 286
289 Ok(RangeInfo::new(range, SourceChange::from_edits(source_file_edits, file_system_edits))) 287 Ok(RangeInfo::new(range, source_change))
290} 288}
291 289
292fn rename_to_self( 290fn rename_to_self(
@@ -335,20 +333,16 @@ fn rename_to_self(
335 333
336 let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; 334 let RangeInfo { range, info: refs } = find_all_refs(sema, position)?;
337 335
338 let mut edits = refs 336 let mut source_change = SourceChange::default();
339 .references() 337 source_change.extend(refs.references().iter().map(|(&file_id, references)| {
340 .iter() 338 source_edit_from_references(sema, file_id, references, "self")
341 .map(|(&file_id, references)| { 339 }));
342 source_edit_from_references(sema, file_id, references, "self") 340 source_change.insert_source_edit(
343 }) 341 position.file_id,
344 .collect::<Vec<_>>(); 342 TextEdit::replace(param_range, String::from(self_param)),
345 343 );
346 edits.push(SourceFileEdit {
347 file_id: position.file_id,
348 edit: TextEdit::replace(param_range, String::from(self_param)),
349 });
350 344
351 Ok(RangeInfo::new(range, SourceChange::from(edits))) 345 Ok(RangeInfo::new(range, source_change))
352} 346}
353 347
354fn text_edit_from_self_param( 348fn text_edit_from_self_param(
@@ -402,7 +396,7 @@ fn rename_self_to_param(
402 .ok_or_else(|| format_err!("No surrounding method declaration found"))?; 396 .ok_or_else(|| format_err!("No surrounding method declaration found"))?;
403 let search_range = fn_def.syntax().text_range(); 397 let search_range = fn_def.syntax().text_range();
404 398
405 let mut edits: Vec<SourceFileEdit> = vec![]; 399 let mut source_change = SourceChange::default();
406 400
407 for (idx, _) in text.match_indices("self") { 401 for (idx, _) in text.match_indices("self") {
408 let offset: TextSize = idx.try_into().unwrap(); 402 let offset: TextSize = idx.try_into().unwrap();
@@ -416,18 +410,18 @@ fn rename_self_to_param(
416 } else { 410 } else {
417 TextEdit::replace(usage.text_range(), String::from(new_name)) 411 TextEdit::replace(usage.text_range(), String::from(new_name))
418 }; 412 };
419 edits.push(SourceFileEdit { file_id: position.file_id, edit }); 413 source_change.insert_source_edit(position.file_id, edit);
420 } 414 }
421 } 415 }
422 416
423 if edits.len() > 1 && ident_kind == IdentifierKind::Underscore { 417 if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore {
424 bail!("Cannot rename reference to `_` as it is being referenced multiple times"); 418 bail!("Cannot rename reference to `_` as it is being referenced multiple times");
425 } 419 }
426 420
427 let range = ast::SelfParam::cast(self_token.parent()) 421 let range = ast::SelfParam::cast(self_token.parent())
428 .map_or(self_token.text_range(), |p| p.syntax().text_range()); 422 .map_or(self_token.text_range(), |p| p.syntax().text_range());
429 423
430 Ok(RangeInfo::new(range, SourceChange::from(edits))) 424 Ok(RangeInfo::new(range, source_change))
431} 425}
432 426
433fn rename_reference( 427fn rename_reference(
@@ -464,14 +458,12 @@ fn rename_reference(
464 (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident), 458 (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident),
465 } 459 }
466 460
467 let edit = refs 461 let mut source_change = SourceChange::default();
468 .into_iter() 462 source_change.extend(refs.into_iter().map(|(file_id, references)| {
469 .map(|(file_id, references)| { 463 source_edit_from_references(sema, file_id, &references, new_name)
470 source_edit_from_references(sema, file_id, &references, new_name) 464 }));
471 })
472 .collect::<Vec<_>>();
473 465
474 Ok(RangeInfo::new(range, SourceChange::from(edit))) 466 Ok(RangeInfo::new(range, source_change))
475} 467}
476 468
477#[cfg(test)] 469#[cfg(test)]
@@ -494,8 +486,8 @@ mod tests {
494 let mut text_edit_builder = TextEdit::builder(); 486 let mut text_edit_builder = TextEdit::builder();
495 let mut file_id: Option<FileId> = None; 487 let mut file_id: Option<FileId> = None;
496 for edit in source_change.info.source_file_edits { 488 for edit in source_change.info.source_file_edits {
497 file_id = Some(edit.file_id); 489 file_id = Some(edit.0);
498 for indel in edit.edit.into_iter() { 490 for indel in edit.1.into_iter() {
499 text_edit_builder.replace(indel.delete, indel.insert); 491 text_edit_builder.replace(indel.delete, indel.insert);
500 } 492 }
501 } 493 }
@@ -895,21 +887,18 @@ mod foo$0;
895 RangeInfo { 887 RangeInfo {
896 range: 4..7, 888 range: 4..7,
897 info: SourceChange { 889 info: SourceChange {
898 source_file_edits: [ 890 source_file_edits: {
899 SourceFileEdit { 891 FileId(
900 file_id: FileId( 892 1,
901 1, 893 ): TextEdit {
902 ), 894 indels: [
903 edit: TextEdit { 895 Indel {
904 indels: [ 896 insert: "foo2",
905 Indel { 897 delete: 4..7,
906 insert: "foo2", 898 },
907 delete: 4..7, 899 ],
908 },
909 ],
910 },
911 }, 900 },
912 ], 901 },
913 file_system_edits: [ 902 file_system_edits: [
914 MoveFile { 903 MoveFile {
915 src: FileId( 904 src: FileId(
@@ -950,34 +939,28 @@ use crate::foo$0::FooContent;
950 RangeInfo { 939 RangeInfo {
951 range: 11..14, 940 range: 11..14,
952 info: SourceChange { 941 info: SourceChange {
953 source_file_edits: [ 942 source_file_edits: {
954 SourceFileEdit { 943 FileId(
955 file_id: FileId( 944 0,
956 0, 945 ): TextEdit {
957 ), 946 indels: [
958 edit: TextEdit { 947 Indel {
959 indels: [ 948 insert: "quux",
960 Indel { 949 delete: 8..11,
961 insert: "quux", 950 },
962 delete: 8..11, 951 ],
963 },
964 ],
965 },
966 }, 952 },
967 SourceFileEdit { 953 FileId(
968 file_id: FileId( 954 2,
969 2, 955 ): TextEdit {
970 ), 956 indels: [
971 edit: TextEdit { 957 Indel {
972 indels: [ 958 insert: "quux",
973 Indel { 959 delete: 11..14,
974 insert: "quux", 960 },
975 delete: 11..14, 961 ],
976 },
977 ],
978 },
979 }, 962 },
980 ], 963 },
981 file_system_edits: [ 964 file_system_edits: [
982 MoveFile { 965 MoveFile {
983 src: FileId( 966 src: FileId(
@@ -1012,21 +995,18 @@ mod fo$0o;
1012 RangeInfo { 995 RangeInfo {
1013 range: 4..7, 996 range: 4..7,
1014 info: SourceChange { 997 info: SourceChange {
1015 source_file_edits: [ 998 source_file_edits: {
1016 SourceFileEdit { 999 FileId(
1017 file_id: FileId( 1000 0,
1018 0, 1001 ): TextEdit {
1019 ), 1002 indels: [
1020 edit: TextEdit { 1003 Indel {
1021 indels: [ 1004 insert: "foo2",
1022 Indel { 1005 delete: 4..7,
1023 insert: "foo2", 1006 },
1024 delete: 4..7, 1007 ],
1025 },
1026 ],
1027 },
1028 }, 1008 },
1029 ], 1009 },
1030 file_system_edits: [ 1010 file_system_edits: [
1031 MoveFile { 1011 MoveFile {
1032 src: FileId( 1012 src: FileId(
@@ -1062,21 +1042,18 @@ mod outer { mod fo$0o; }
1062 RangeInfo { 1042 RangeInfo {
1063 range: 16..19, 1043 range: 16..19,
1064 info: SourceChange { 1044 info: SourceChange {
1065 source_file_edits: [ 1045 source_file_edits: {
1066 SourceFileEdit { 1046 FileId(
1067 file_id: FileId( 1047 0,
1068 0, 1048 ): TextEdit {
1069 ), 1049 indels: [
1070 edit: TextEdit { 1050 Indel {
1071 indels: [ 1051 insert: "bar",
1072 Indel { 1052 delete: 16..19,
1073 insert: "bar", 1053 },
1074 delete: 16..19, 1054 ],
1075 },
1076 ],
1077 },
1078 }, 1055 },
1079 ], 1056 },
1080 file_system_edits: [ 1057 file_system_edits: [
1081 MoveFile { 1058 MoveFile {
1082 src: FileId( 1059 src: FileId(
@@ -1135,34 +1112,28 @@ pub mod foo$0;
1135 RangeInfo { 1112 RangeInfo {
1136 range: 8..11, 1113 range: 8..11,
1137 info: SourceChange { 1114 info: SourceChange {
1138 source_file_edits: [ 1115 source_file_edits: {
1139 SourceFileEdit { 1116 FileId(
1140 file_id: FileId( 1117 0,
1141 1, 1118 ): TextEdit {
1142 ), 1119 indels: [
1143 edit: TextEdit { 1120 Indel {
1144 indels: [ 1121 insert: "foo2",
1145 Indel { 1122 delete: 27..30,
1146 insert: "foo2", 1123 },
1147 delete: 8..11, 1124 ],
1148 },
1149 ],
1150 },
1151 }, 1125 },
1152 SourceFileEdit { 1126 FileId(
1153 file_id: FileId( 1127 1,
1154 0, 1128 ): TextEdit {
1155 ), 1129 indels: [
1156 edit: TextEdit { 1130 Indel {
1157 indels: [ 1131 insert: "foo2",
1158 Indel { 1132 delete: 8..11,
1159 insert: "foo2", 1133 },
1160 delete: 27..30, 1134 ],
1161 },
1162 ],
1163 },
1164 }, 1135 },
1165 ], 1136 },
1166 file_system_edits: [ 1137 file_system_edits: [
1167 MoveFile { 1138 MoveFile {
1168 src: FileId( 1139 src: FileId(