Skip to content

Commit a9b6aec

Browse files
committed
Struct field rename renames field in constructor field shorthand
1 parent 530ff9f commit a9b6aec

File tree

2 files changed

+96
-26
lines changed

2 files changed

+96
-26
lines changed

crates/ra_ide/src/references/rename.rs

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use ra_syntax::{
99
use ra_text_edit::TextEdit;
1010

1111
use crate::{
12-
FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, SourceFileEdit, TextRange,
12+
FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, SourceChange,
13+
SourceFileEdit, TextRange,
1314
};
1415

1516
use super::find_all_refs;
@@ -46,12 +47,20 @@ fn find_name_and_module_at_offset(
4647
Some((ast_name, ast_module))
4748
}
4849

49-
fn source_edit_from_file_id_range(
50-
file_id: FileId,
51-
range: TextRange,
52-
new_name: &str,
53-
) -> SourceFileEdit {
54-
SourceFileEdit { file_id, edit: TextEdit::replace(range, new_name.into()) }
50+
fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFileEdit {
51+
let mut replacement_text = String::from(new_name);
52+
let file_id = reference.file_range.file_id;
53+
let range = match reference.kind {
54+
ReferenceKind::StructFieldShorthand => {
55+
replacement_text.push_str(": ");
56+
TextRange::from_to(
57+
reference.file_range.range.start(),
58+
reference.file_range.range.start(),
59+
)
60+
}
61+
_ => reference.file_range.range,
62+
};
63+
SourceFileEdit { file_id, edit: TextEdit::replace(range, replacement_text) }
5564
}
5665

5766
fn rename_mod(
@@ -99,13 +108,10 @@ fn rename_mod(
99108
source_file_edits.push(edit);
100109

101110
if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) {
102-
let ref_edits = refs.references.into_iter().map(|reference| {
103-
source_edit_from_file_id_range(
104-
reference.file_range.file_id,
105-
reference.file_range.range,
106-
new_name,
107-
)
108-
});
111+
let ref_edits = refs
112+
.references
113+
.into_iter()
114+
.map(|reference| source_edit_from_reference(reference, new_name));
109115
source_file_edits.extend(ref_edits);
110116
}
111117

@@ -121,13 +127,7 @@ fn rename_reference(
121127

122128
let edit = refs
123129
.into_iter()
124-
.map(|reference| {
125-
source_edit_from_file_id_range(
126-
reference.file_range.file_id,
127-
reference.file_range.range,
128-
new_name,
129-
)
130-
})
130+
.map(|reference| source_edit_from_reference(reference, new_name))
131131
.collect::<Vec<_>>();
132132

133133
if edit.is_empty() {
@@ -285,6 +285,64 @@ mod tests {
285285
);
286286
}
287287

288+
#[test]
289+
fn test_rename_for_struct_field() {
290+
test_rename(
291+
r#"
292+
struct Foo {
293+
i<|>: i32,
294+
}
295+
296+
impl Foo {
297+
fn new(i: i32) -> Self {
298+
Self { i: i }
299+
}
300+
}
301+
"#,
302+
"j",
303+
r#"
304+
struct Foo {
305+
j: i32,
306+
}
307+
308+
impl Foo {
309+
fn new(i: i32) -> Self {
310+
Self { j: i }
311+
}
312+
}
313+
"#,
314+
);
315+
}
316+
317+
#[test]
318+
fn test_rename_for_struct_field_shorthand() {
319+
test_rename(
320+
r#"
321+
struct Foo {
322+
i<|>: i32,
323+
}
324+
325+
impl Foo {
326+
fn new(i: i32) -> Self {
327+
Self { i }
328+
}
329+
}
330+
"#,
331+
"j",
332+
r#"
333+
struct Foo {
334+
j: i32,
335+
}
336+
337+
impl Foo {
338+
fn new(i: i32) -> Self {
339+
Self { j: i }
340+
}
341+
}
342+
"#,
343+
);
344+
}
345+
288346
#[test]
289347
fn test_rename_mod() {
290348
let (analysis, position) = analysis_and_position(

crates/ra_ide_db/src/search.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_hash::FxHashMap;
1717
use test_utils::tested_by;
1818

1919
use crate::{
20-
defs::{classify_name_ref, Definition},
20+
defs::{classify_name_ref, Definition, NameRefClass},
2121
RootDatabase,
2222
};
2323

@@ -30,6 +30,7 @@ pub struct Reference {
3030

3131
#[derive(Debug, Clone, PartialEq)]
3232
pub enum ReferenceKind {
33+
StructFieldShorthand,
3334
StructLiteral,
3435
Other,
3536
}
@@ -237,9 +238,8 @@ impl Definition {
237238
// FIXME: reuse sb
238239
// See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
239240

240-
if let Some(d) = classify_name_ref(&sema, &name_ref) {
241-
let d = d.definition();
242-
if &d == self {
241+
match (classify_name_ref(&sema, &name_ref), self) {
242+
(Some(NameRefClass::Definition(def)), _) if &def == self => {
243243
let kind = if is_record_lit_name_ref(&name_ref)
244244
|| is_call_expr_name_ref(&name_ref)
245245
{
@@ -252,9 +252,21 @@ impl Definition {
252252
refs.push(Reference {
253253
file_range,
254254
kind,
255-
access: reference_access(&d, &name_ref),
255+
access: reference_access(&def, &name_ref),
256256
});
257257
}
258+
(
259+
Some(NameRefClass::FieldShorthand { local, field: _ }),
260+
Definition::StructField(_),
261+
) => {
262+
let file_range = sema.original_range(name_ref.syntax());
263+
refs.push(Reference {
264+
file_range: file_range,
265+
kind: ReferenceKind::StructFieldShorthand,
266+
access: reference_access(&Definition::Local(local), &name_ref),
267+
});
268+
}
269+
_ => {} // not a usage
258270
}
259271
}
260272
}

0 commit comments

Comments
 (0)