fix: don't include r# prefix in filesystem changes

This commit is contained in:
Ryo Yoshida 2023-02-13 18:44:53 +09:00
parent 92fdfb548e
commit 9b0daf20c9
No known key found for this signature in database
GPG Key ID: E25698A930586171
2 changed files with 150 additions and 4 deletions

View File

@ -190,6 +190,7 @@ fn rename_mod(
let InFile { file_id, value: def_source } = module.definition_source(sema.db);
if let ModuleSource::SourceFile(..) = def_source {
let new_name = new_name.trim_start_matches("r#");
let anchor = file_id.original_file(sema.db);
let is_mod_rs = module.is_mod_rs(sema.db);
@ -207,9 +208,13 @@ fn rename_mod(
// - Module has submodules defined in separate files
let dir_paths = match (is_mod_rs, has_detached_child, module.name(sema.db)) {
// Go up one level since the anchor is inside the dir we're trying to rename
(true, _, Some(mod_name)) => Some((format!("../{mod_name}"), format!("../{new_name}"))),
(true, _, Some(mod_name)) => {
Some((format!("../{}", mod_name.unescaped()), format!("../{new_name}")))
}
// The anchor is on the same level as target dir
(false, true, Some(mod_name)) => Some((mod_name.to_string(), new_name.to_string())),
(false, true, Some(mod_name)) => {
Some((mod_name.unescaped().to_string(), new_name.to_string()))
}
_ => None,
};

View File

@ -13,7 +13,7 @@
};
use itertools::Itertools;
use stdx::{always, never};
use syntax::{ast, AstNode, SyntaxNode, TextRange, TextSize};
use syntax::{ast, utils::is_raw_identifier, AstNode, SmolStr, SyntaxNode, TextRange, TextSize};
use text_edit::TextEdit;
@ -122,7 +122,11 @@ pub(crate) fn will_rename_file(
let sema = Semantics::new(db);
let module = sema.to_module_def(file_id)?;
let def = Definition::Module(module);
let mut change = def.rename(&sema, new_name_stem).ok()?;
let mut change = if is_raw_identifier(new_name_stem) {
def.rename(&sema, &SmolStr::from_iter(["r#", new_name_stem])).ok()?
} else {
def.rename(&sema, new_name_stem).ok()?
};
change.file_system_edits.clear();
Some(change)
}
@ -1286,6 +1290,143 @@ fn foo() {}
)
}
#[test]
fn test_rename_mod_to_raw_ident() {
check_expect(
"r#fn",
r#"
//- /lib.rs
mod foo$0;
fn main() { foo::bar::baz(); }
//- /foo.rs
pub mod bar;
//- /foo/bar.rs
pub fn baz() {}
"#,
expect![[r#"
SourceChange {
source_file_edits: {
FileId(
0,
): TextEdit {
indels: [
Indel {
insert: "r#fn",
delete: 4..7,
},
Indel {
insert: "r#fn",
delete: 22..25,
},
],
},
},
file_system_edits: [
MoveFile {
src: FileId(
1,
),
dst: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "fn.rs",
},
},
MoveDir {
src: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "foo",
},
src_id: FileId(
1,
),
dst: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "fn",
},
},
],
is_snippet: false,
}
"#]],
);
}
#[test]
fn test_rename_mod_from_raw_ident() {
// FIXME: `r#fn` in path expression is not renamed.
check_expect(
"foo",
r#"
//- /lib.rs
mod r#fn$0;
fn main() { r#fn::bar::baz(); }
//- /fn.rs
pub mod bar;
//- /fn/bar.rs
pub fn baz() {}
"#,
expect![[r#"
SourceChange {
source_file_edits: {
FileId(
0,
): TextEdit {
indels: [
Indel {
insert: "foo",
delete: 4..8,
},
],
},
},
file_system_edits: [
MoveFile {
src: FileId(
1,
),
dst: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "foo.rs",
},
},
MoveDir {
src: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "fn",
},
src_id: FileId(
1,
),
dst: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "foo",
},
},
],
is_snippet: false,
}
"#]],
);
}
#[test]
fn test_enum_variant_from_module_1() {
cov_mark::check!(rename_non_local);