11883: fix(ide): move moudle directory when rename r=rainy-me a=rainy-me

fix: #10992

Added `FileSystemEdit::MoveDir` variant for move dirs. Original implemented as recursively move child mod files but had many issues like

1. left empty dir after rename file
2. only affect rust file
3. not performant

so changed to current version

Co-authored-by: rainy-me <github@yue.coffee>
This commit is contained in:
bors[bot] 2022-04-12 15:17:00 +00:00 committed by GitHub
commit 49847a25ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 106 additions and 13 deletions

View File

@ -968,15 +968,21 @@ fn test_rename_mod_in_dir() {
},
},
file_system_edits: [
MoveFile {
src: FileId(
MoveDir {
src: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "foo",
},
src_id: FileId(
1,
),
dst: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "../foo2/mod.rs",
path: "foo2",
},
},
],
@ -1113,6 +1119,68 @@ fn f() {
);
}
#[test]
fn test_rename_mod_recursive() {
check_expect(
"foo2",
r#"
//- /lib.rs
mod foo$0;
//- /foo.rs
mod bar;
mod corge;
//- /foo/bar.rs
mod qux;
//- /foo/bar/qux.rs
mod quux;
//- /foo/bar/qux/quux/mod.rs
// empty
//- /foo/corge.rs
// empty
"#,
expect![[r#"
SourceChange {
source_file_edits: {
FileId(
0,
): TextEdit {
indels: [
Indel {
insert: "foo2",
delete: 4..7,
},
],
},
},
file_system_edits: [
MoveDir {
src: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "foo",
},
src_id: FileId(
1,
),
dst: AnchoredPathBuf {
anchor: FileId(
1,
),
path: "foo2",
},
},
],
is_snippet: false,
}
"#]],
)
}
#[test]
fn test_rename_mod_ref_by_super() {
check(

View File

@ -162,6 +162,10 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
FileSystemEdit::MoveFile { src, dst } => {
(dst, db.file_text(src).as_ref().to_owned())
}
FileSystemEdit::MoveDir { src, src_id, dst } => {
// temporary placeholder for MoveDir since we are not using MoveDir in ide assists yet.
(dst, format!("{:?}\n{:?}", src_id, src))
}
};
let sr = db.file_source_root(dst.anchor);
let sr = db.source_root(sr);

View File

@ -178,17 +178,23 @@ fn rename_mod(
let mut source_change = SourceChange::default();
let InFile { file_id, value: def_source } = module.definition_source(sema.db);
let file_id = file_id.original_file(sema.db);
if let ModuleSource::SourceFile(..) = def_source {
// mod is defined in path/to/dir/mod.rs
let path = if module.is_mod_rs(sema.db) {
format!("../{}/mod.rs", new_name)
} else {
format!("{}.rs", new_name)
};
let dst = AnchoredPathBuf { anchor: file_id, path };
let move_file = FileSystemEdit::MoveFile { src: file_id, dst };
source_change.push_file_system_edit(move_file);
let anchor = file_id.original_file(sema.db);
// not mod.rs and doesn't has children, rename file only
if !module.is_mod_rs(sema.db) && module.children(sema.db).next().is_none() {
let path = format!("{}.rs", new_name);
let dst = AnchoredPathBuf { anchor, path };
source_change.push_file_system_edit(FileSystemEdit::MoveFile { src: anchor, dst })
} else if let Some(mod_name) = module.name(sema.db) {
// is mod.rs or has children, rename dir
let src = AnchoredPathBuf { anchor, path: mod_name.to_string() };
let dst = AnchoredPathBuf { anchor, path: new_name.to_string() };
source_change.push_file_system_edit(FileSystemEdit::MoveDir {
src,
src_id: anchor,
dst,
})
}
}
if let Some(src) = module.declaration_source(sema.db) {

View File

@ -85,6 +85,7 @@ fn from(source_file_edits: FxHashMap<FileId, TextEdit>) -> SourceChange {
pub enum FileSystemEdit {
CreateFile { dst: AnchoredPathBuf, initial_contents: String },
MoveFile { src: FileId, dst: AnchoredPathBuf },
MoveDir { src: AnchoredPathBuf, src_id: FileId, dst: AnchoredPathBuf },
}
impl From<FileSystemEdit> for SourceChange {

View File

@ -866,6 +866,20 @@ pub(crate) fn snippet_text_document_ops(
rename_file,
)))
}
FileSystemEdit::MoveDir { src, src_id, dst } => {
let old_uri = snap.anchored_path(&src);
let new_uri = snap.anchored_path(&dst);
let mut rename_file =
lsp_types::RenameFile { old_uri, new_uri, options: None, annotation_id: None };
if snap.analysis.is_library_file(src_id).ok() == Some(true)
&& snap.config.change_annotation_support()
{
rename_file.annotation_id = Some(outside_workspace_annotation_id())
}
ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename(
rename_file,
)))
}
}
Ok(ops)
}