5212: Fix module renaming r=matklad a=matklad



bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-07-03 16:55:01 +00:00 committed by GitHub
commit a434ecef51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -116,8 +116,7 @@ fn rename_mod(
} else { } else {
format!("{}.rs", new_name) format!("{}.rs", new_name)
}; };
let move_file = let move_file = FileSystemEdit::MoveFile { src: file_id, anchor: file_id, dst };
FileSystemEdit::MoveFile { src: file_id, anchor: position.file_id, dst };
file_system_edits.push(move_file); file_system_edits.push(move_file);
} }
ModuleSource::Module(..) => {} ModuleSource::Module(..) => {}
@ -271,51 +270,51 @@ fn rename_reference(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use insta::assert_debug_snapshot; use expect::{expect, Expect};
use ra_text_edit::TextEditBuilder; use ra_text_edit::TextEditBuilder;
use stdx::trim_indent; use stdx::trim_indent;
use test_utils::{assert_eq_text, mark}; use test_utils::{assert_eq_text, mark};
use crate::{mock_analysis::analysis_and_position, FileId}; use crate::{mock_analysis::analysis_and_position, FileId};
fn check(new_name: &str, ra_fixture_before: &str, ra_fixture_after: &str) {
let ra_fixture_after = &trim_indent(ra_fixture_after);
let (analysis, position) = analysis_and_position(ra_fixture_before);
let source_change = analysis.rename(position, new_name).unwrap();
let mut text_edit_builder = TextEditBuilder::default();
let mut file_id: Option<FileId> = None;
if let Some(change) = source_change {
for edit in change.info.source_file_edits {
file_id = Some(edit.file_id);
for indel in edit.edit.into_iter() {
text_edit_builder.replace(indel.delete, indel.insert);
}
}
}
let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string();
text_edit_builder.finish().apply(&mut result);
assert_eq_text!(ra_fixture_after, &*result);
}
fn check_expect(new_name: &str, ra_fixture: &str, expect: Expect) {
let (analysis, position) = analysis_and_position(ra_fixture);
let source_change = analysis.rename(position, new_name).unwrap().unwrap();
expect.assert_debug_eq(&source_change)
}
#[test] #[test]
fn test_rename_to_underscore() { fn test_rename_to_underscore() {
test_rename( check("_", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let _ = 1; }"#);
r#"
fn main() {
let i<|> = 1;
}"#,
"_",
r#"
fn main() {
let _ = 1;
}"#,
);
} }
#[test] #[test]
fn test_rename_to_raw_identifier() { fn test_rename_to_raw_identifier() {
test_rename( check("r#fn", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let r#fn = 1; }"#);
r#"
fn main() {
let i<|> = 1;
}"#,
"r#fn",
r#"
fn main() {
let r#fn = 1;
}"#,
);
} }
#[test] #[test]
fn test_rename_to_invalid_identifier() { fn test_rename_to_invalid_identifier() {
let (analysis, position) = analysis_and_position( let (analysis, position) = analysis_and_position(r#"fn main() { let i<|> = 1; }"#);
"
fn main() {
let i<|> = 1;
}",
);
let new_name = "invalid!"; let new_name = "invalid!";
let source_change = analysis.rename(position, new_name).unwrap(); let source_change = analysis.rename(position, new_name).unwrap();
assert!(source_change.is_none()); assert!(source_change.is_none());
@ -323,163 +322,138 @@ mod tests {
#[test] #[test]
fn test_rename_for_local() { fn test_rename_for_local() {
test_rename( check(
"k",
r#" r#"
fn main() { fn main() {
let mut i = 1; let mut i = 1;
let j = 1; let j = 1;
i = i<|> + j; i = i<|> + j;
{ { i = 0; }
i = 0;
}
i = 5; i = 5;
}"#, }
"k", "#,
r#" r#"
fn main() { fn main() {
let mut k = 1; let mut k = 1;
let j = 1; let j = 1;
k = k + j; k = k + j;
{ { k = 0; }
k = 0;
}
k = 5; k = 5;
}"#, }
"#,
); );
} }
#[test] #[test]
fn test_rename_for_macro_args() { fn test_rename_for_macro_args() {
test_rename( check(
"b",
r#" r#"
macro_rules! foo {($i:ident) => {$i} } macro_rules! foo {($i:ident) => {$i} }
fn main() { fn main() {
let a<|> = "test"; let a<|> = "test";
foo!(a); foo!(a);
}"#, }
"b", "#,
r#" r#"
macro_rules! foo {($i:ident) => {$i} } macro_rules! foo {($i:ident) => {$i} }
fn main() { fn main() {
let b = "test"; let b = "test";
foo!(b); foo!(b);
}"#, }
"#,
); );
} }
#[test] #[test]
fn test_rename_for_macro_args_rev() { fn test_rename_for_macro_args_rev() {
test_rename( check(
"b",
r#" r#"
macro_rules! foo {($i:ident) => {$i} } macro_rules! foo {($i:ident) => {$i} }
fn main() { fn main() {
let a = "test"; let a = "test";
foo!(a<|>); foo!(a<|>);
}"#, }
"b", "#,
r#" r#"
macro_rules! foo {($i:ident) => {$i} } macro_rules! foo {($i:ident) => {$i} }
fn main() { fn main() {
let b = "test"; let b = "test";
foo!(b); foo!(b);
}"#, }
"#,
); );
} }
#[test] #[test]
fn test_rename_for_macro_define_fn() { fn test_rename_for_macro_define_fn() {
test_rename( check(
"bar",
r#" r#"
macro_rules! define_fn {($id:ident) => { fn $id{} }} macro_rules! define_fn {($id:ident) => { fn $id{} }}
define_fn!(foo); define_fn!(foo);
fn main() { fn main() {
fo<|>o(); fo<|>o();
}"#, }
"bar", "#,
r#" r#"
macro_rules! define_fn {($id:ident) => { fn $id{} }} macro_rules! define_fn {($id:ident) => { fn $id{} }}
define_fn!(bar); define_fn!(bar);
fn main() { fn main() {
bar(); bar();
}"#, }
"#,
); );
} }
#[test] #[test]
fn test_rename_for_macro_define_fn_rev() { fn test_rename_for_macro_define_fn_rev() {
test_rename( check(
"bar",
r#" r#"
macro_rules! define_fn {($id:ident) => { fn $id{} }} macro_rules! define_fn {($id:ident) => { fn $id{} }}
define_fn!(fo<|>o); define_fn!(fo<|>o);
fn main() { fn main() {
foo(); foo();
}"#, }
"bar", "#,
r#" r#"
macro_rules! define_fn {($id:ident) => { fn $id{} }} macro_rules! define_fn {($id:ident) => { fn $id{} }}
define_fn!(bar); define_fn!(bar);
fn main() { fn main() {
bar(); bar();
}"#, }
"#,
); );
} }
#[test] #[test]
fn test_rename_for_param_inside() { fn test_rename_for_param_inside() {
test_rename( check("j", r#"fn foo(i : u32) -> u32 { i<|> }"#, r#"fn foo(j : u32) -> u32 { j }"#);
r#"
fn foo(i : u32) -> u32 {
i<|>
}"#,
"j",
r#"
fn foo(j : u32) -> u32 {
j
}"#,
);
} }
#[test] #[test]
fn test_rename_refs_for_fn_param() { fn test_rename_refs_for_fn_param() {
test_rename( check("j", r#"fn foo(i<|> : u32) -> u32 { i }"#, r#"fn foo(j : u32) -> u32 { j }"#);
r#"
fn foo(i<|> : u32) -> u32 {
i
}"#,
"new_name",
r#"
fn foo(new_name : u32) -> u32 {
new_name
}"#,
);
} }
#[test] #[test]
fn test_rename_for_mut_param() { fn test_rename_for_mut_param() {
test_rename( check("j", r#"fn foo(mut i<|> : u32) -> u32 { i }"#, r#"fn foo(mut j : u32) -> u32 { j }"#);
r#"
fn foo(mut i<|> : u32) -> u32 {
i
}"#,
"new_name",
r#"
fn foo(mut new_name : u32) -> u32 {
new_name
}"#,
);
} }
#[test] #[test]
fn test_rename_struct_field() { fn test_rename_struct_field() {
test_rename( check(
"j",
r#" r#"
struct Foo { struct Foo { i<|>: i32 }
i<|>: i32,
}
impl Foo { impl Foo {
fn new(i: i32) -> Self { fn new(i: i32) -> Self {
@ -487,11 +461,8 @@ mod tests {
} }
} }
"#, "#,
"j",
r#" r#"
struct Foo { struct Foo { j: i32 }
j: i32,
}
impl Foo { impl Foo {
fn new(i: i32) -> Self { fn new(i: i32) -> Self {
@ -505,11 +476,10 @@ mod tests {
#[test] #[test]
fn test_rename_struct_field_for_shorthand() { fn test_rename_struct_field_for_shorthand() {
mark::check!(test_rename_struct_field_for_shorthand); mark::check!(test_rename_struct_field_for_shorthand);
test_rename( check(
"j",
r#" r#"
struct Foo { struct Foo { i<|>: i32 }
i<|>: i32,
}
impl Foo { impl Foo {
fn new(i: i32) -> Self { fn new(i: i32) -> Self {
@ -517,11 +487,8 @@ mod tests {
} }
} }
"#, "#,
"j",
r#" r#"
struct Foo { struct Foo { j: i32 }
j: i32,
}
impl Foo { impl Foo {
fn new(i: i32) -> Self { fn new(i: i32) -> Self {
@ -535,11 +502,10 @@ mod tests {
#[test] #[test]
fn test_rename_local_for_field_shorthand() { fn test_rename_local_for_field_shorthand() {
mark::check!(test_rename_local_for_field_shorthand); mark::check!(test_rename_local_for_field_shorthand);
test_rename( check(
"j",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn new(i<|>: i32) -> Self { fn new(i<|>: i32) -> Self {
@ -547,11 +513,8 @@ mod tests {
} }
} }
"#, "#,
"j",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn new(j: i32) -> Self { fn new(j: i32) -> Self {
@ -564,15 +527,11 @@ mod tests {
#[test] #[test]
fn test_field_shorthand_correct_struct() { fn test_field_shorthand_correct_struct() {
test_rename( check(
"j",
r#" r#"
struct Foo { struct Foo { i<|>: i32 }
i<|>: i32, struct Bar { i: i32 }
}
struct Bar {
i: i32,
}
impl Bar { impl Bar {
fn new(i: i32) -> Self { fn new(i: i32) -> Self {
@ -580,15 +539,9 @@ mod tests {
} }
} }
"#, "#,
"j",
r#" r#"
struct Foo { struct Foo { j: i32 }
j: i32, struct Bar { i: i32 }
}
struct Bar {
i: i32,
}
impl Bar { impl Bar {
fn new(i: i32) -> Self { fn new(i: i32) -> Self {
@ -601,11 +554,10 @@ mod tests {
#[test] #[test]
fn test_shadow_local_for_struct_shorthand() { fn test_shadow_local_for_struct_shorthand() {
test_rename( check(
"j",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
fn baz(i<|>: i32) -> Self { fn baz(i<|>: i32) -> Self {
let x = Foo { i }; let x = Foo { i };
@ -615,11 +567,8 @@ mod tests {
} }
} }
"#, "#,
"j",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
fn baz(j: i32) -> Self { fn baz(j: i32) -> Self {
let x = Foo { i: j }; let x = Foo { i: j };
@ -634,7 +583,8 @@ mod tests {
#[test] #[test]
fn test_rename_mod() { fn test_rename_mod() {
let (analysis, position) = analysis_and_position( check_expect(
"foo2",
r#" r#"
//- /lib.rs //- /lib.rs
mod bar; mod bar;
@ -643,14 +593,9 @@ mod bar;
mod foo<|>; mod foo<|>;
//- /bar/foo.rs //- /bar/foo.rs
// emtpy // empty
"#, "#,
); expect![[r#"
let new_name = "foo2";
let source_change = analysis.rename(position, new_name).unwrap();
assert_debug_snapshot!(&source_change,
@r###"
Some(
RangeInfo { RangeInfo {
range: 4..7, range: 4..7,
info: SourceChange { info: SourceChange {
@ -675,21 +620,22 @@ mod foo<|>;
3, 3,
), ),
anchor: FileId( anchor: FileId(
2, 3,
), ),
dst: "foo2.rs", dst: "foo2.rs",
}, },
], ],
is_snippet: false, is_snippet: false,
}, },
}, }
) "#]],
"###); );
} }
#[test] #[test]
fn test_rename_mod_in_use_tree() { fn test_rename_mod_in_use_tree() {
let (analysis, position) = analysis_and_position( check_expect(
"quux",
r#" r#"
//- /main.rs //- /main.rs
pub mod foo; pub mod foo;
@ -702,12 +648,7 @@ pub struct FooContent;
//- /bar.rs //- /bar.rs
use crate::foo<|>::FooContent; use crate::foo<|>::FooContent;
"#, "#,
); expect![[r#"
let new_name = "qux";
let source_change = analysis.rename(position, new_name).unwrap();
assert_debug_snapshot!(&source_change,
@r###"
Some(
RangeInfo { RangeInfo {
range: 11..14, range: 11..14,
info: SourceChange { info: SourceChange {
@ -719,7 +660,7 @@ use crate::foo<|>::FooContent;
edit: TextEdit { edit: TextEdit {
indels: [ indels: [
Indel { Indel {
insert: "qux", insert: "quux",
delete: 8..11, delete: 8..11,
}, },
], ],
@ -732,7 +673,7 @@ use crate::foo<|>::FooContent;
edit: TextEdit { edit: TextEdit {
indels: [ indels: [
Indel { Indel {
insert: "qux", insert: "quux",
delete: 11..14, delete: 11..14,
}, },
], ],
@ -745,33 +686,29 @@ use crate::foo<|>::FooContent;
2, 2,
), ),
anchor: FileId( anchor: FileId(
3, 2,
), ),
dst: "qux.rs", dst: "quux.rs",
}, },
], ],
is_snippet: false, is_snippet: false,
}, },
}, }
) "#]],
"###); );
} }
#[test] #[test]
fn test_rename_mod_in_dir() { fn test_rename_mod_in_dir() {
let (analysis, position) = analysis_and_position( check_expect(
"foo2",
r#" r#"
//- /lib.rs //- /lib.rs
mod fo<|>o; mod fo<|>o;
//- /foo/mod.rs //- /foo/mod.rs
// emtpy // emtpy
"#, "#,
); expect![[r#"
let new_name = "foo2";
let source_change = analysis.rename(position, new_name).unwrap();
assert_debug_snapshot!(&source_change,
@r###"
Some(
RangeInfo { RangeInfo {
range: 4..7, range: 4..7,
info: SourceChange { info: SourceChange {
@ -796,45 +733,87 @@ mod fo<|>o;
2, 2,
), ),
anchor: FileId( anchor: FileId(
1, 2,
), ),
dst: "../foo2/mod.rs", dst: "../foo2/mod.rs",
}, },
], ],
is_snippet: false, is_snippet: false,
}, },
}
"#]],
);
}
#[test]
fn test_rename_unusually_nested_mod() {
check_expect(
"bar",
r#"
//- /lib.rs
mod outer { mod fo<|>o; }
//- /outer/foo.rs
// emtpy
"#,
expect![[r#"
RangeInfo {
range: 16..19,
info: SourceChange {
source_file_edits: [
SourceFileEdit {
file_id: FileId(
1,
),
edit: TextEdit {
indels: [
Indel {
insert: "bar",
delete: 16..19,
}, },
) ],
"### },
},
],
file_system_edits: [
MoveFile {
src: FileId(
2,
),
anchor: FileId(
2,
),
dst: "bar.rs",
},
],
is_snippet: false,
},
}
"#]],
); );
} }
#[test] #[test]
fn test_module_rename_in_path() { fn test_module_rename_in_path() {
test_rename( check(
r#"
mod <|>foo {
pub fn bar() {}
}
fn main() {
foo::bar();
}"#,
"baz", "baz",
r#" r#"
mod baz { mod <|>foo { pub fn bar() {} }
pub fn bar() {}
}
fn main() { fn main() { foo::bar(); }
baz::bar(); "#,
}"#, r#"
mod baz { pub fn bar() {} }
fn main() { baz::bar(); }
"#,
); );
} }
#[test] #[test]
fn test_rename_mod_filename_and_path() { fn test_rename_mod_filename_and_path() {
let (analysis, position) = analysis_and_position( check_expect(
"foo2",
r#" r#"
//- /lib.rs //- /lib.rs
mod bar; mod bar;
@ -848,12 +827,7 @@ pub mod foo<|>;
//- /bar/foo.rs //- /bar/foo.rs
// pub fn fun() {} // pub fn fun() {}
"#, "#,
); expect![[r#"
let new_name = "foo2";
let source_change = analysis.rename(position, new_name).unwrap();
assert_debug_snapshot!(&source_change,
@r###"
Some(
RangeInfo { RangeInfo {
range: 8..11, range: 8..11,
info: SourceChange { info: SourceChange {
@ -891,26 +865,25 @@ pub mod foo<|>;
3, 3,
), ),
anchor: FileId( anchor: FileId(
2, 3,
), ),
dst: "foo2.rs", dst: "foo2.rs",
}, },
], ],
is_snippet: false, is_snippet: false,
}, },
}, }
) "#]],
"###); );
} }
#[test] #[test]
fn test_enum_variant_from_module_1() { fn test_enum_variant_from_module_1() {
test_rename( check(
"Baz",
r#" r#"
mod foo { mod foo {
pub enum Foo { pub enum Foo { Bar<|> }
Bar<|>,
}
} }
fn func(f: foo::Foo) { fn func(f: foo::Foo) {
@ -919,12 +892,9 @@ pub mod foo<|>;
} }
} }
"#, "#,
"Baz",
r#" r#"
mod foo { mod foo {
pub enum Foo { pub enum Foo { Baz }
Baz,
}
} }
fn func(f: foo::Foo) { fn func(f: foo::Foo) {
@ -938,24 +908,20 @@ pub mod foo<|>;
#[test] #[test]
fn test_enum_variant_from_module_2() { fn test_enum_variant_from_module_2() {
test_rename( check(
"baz",
r#" r#"
mod foo { mod foo {
pub struct Foo { pub struct Foo { pub bar<|>: uint }
pub bar<|>: uint,
}
} }
fn foo(f: foo::Foo) { fn foo(f: foo::Foo) {
let _ = f.bar; let _ = f.bar;
} }
"#, "#,
"baz",
r#" r#"
mod foo { mod foo {
pub struct Foo { pub struct Foo { pub baz: uint }
pub baz: uint,
}
} }
fn foo(f: foo::Foo) { fn foo(f: foo::Foo) {
@ -967,11 +933,10 @@ pub mod foo<|>;
#[test] #[test]
fn test_parameter_to_self() { fn test_parameter_to_self() {
test_rename( check(
"self",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn f(foo<|>: &mut Foo) -> i32 { fn f(foo<|>: &mut Foo) -> i32 {
@ -979,11 +944,8 @@ pub mod foo<|>;
} }
} }
"#, "#,
"self",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn f(&mut self) -> i32 { fn f(&mut self) -> i32 {
@ -996,11 +958,10 @@ pub mod foo<|>;
#[test] #[test]
fn test_self_to_parameter() { fn test_self_to_parameter() {
test_rename( check(
"foo",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn f(&mut <|>self) -> i32 { fn f(&mut <|>self) -> i32 {
@ -1008,11 +969,8 @@ pub mod foo<|>;
} }
} }
"#, "#,
"foo",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn f(foo: &mut Foo) -> i32 { fn f(foo: &mut Foo) -> i32 {
@ -1025,11 +983,10 @@ pub mod foo<|>;
#[test] #[test]
fn test_self_in_path_to_parameter() { fn test_self_in_path_to_parameter() {
test_rename( check(
"foo",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn f(&self) -> i32 { fn f(&self) -> i32 {
@ -1038,11 +995,8 @@ pub mod foo<|>;
} }
} }
"#, "#,
"foo",
r#" r#"
struct Foo { struct Foo { i: i32 }
i: i32,
}
impl Foo { impl Foo {
fn f(foo: &Foo) -> i32 { fn f(foo: &Foo) -> i32 {
@ -1053,23 +1007,4 @@ pub mod foo<|>;
"#, "#,
); );
} }
fn test_rename(ra_fixture_before: &str, new_name: &str, ra_fixture_after: &str) {
let ra_fixture_after = &trim_indent(ra_fixture_after);
let (analysis, position) = analysis_and_position(ra_fixture_before);
let source_change = analysis.rename(position, new_name).unwrap();
let mut text_edit_builder = TextEditBuilder::default();
let mut file_id: Option<FileId> = None;
if let Some(change) = source_change {
for edit in change.info.source_file_edits {
file_id = Some(edit.file_id);
for indel in edit.edit.into_iter() {
text_edit_builder.replace(indel.delete, indel.insert);
}
}
}
let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string();
text_edit_builder.finish().apply(&mut result);
assert_eq_text!(ra_fixture_after, &*result);
}
} }