Repository: rust-analyzer/rust-analyzer
Pull request #7178 (2021-01-06 13:26:23)

Better target for move module
bors r+
🤖

bors[bot]: Build failed:
  * [Rust (ubuntu-latest)](https://github.com/rust-analyzer/rust-analyzer/runs/1656570033)

Patch:
diff --git a/crates/assists/src/handlers/extract_module_to_file.rs b/crates/assists/src/handlers/move_module_to_file.rs
similarity index 65%
rename from crates/assists/src/handlers/extract_module_to_file.rs
rename to crates/assists/src/handlers/move_module_to_file.rs
index 50bf67ef77..165faaf617 100644
--- a/crates/assists/src/handlers/extract_module_to_file.rs
+++ b/crates/assists/src/handlers/move_module_to_file.rs
@@ -2,17 +2,18 @@ use ast::edit::IndentLevel;
 use ide_db::base_db::AnchoredPathBuf;
 use syntax::{
     ast::{self, edit::AstNodeEdit, NameOwner},
-    AstNode,
+    AstNode, TextRange,
 };
+use test_utils::mark;
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
 
-// Assist: extract_module_to_file
+// Assist: move_module_to_file
 //
-// This assist extract module to file.
+// Moves inline module's contents to a separate file.
 //
 // ```
-// mod foo {<|>
+// mod <|>foo {
 //     fn t() {}
 // }
 // ```
@@ -20,19 +21,24 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 // ```
 // mod foo;
 // ```
-pub(crate) fn extract_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
+pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
     let module_ast = ctx.find_node_at_offset::<ast::Module>()?;
+    let module_items = module_ast.item_list()?;
+
+    let l_curly_offset = module_items.syntax().text_range().start();
+    if l_curly_offset <= ctx.offset() {
+        mark::hit!(available_before_curly);
+        return None;
+    }
+    let target = TextRange::new(module_ast.syntax().text_range().start(), l_curly_offset);
+
     let module_name = module_ast.name()?;
 
     let module_def = ctx.sema.to_def(&module_ast)?;
     let parent_module = module_def.parent(ctx.db())?;
 
-    let module_items = module_ast.item_list()?;
-    let target = module_ast.syntax().text_range();
-    let anchor_file_id = ctx.frange.file_id;
-
     acc.add(
-        AssistId("extract_module_to_file", AssistKind::RefactorExtract),
+        AssistId("move_module_to_file", AssistKind::RefactorExtract),
         "Extract module to file",
         target,
         |builder| {
@@ -53,9 +59,9 @@ pub(crate) fn extract_module_to_file(acc: &mut Assists, ctx: &AssistContext) ->
                 items
             };
 
-            builder.replace(target, format!("mod {};", module_name));
+            builder.replace(module_ast.syntax().text_range(), format!("mod {};", module_name));
 
-            let dst = AnchoredPathBuf { anchor: anchor_file_id, path };
+            let dst = AnchoredPathBuf { anchor: ctx.frange.file_id, path };
             builder.create_file(dst, contents);
         },
     )
@@ -63,16 +69,16 @@ pub(crate) fn extract_module_to_file(acc: &mut Assists, ctx: &AssistContext) ->
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::check_assist;
+    use crate::tests::{check_assist, check_assist_not_applicable};
 
     use super::*;
 
     #[test]
     fn extract_from_root() {
         check_assist(
-            extract_module_to_file,
+            move_module_to_file,
             r#"
-mod tests {<|>
+mod <|>tests {
     #[test] fn t() {}
 }
 "#,
@@ -88,12 +94,12 @@ mod tests;
     #[test]
     fn extract_from_submodule() {
         check_assist(
-            extract_module_to_file,
+            move_module_to_file,
             r#"
 //- /main.rs
 mod submod;
 //- /submod.rs
-mod inner<|> {
+<|>mod inner {
     fn f() {}
 }
 fn g() {}
@@ -111,7 +117,7 @@ fn f() {}
     #[test]
     fn extract_from_mod_rs() {
         check_assist(
-            extract_module_to_file,
+            move_module_to_file,
             r#"
 //- /main.rs
 mod submodule;
@@ -130,4 +136,10 @@ fn f() {}
 "#,
         );
     }
+
+    #[test]
+    fn available_before_curly() {
+        mark::check!(available_before_curly);
+        check_assist_not_applicable(move_module_to_file, r#"mod m { <|> }"#);
+    }
 }
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs
index 9c2a957357..5e3a1b3683 100644
--- a/crates/assists/src/lib.rs
+++ b/crates/assists/src/lib.rs
@@ -116,7 +116,6 @@ mod handlers {
     mod convert_integer_literal;
     mod early_return;
     mod expand_glob_import;
-    mod extract_module_to_file;
     mod extract_struct_from_enum_variant;
     mod extract_variable;
     mod fill_match_arms;
@@ -139,6 +138,7 @@ mod handlers {
     mod merge_match_arms;
     mod move_bounds;
     mod move_guard;
+    mod move_module_to_file;
     mod pull_assignment_up;
     mod qualify_path;
     mod raw_string;
@@ -169,7 +169,7 @@ mod handlers {
             convert_integer_literal::convert_integer_literal,
             early_return::convert_to_guarded_return,
             expand_glob_import::expand_glob_import,
-            extract_module_to_file::extract_module_to_file,
+            move_module_to_file::move_module_to_file,
             extract_struct_from_enum_variant::extract_struct_from_enum_variant,
             extract_variable::extract_variable,
             fill_match_arms::fill_match_arms,


Test patch:
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs
index b15352cf32..fdebee4fe5 100644
--- a/crates/assists/src/tests/generated.rs
+++ b/crates/assists/src/tests/generated.rs
@@ -237,21 +237,6 @@ fn qux(bar: Bar, baz: Baz) {}
     )
 }
 
-#[test]
-fn doctest_extract_module_to_file() {
-    check_doc_test(
-        "extract_module_to_file",
-        r#####"
-mod foo {<|>
-    fn t() {}
-}
-"#####,
-        r#####"
-mod foo;
-"#####,
-    )
-}
-
 #[test]
 fn doctest_extract_struct_from_enum_variant() {
     check_doc_test(
@@ -760,6 +745,21 @@ fn handle(action: Action) {
     )
 }
 
+#[test]
+fn doctest_move_module_to_file() {
+    check_doc_test(
+        "move_module_to_file",
+        r#####"
+mod <|>foo {
+    fn t() {}
+}
+"#####,
+        r#####"
+mod foo;
+"#####,
+    )
+}
+
 #[test]
 fn doctest_pull_assignment_up() {
     check_doc_test(