rust/crates/ide-assists/src/handlers/move_from_mod_rs.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

131 lines
2.8 KiB
Rust
Raw Normal View History

2021-09-27 21:20:29 -05:00
use ide_db::{
assists::{AssistId, AssistKind},
base_db::AnchoredPathBuf,
};
2021-09-27 21:20:35 -05:00
use syntax::{ast, AstNode};
2021-09-27 21:20:29 -05:00
2021-09-27 21:20:35 -05:00
use crate::{
assist_context::{AssistContext, Assists},
utils::trimmed_text_range,
};
2021-09-27 21:20:29 -05:00
// Assist: move_from_mod_rs
//
// Moves xxx/mod.rs to xxx.rs.
//
// ```
// //- /main.rs
// mod a;
// //- /a/mod.rs
// $0fn t() {}$0
// ```
// ->
// ```
// fn t() {}
// ```
pub(crate) fn move_from_mod_rs(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let source_file = ctx.find_node_at_offset::<ast::SourceFile>()?;
2021-10-13 07:39:37 -05:00
let module = ctx.sema.to_module_def(ctx.file_id())?;
2021-09-27 21:20:29 -05:00
// Enable this assist if the user select all "meaningful" content in the source file
let trimmed_selected_range = trimmed_text_range(&source_file, ctx.selection_trimmed());
2021-09-27 21:20:29 -05:00
let trimmed_file_range = trimmed_text_range(&source_file, source_file.syntax().text_range());
if !module.is_mod_rs(ctx.db()) {
cov_mark::hit!(not_mod_rs);
return None;
}
if trimmed_selected_range != trimmed_file_range {
cov_mark::hit!(not_all_selected);
return None;
}
2021-09-27 21:20:35 -05:00
let target = source_file.syntax().text_range();
2021-09-27 21:20:29 -05:00
let module_name = module.name(ctx.db())?.to_string();
let path = format!("../{}.rs", module_name);
2021-10-13 07:39:37 -05:00
let dst = AnchoredPathBuf { anchor: ctx.file_id(), path };
2021-09-27 21:20:29 -05:00
acc.add(
AssistId("move_from_mod_rs", AssistKind::Refactor),
2021-09-27 21:20:35 -05:00
format!("Convert {}/mod.rs to {}.rs", module_name, module_name),
2021-09-27 21:20:29 -05:00
target,
|builder| {
2021-10-13 07:39:37 -05:00
builder.move_file(ctx.file_id(), dst);
2021-09-27 21:20:29 -05:00
},
)
}
#[cfg(test)]
mod tests {
use crate::tests::{check_assist, check_assist_not_applicable};
use super::*;
#[test]
fn trivial() {
check_assist(
move_from_mod_rs,
r#"
//- /main.rs
mod a;
//- /a/mod.rs
$0fn t() {}
$0"#,
r#"
//- /a.rs
fn t() {}
"#,
);
}
#[test]
fn must_select_all_file() {
cov_mark::check!(not_all_selected);
check_assist_not_applicable(
move_from_mod_rs,
r#"
//- /main.rs
mod a;
//- /a/mod.rs
fn t() {}$0
"#,
);
cov_mark::check!(not_all_selected);
check_assist_not_applicable(
move_from_mod_rs,
r#"
//- /main.rs
mod a;
//- /a/mod.rs
$0fn$0 t() {}
"#,
);
}
#[test]
fn cannot_move_not_mod_rs() {
cov_mark::check!(not_mod_rs);
check_assist_not_applicable(
move_from_mod_rs,
r#"//- /main.rs
mod a;
//- /a.rs
$0fn t() {}$0
"#,
);
}
#[test]
fn cannot_downgrade_main_and_lib_rs() {
check_assist_not_applicable(
move_from_mod_rs,
r#"//- /main.rs
$0fn t() {}$0
"#,
);
check_assist_not_applicable(
move_from_mod_rs,
r#"//- /lib.rs
$0fn t() {}$0
"#,
);
}
}