use ide_db::{ assists::{AssistId, AssistKind}, base_db::AnchoredPathBuf, }; use syntax::{ast, AstNode}; use crate::{ assist_context::{AssistContext, Assists}, utils::trimmed_text_range, }; // 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::()?; let module = ctx.sema.to_module_def(ctx.file_id())?; // 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()); 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; } let target = source_file.syntax().text_range(); let module_name = module.name(ctx.db())?.to_string(); let path = format!("../{module_name}.rs"); let dst = AnchoredPathBuf { anchor: ctx.file_id(), path }; acc.add( AssistId("move_from_mod_rs", AssistKind::Refactor), format!("Convert {module_name}/mod.rs to {module_name}.rs"), target, |builder| { builder.move_file(ctx.file_id(), dst); }, ) } #[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 "#, ); } }