Add promote_mod_file assist
This commit is contained in:
parent
d270679997
commit
fede1a3beb
@ -294,6 +294,10 @@ pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<St
|
|||||||
let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
|
let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
|
||||||
self.source_change.push_file_system_edit(file_system_edit);
|
self.source_change.push_file_system_edit(file_system_edit);
|
||||||
}
|
}
|
||||||
|
pub(crate) fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
|
||||||
|
let file_system_edit = FileSystemEdit::MoveFile { src, dst };
|
||||||
|
self.source_change.push_file_system_edit(file_system_edit);
|
||||||
|
}
|
||||||
|
|
||||||
fn finish(mut self) -> SourceChange {
|
fn finish(mut self) -> SourceChange {
|
||||||
self.commit();
|
self.commit();
|
||||||
|
148
crates/ide_assists/src/handlers/promote_mod_file.rs
Normal file
148
crates/ide_assists/src/handlers/promote_mod_file.rs
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
use ide_db::{
|
||||||
|
assists::{AssistId, AssistKind},
|
||||||
|
base_db::AnchoredPathBuf,
|
||||||
|
};
|
||||||
|
use syntax::{
|
||||||
|
ast::{self},
|
||||||
|
AstNode, TextRange,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::assist_context::{AssistContext, Assists};
|
||||||
|
|
||||||
|
pub(crate) fn promote_mod_file(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||||
|
let source_file = ctx.find_node_at_offset::<ast::SourceFile>()?;
|
||||||
|
let module = ctx.sema.to_module_def(ctx.frange.file_id)?;
|
||||||
|
if module.is_mod_rs(ctx.db()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let target = TextRange::new(
|
||||||
|
source_file.syntax().text_range().start(),
|
||||||
|
source_file.syntax().text_range().end(),
|
||||||
|
);
|
||||||
|
let path = format!("./{}/mod.rs", module.name(ctx.db())?.to_string());
|
||||||
|
let dst = AnchoredPathBuf { anchor: ctx.frange.file_id, path };
|
||||||
|
acc.add(
|
||||||
|
AssistId("promote_mod_file", AssistKind::Refactor),
|
||||||
|
"Promote Module to directory",
|
||||||
|
target,
|
||||||
|
|builder| {
|
||||||
|
builder.move_file(ctx.frange.file_id, dst);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::tests::{check_assist, check_assist_not_applicable};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn trivial() {
|
||||||
|
check_assist(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"
|
||||||
|
//- /main.rs
|
||||||
|
mod a;
|
||||||
|
//- /a.rs
|
||||||
|
$0fn t() {}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
//- /a/mod.rs
|
||||||
|
fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cursor_can_be_putted_anywhere() {
|
||||||
|
check_assist(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"
|
||||||
|
//- /main.rs
|
||||||
|
mod a;
|
||||||
|
//- /a.rs
|
||||||
|
fn t() {}$0
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
//- /a/mod.rs
|
||||||
|
fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"
|
||||||
|
//- /main.rs
|
||||||
|
mod a;
|
||||||
|
//- /a.rs
|
||||||
|
fn t()$0 {}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
//- /a/mod.rs
|
||||||
|
fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"
|
||||||
|
//- /main.rs
|
||||||
|
mod a;
|
||||||
|
//- /a.rs
|
||||||
|
fn t($0) {}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
//- /a/mod.rs
|
||||||
|
fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cannot_promote_mod_rs() {
|
||||||
|
check_assist_not_applicable(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"//- /main.rs
|
||||||
|
mod a;
|
||||||
|
//- /a/mod.rs
|
||||||
|
$0fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cannot_promote_main_and_lib_rs() {
|
||||||
|
check_assist_not_applicable(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"//- /main.rs
|
||||||
|
$0fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_assist_not_applicable(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"//- /lib.rs
|
||||||
|
$0fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn works_in_mod() {
|
||||||
|
// note: /a/b.rs remains untouched
|
||||||
|
check_assist(
|
||||||
|
promote_mod_file,
|
||||||
|
r#"//- /main.rs
|
||||||
|
mod a;
|
||||||
|
//- /a.rs
|
||||||
|
mod b;
|
||||||
|
$0fn t() {}
|
||||||
|
//- /a/b.rs
|
||||||
|
fn t1() {}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
//- /a/mod.rs
|
||||||
|
mod b;
|
||||||
|
fn t() {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -96,6 +96,7 @@ mod handlers {
|
|||||||
mod move_bounds;
|
mod move_bounds;
|
||||||
mod move_guard;
|
mod move_guard;
|
||||||
mod move_module_to_file;
|
mod move_module_to_file;
|
||||||
|
mod promote_mod_file;
|
||||||
mod pull_assignment_up;
|
mod pull_assignment_up;
|
||||||
mod qualify_path;
|
mod qualify_path;
|
||||||
mod raw_string;
|
mod raw_string;
|
||||||
@ -167,6 +168,7 @@ pub(crate) fn all() -> &'static [Handler] {
|
|||||||
move_guard::move_arm_cond_to_match_guard,
|
move_guard::move_arm_cond_to_match_guard,
|
||||||
move_guard::move_guard_to_arm_body,
|
move_guard::move_guard_to_arm_body,
|
||||||
move_module_to_file::move_module_to_file,
|
move_module_to_file::move_module_to_file,
|
||||||
|
promote_mod_file::promote_mod_file,
|
||||||
pull_assignment_up::pull_assignment_up,
|
pull_assignment_up::pull_assignment_up,
|
||||||
qualify_path::qualify_path,
|
qualify_path::qualify_path,
|
||||||
raw_string::add_hash,
|
raw_string::add_hash,
|
||||||
|
@ -142,7 +142,6 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
|
|||||||
(Some(assist), ExpectedResult::After(after)) => {
|
(Some(assist), ExpectedResult::After(after)) => {
|
||||||
let source_change =
|
let source_change =
|
||||||
assist.source_change.expect("Assist did not contain any source changes");
|
assist.source_change.expect("Assist did not contain any source changes");
|
||||||
assert!(!source_change.source_file_edits.is_empty());
|
|
||||||
let skip_header = source_change.source_file_edits.len() == 1
|
let skip_header = source_change.source_file_edits.len() == 1
|
||||||
&& source_change.file_system_edits.len() == 0;
|
&& source_change.file_system_edits.len() == 0;
|
||||||
|
|
||||||
@ -160,15 +159,19 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for file_system_edit in source_change.file_system_edits {
|
for file_system_edit in source_change.file_system_edits {
|
||||||
if let FileSystemEdit::CreateFile { dst, initial_contents } = file_system_edit {
|
let (dst, contents) = match file_system_edit {
|
||||||
let sr = db.file_source_root(dst.anchor);
|
FileSystemEdit::CreateFile { dst, initial_contents } => (dst, initial_contents),
|
||||||
let sr = db.source_root(sr);
|
FileSystemEdit::MoveFile { src, dst } => {
|
||||||
let mut base = sr.path_for_file(&dst.anchor).unwrap().clone();
|
(dst, db.file_text(src).as_ref().to_owned())
|
||||||
base.pop();
|
}
|
||||||
let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]);
|
};
|
||||||
format_to!(buf, "//- {}\n", created_file_path);
|
let sr = db.file_source_root(dst.anchor);
|
||||||
buf.push_str(&initial_contents);
|
let sr = db.source_root(sr);
|
||||||
}
|
let mut base = sr.path_for_file(&dst.anchor).unwrap().clone();
|
||||||
|
base.pop();
|
||||||
|
let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]);
|
||||||
|
format_to!(buf, "//- {}\n", created_file_path);
|
||||||
|
buf.push_str(&contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq_text!(after, &buf);
|
assert_eq_text!(after, &buf);
|
||||||
|
Loading…
Reference in New Issue
Block a user