Struct field rename renames field in constructor field shorthand

This commit is contained in:
Matt Niemeir 2020-03-09 21:18:55 -05:00
parent 530ff9f57f
commit a9b6aec8a7
2 changed files with 96 additions and 26 deletions

View file

@ -9,7 +9,8 @@ use ra_syntax::{
use ra_text_edit::TextEdit; use ra_text_edit::TextEdit;
use crate::{ use crate::{
FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, SourceFileEdit, TextRange, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, SourceChange,
SourceFileEdit, TextRange,
}; };
use super::find_all_refs; use super::find_all_refs;
@ -46,12 +47,20 @@ fn find_name_and_module_at_offset(
Some((ast_name, ast_module)) Some((ast_name, ast_module))
} }
fn source_edit_from_file_id_range( fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFileEdit {
file_id: FileId, let mut replacement_text = String::from(new_name);
range: TextRange, let file_id = reference.file_range.file_id;
new_name: &str, let range = match reference.kind {
) -> SourceFileEdit { ReferenceKind::StructFieldShorthand => {
SourceFileEdit { file_id, edit: TextEdit::replace(range, new_name.into()) } replacement_text.push_str(": ");
TextRange::from_to(
reference.file_range.range.start(),
reference.file_range.range.start(),
)
}
_ => reference.file_range.range,
};
SourceFileEdit { file_id, edit: TextEdit::replace(range, replacement_text) }
} }
fn rename_mod( fn rename_mod(
@ -99,13 +108,10 @@ fn rename_mod(
source_file_edits.push(edit); source_file_edits.push(edit);
if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) { if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) {
let ref_edits = refs.references.into_iter().map(|reference| { let ref_edits = refs
source_edit_from_file_id_range( .references
reference.file_range.file_id, .into_iter()
reference.file_range.range, .map(|reference| source_edit_from_reference(reference, new_name));
new_name,
)
});
source_file_edits.extend(ref_edits); source_file_edits.extend(ref_edits);
} }
@ -121,13 +127,7 @@ fn rename_reference(
let edit = refs let edit = refs
.into_iter() .into_iter()
.map(|reference| { .map(|reference| source_edit_from_reference(reference, new_name))
source_edit_from_file_id_range(
reference.file_range.file_id,
reference.file_range.range,
new_name,
)
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if edit.is_empty() { if edit.is_empty() {
@ -285,6 +285,64 @@ mod tests {
); );
} }
#[test]
fn test_rename_for_struct_field() {
test_rename(
r#"
struct Foo {
i<|>: i32,
}
impl Foo {
fn new(i: i32) -> Self {
Self { i: i }
}
}
"#,
"j",
r#"
struct Foo {
j: i32,
}
impl Foo {
fn new(i: i32) -> Self {
Self { j: i }
}
}
"#,
);
}
#[test]
fn test_rename_for_struct_field_shorthand() {
test_rename(
r#"
struct Foo {
i<|>: i32,
}
impl Foo {
fn new(i: i32) -> Self {
Self { i }
}
}
"#,
"j",
r#"
struct Foo {
j: i32,
}
impl Foo {
fn new(i: i32) -> Self {
Self { j: i }
}
}
"#,
);
}
#[test] #[test]
fn test_rename_mod() { fn test_rename_mod() {
let (analysis, position) = analysis_and_position( let (analysis, position) = analysis_and_position(

View file

@ -17,7 +17,7 @@ use rustc_hash::FxHashMap;
use test_utils::tested_by; use test_utils::tested_by;
use crate::{ use crate::{
defs::{classify_name_ref, Definition}, defs::{classify_name_ref, Definition, NameRefClass},
RootDatabase, RootDatabase,
}; };
@ -30,6 +30,7 @@ pub struct Reference {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum ReferenceKind { pub enum ReferenceKind {
StructFieldShorthand,
StructLiteral, StructLiteral,
Other, Other,
} }
@ -237,9 +238,8 @@ impl Definition {
// FIXME: reuse sb // FIXME: reuse sb
// See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
if let Some(d) = classify_name_ref(&sema, &name_ref) { match (classify_name_ref(&sema, &name_ref), self) {
let d = d.definition(); (Some(NameRefClass::Definition(def)), _) if &def == self => {
if &d == self {
let kind = if is_record_lit_name_ref(&name_ref) let kind = if is_record_lit_name_ref(&name_ref)
|| is_call_expr_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref)
{ {
@ -252,9 +252,21 @@ impl Definition {
refs.push(Reference { refs.push(Reference {
file_range, file_range,
kind, kind,
access: reference_access(&d, &name_ref), access: reference_access(&def, &name_ref),
}); });
} }
(
Some(NameRefClass::FieldShorthand { local, field: _ }),
Definition::StructField(_),
) => {
let file_range = sema.original_range(name_ref.syntax());
refs.push(Reference {
file_range: file_range,
kind: ReferenceKind::StructFieldShorthand,
access: reference_access(&Definition::Local(local), &name_ref),
});
}
_ => {} // not a usage
} }
} }
} }