aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-11 09:22:09 +0000
committerGitHub <[email protected]>2020-03-11 09:22:09 +0000
commitbf77850c8106a71b317fb6c707a28e00d258884c (patch)
tree314afb27e80d7de8ccaf3f2eaa7b2e309de2e87f /crates/ra_ide
parent0714a065d578e8b22b0451bfc64378c875fe858f (diff)
parent13ccbb2919dff8e98d0a242d9d6b7edd17a6bd2c (diff)
Merge #3542
3542: Renames work on struct field shorthands r=matklad a=m-n When renaming either a local or a struct field, struct field shorthands are now renamed correctly. Happy to refactor this if it doesn't fit the design of the code. Thanks for adding the suggestion of where to start on the issue. I wasn't sure if I should also look at the behavior of renaming when placing the cursor at the field shorthand; the following describes the behavior with this patch: ```rust #[test] fn test_rename_field_shorthand_for_unspecified() { // when renaming a shorthand, should we have a way to specify // between renaming the field and the local? // // If not is this the correct default? test_rename( r#" struct Foo { i: i32, } impl Foo { fn new(i: i32) -> Self { Self { i<|> } } } "#, "j", r#" struct Foo { i: i32, } impl Foo { fn new(j: i32) -> Self { Self { i: j } } } "#, ); } ``` Resolves #3431 Co-authored-by: Matt Niemeir <[email protected]>
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/references/rename.rs208
1 files changed, 187 insertions, 21 deletions
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index 5b4bcf434..7d1190af9 100644
--- a/crates/ra_ide/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
@@ -9,7 +9,8 @@ use ra_syntax::{
9use ra_text_edit::TextEdit; 9use ra_text_edit::TextEdit;
10 10
11use crate::{ 11use crate::{
12 FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, SourceFileEdit, TextRange, 12 FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, SourceChange,
13 SourceFileEdit, TextRange,
13}; 14};
14 15
15use super::find_all_refs; 16use super::find_all_refs;
@@ -46,12 +47,29 @@ fn find_name_and_module_at_offset(
46 Some((ast_name, ast_module)) 47 Some((ast_name, ast_module))
47} 48}
48 49
49fn source_edit_from_file_id_range( 50fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFileEdit {
50 file_id: FileId, 51 let mut replacement_text = String::new();
51 range: TextRange, 52 let file_id = reference.file_range.file_id;
52 new_name: &str, 53 let range = match reference.kind {
53) -> SourceFileEdit { 54 ReferenceKind::StructFieldShorthandForField => {
54 SourceFileEdit { file_id, edit: TextEdit::replace(range, new_name.into()) } 55 replacement_text.push_str(new_name);
56 replacement_text.push_str(": ");
57 TextRange::from_to(
58 reference.file_range.range.start(),
59 reference.file_range.range.start(),
60 )
61 }
62 ReferenceKind::StructFieldShorthandForLocal => {
63 replacement_text.push_str(": ");
64 replacement_text.push_str(new_name);
65 TextRange::from_to(reference.file_range.range.end(), reference.file_range.range.end())
66 }
67 _ => {
68 replacement_text.push_str(new_name);
69 reference.file_range.range
70 }
71 };
72 SourceFileEdit { file_id, edit: TextEdit::replace(range, replacement_text) }
55} 73}
56 74
57fn rename_mod( 75fn rename_mod(
@@ -99,13 +117,10 @@ fn rename_mod(
99 source_file_edits.push(edit); 117 source_file_edits.push(edit);
100 118
101 if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) { 119 if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) {
102 let ref_edits = refs.references.into_iter().map(|reference| { 120 let ref_edits = refs
103 source_edit_from_file_id_range( 121 .references
104 reference.file_range.file_id, 122 .into_iter()
105 reference.file_range.range, 123 .map(|reference| source_edit_from_reference(reference, new_name));
106 new_name,
107 )
108 });
109 source_file_edits.extend(ref_edits); 124 source_file_edits.extend(ref_edits);
110 } 125 }
111 126
@@ -121,13 +136,7 @@ fn rename_reference(
121 136
122 let edit = refs 137 let edit = refs
123 .into_iter() 138 .into_iter()
124 .map(|reference| { 139 .map(|reference| source_edit_from_reference(reference, new_name))
125 source_edit_from_file_id_range(
126 reference.file_range.file_id,
127 reference.file_range.range,
128 new_name,
129 )
130 })
131 .collect::<Vec<_>>(); 140 .collect::<Vec<_>>();
132 141
133 if edit.is_empty() { 142 if edit.is_empty() {
@@ -286,6 +295,163 @@ mod tests {
286 } 295 }
287 296
288 #[test] 297 #[test]
298 fn test_rename_struct_field() {
299 test_rename(
300 r#"
301 struct Foo {
302 i<|>: i32,
303 }
304
305 impl Foo {
306 fn new(i: i32) -> Self {
307 Self { i: i }
308 }
309 }
310 "#,
311 "j",
312 r#"
313 struct Foo {
314 j: i32,
315 }
316
317 impl Foo {
318 fn new(i: i32) -> Self {
319 Self { j: i }
320 }
321 }
322 "#,
323 );
324 }
325
326 #[test]
327 fn test_rename_struct_field_for_shorthand() {
328 test_rename(
329 r#"
330 struct Foo {
331 i<|>: i32,
332 }
333
334 impl Foo {
335 fn new(i: i32) -> Self {
336 Self { i }
337 }
338 }
339 "#,
340 "j",
341 r#"
342 struct Foo {
343 j: i32,
344 }
345
346 impl Foo {
347 fn new(i: i32) -> Self {
348 Self { j: i }
349 }
350 }
351 "#,
352 );
353 }
354
355 #[test]
356 fn test_rename_local_for_field_shorthand() {
357 test_rename(
358 r#"
359 struct Foo {
360 i: i32,
361 }
362
363 impl Foo {
364 fn new(i<|>: i32) -> Self {
365 Self { i }
366 }
367 }
368 "#,
369 "j",
370 r#"
371 struct Foo {
372 i: i32,
373 }
374
375 impl Foo {
376 fn new(j: i32) -> Self {
377 Self { i: j }
378 }
379 }
380 "#,
381 );
382 }
383
384 #[test]
385 fn test_field_shorthand_correct_struct() {
386 test_rename(
387 r#"
388 struct Foo {
389 i<|>: i32,
390 }
391
392 struct Bar {
393 i: i32,
394 }
395
396 impl Bar {
397 fn new(i: i32) -> Self {
398 Self { i }
399 }
400 }
401 "#,
402 "j",
403 r#"
404 struct Foo {
405 j: i32,
406 }
407
408 struct Bar {
409 i: i32,
410 }
411
412 impl Bar {
413 fn new(i: i32) -> Self {
414 Self { i }
415 }
416 }
417 "#,
418 );
419 }
420
421 #[test]
422 fn test_shadow_local_for_struct_shorthand() {
423 test_rename(
424 r#"
425 struct Foo {
426 i: i32,
427 }
428
429 fn baz(i<|>: i32) -> Self {
430 let x = Foo { i };
431 {
432 let i = 0;
433 Foo { i }
434 }
435 }
436 "#,
437 "j",
438 r#"
439 struct Foo {
440 i: i32,
441 }
442
443 fn baz(j: i32) -> Self {
444 let x = Foo { i: j };
445 {
446 let i = 0;
447 Foo { i }
448 }
449 }
450 "#,
451 );
452 }
453
454 #[test]
289 fn test_rename_mod() { 455 fn test_rename_mod() {
290 let (analysis, position) = analysis_and_position( 456 let (analysis, position) = analysis_and_position(
291 " 457 "