about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLuuk Wester <luuk.wester@gmail.com>2024-05-24 21:51:05 +0200
committerLuuk Wester <luuk.wester@gmail.com>2024-05-24 21:56:55 +0200
commite0d1092d63d80d32685e2aec3fe2fc0e70a106cb (patch)
treee7ff66bee9acf0e55a83c8ee154a8f1262eb3059 /src
parentab863527897916080e9ec451dbf109aad780ea19 (diff)
downloadrust-e0d1092d63d80d32685e2aec3fe2fc0e70a106cb.tar.gz
rust-e0d1092d63d80d32685e2aec3fe2fc0e70a106cb.zip
cosmetic and performance fixes, and drop support for adding //! comments anywhere, except
for at the top of files.
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs187
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs4
2 files changed, 78 insertions, 113 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs
index 1ac30d71f26..2e738834475 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs
@@ -11,12 +11,12 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 // Converts comments to documentation.
 //
 // ```
-// // Wow what $0a nice function
+// // Wow what $0a nice module
 // // I sure hope this shows up when I hover over it
 // ```
 // ->
 // ```
-// //! Wow what a nice function
+// //! Wow what a nice module
 // //! I sure hope this shows up when I hover over it
 // ```
 pub(crate) fn convert_comment_from_or_to_doc(
@@ -43,7 +43,7 @@ fn doc_to_comment(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
 
     acc.add(
         AssistId("doc_to_comment", AssistKind::RefactorRewrite),
-        "Replace a comment with doc comment",
+        "Replace comment with doc comment",
         target,
         |edit| {
             // We need to either replace the first occurrence of /* with /***, or we need to replace
@@ -52,11 +52,12 @@ fn doc_to_comment(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
                 ast::CommentShape::Line => {
                     let indentation = IndentLevel::from_token(comment.syntax());
                     let line_start = comment.prefix();
+                    let prefix = format!("{indentation}//");
                     relevant_line_comments(&comment)
                         .iter()
                         .map(|comment| comment.text())
                         .flat_map(|text| text.lines())
-                        .map(|line| indentation.to_string() + &line.replacen(line_start, "//", 1))
+                        .map(|line| line.replacen(line_start, &prefix, 1))
                         .join("\n")
                 }
                 ast::CommentShape::Block => {
@@ -89,23 +90,23 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
 
     acc.add(
         AssistId("comment_to_doc", AssistKind::RefactorRewrite),
-        "Replace a doc comment with comment",
+        "Replace doc comment with comment",
         target,
         |edit| {
             // We need to either replace the first occurrence of /* with /***, or we need to replace
             // the occurrences // at the start of each line with ///
             let output = match comment.kind().shape {
                 ast::CommentShape::Line => {
+                    let indentation = IndentLevel::from_token(comment.syntax());
                     let line_start = match style {
-                        CommentPlacement::Inner => "//!",
-                        CommentPlacement::Outer => "///",
+                        CommentPlacement::Inner => format!("{indentation}//!"),
+                        CommentPlacement::Outer => format!("{indentation}///"),
                     };
-                    let indentation = IndentLevel::from_token(comment.syntax());
                     relevant_line_comments(&comment)
                         .iter()
                         .map(|comment| comment.text())
                         .flat_map(|text| text.lines())
-                        .map(|line| indentation.to_string() + &line.replacen("//", line_start, 1))
+                        .map(|line| line.replacen("//", &line_start, 1))
                         .join("\n")
                 }
                 ast::CommentShape::Block => {
@@ -139,21 +140,21 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
 /// Not all comments are valid candidates for conversion into doc comments. For example, the
 /// comments in the code:
 /// ```rust
-/// // foos the bar
-/// fn foo_bar(foo: Foo) -> Bar {
-///   // Bar the foo
-///   foo.into_bar()
-/// }
+/// // Brilliant module right here
 ///
-/// trait A {
-///     // The A trait
+/// // Really good right
+/// fn good_function(foo: Foo) -> Bar {
+///     foo.into_bar()
 /// }
+///
+/// // So nice
+/// mod nice_module {}
 /// ```
 /// can be converted to doc comments. However, the comments in this example:
 /// ```rust
 /// fn foo_bar(foo: Foo /* not bar yet */) -> Bar {
-///   foo.into_bar()
-///   // Nicely done
+///     foo.into_bar()
+///     // Nicely done
 /// }
 /// // end of function
 ///
@@ -161,7 +162,23 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
 ///     // The S struct
 /// }
 /// ```
-/// are not allowed to become doc comments.
+/// are not allowed to become doc comments. Moreover, some comments _are_ allowed, but aren't common
+/// style in Rust. For example, the following comments are allowed to be doc comments, but it is not
+/// common style for them to be:
+/// ```rust
+/// fn foo_bar(foo: Foo) -> Bar {
+///     // this could be an inner comment with //!
+///     foo.into_bar()
+/// }
+///
+/// trait T {
+///     // The T struct could also be documented from within
+/// }
+///
+/// mod mymod {
+///     // Modules only normally get inner documentation when they are defined as a separate file.
+/// }
+/// ```
 fn can_be_doc_comment(comment: &ast::Comment) -> Option<CommentPlacement> {
     use syntax::SyntaxKind::*;
 
@@ -175,38 +192,12 @@ fn can_be_doc_comment(comment: &ast::Comment) -> Option<CommentPlacement> {
         None => return Some(CommentPlacement::Inner),
     }
 
-    // check if comment is followed by: `struct`, `trait`, `mod`, `fn`, `type`, `extern crate`, `use`, `const`
+    // check if comment is followed by: `struct`, `trait`, `mod`, `fn`, `type`, `extern crate`,
+    // `use` or `const`.
     let parent = comment.syntax().parent();
     let parent_kind = parent.as_ref().map(|parent| parent.kind());
-    if matches!(
-        parent_kind,
-        Some(STRUCT | TRAIT | MODULE | FN | TYPE_KW | EXTERN_CRATE | USE | CONST)
-    ) {
-        return Some(CommentPlacement::Outer);
-    }
-
-    // check if comment is preceded by: `fn f() {`, `trait T {`, `mod M {`:
-    let third_parent_kind = comment
-        .syntax()
-        .parent()
-        .and_then(|p| p.parent())
-        .and_then(|p| p.parent())
-        .map(|parent| parent.kind());
-    let is_first_item_in_parent = comment
-        .syntax()
-        .siblings_with_tokens(Direction::Prev)
-        .filter_map(|not| not.into_node())
-        .next()
-        .is_none();
-
-    if matches!(parent_kind, Some(STMT_LIST))
-        && is_first_item_in_parent
-        && matches!(third_parent_kind, Some(FN | TRAIT | MODULE))
-    {
-        return Some(CommentPlacement::Inner);
-    }
-
-    None
+    matches!(parent_kind, Some(STRUCT | TRAIT | MODULE | FN | TYPE_KW | EXTERN_CRATE | USE | CONST))
+        .then_some(CommentPlacement::Outer)
 }
 
 /// The line -> block assist can  be invoked from anywhere within a sequence of line comments.
@@ -467,39 +458,26 @@ mod tests {
 
     #[test]
     fn single_inner_line_comment_to_doc() {
-        check_assist(
+        check_assist_not_applicable(
             convert_comment_from_or_to_doc,
             r#"
-            fn main() {
+            mod mymod {
                 // unseen$0 docs
                 foo();
             }
             "#,
-            r#"
-            fn main() {
-                //! unseen docs
-                foo();
-            }
-            "#,
         );
     }
 
     #[test]
     fn multi_inner_line_comment_to_doc() {
-        check_assist(
+        check_assist_not_applicable(
             convert_comment_from_or_to_doc,
             r#"
-            fn main() {
+            mod mymod {
                 // unseen$0 docs
                 // make me seen!
-                foo();
-            }
-            "#,
-            r#"
-            fn main() {
-                //! unseen docs
-                //! make me seen!
-                foo();
+                type Int = i32;
             }
             "#,
         );
@@ -510,13 +488,13 @@ mod tests {
         check_assist(
             convert_comment_from_or_to_doc,
             r#"
-            fn main() {
+            mod mymod {
                 //! visible$0 docs
                 foo();
             }
             "#,
             r#"
-            fn main() {
+            mod mymod {
                 // visible docs
                 foo();
             }
@@ -529,58 +507,33 @@ mod tests {
         check_assist(
             convert_comment_from_or_to_doc,
             r#"
-            fn main() {
+            mod mymod {
                 //! visible$0 docs
                 //! Hide me!
                 foo();
             }
             "#,
             r#"
-            fn main() {
+            mod mymod {
                 // visible docs
                 // Hide me!
                 foo();
             }
             "#,
         );
-    }
-
-    #[test]
-    fn single_inner_line_block_comment_to_doc() {
-        check_assist(
-            convert_comment_from_or_to_doc,
-            r#"
-            fn main() {
-                /* unseen$0 docs */
-                foo();
-            }
-            "#,
-            r#"
-            fn main() {
-                /*! unseen docs */
-                foo();
-            }
-            "#,
-        );
-    }
-
-    #[test]
-    fn multi_inner_line_block_comment_to_doc() {
         check_assist(
             convert_comment_from_or_to_doc,
             r#"
-            fn main() {
-                /* unseen$0 docs
-                *  make me seen!
-                */
+            mod mymod {
+                /// visible$0 docs
+                /// Hide me!
                 foo();
             }
             "#,
             r#"
-            fn main() {
-                /*! unseen docs
-                *   make me seen!
-                */
+            mod mymod {
+                // visible docs
+                // Hide me!
                 foo();
             }
             "#,
@@ -592,15 +545,15 @@ mod tests {
         check_assist(
             convert_comment_from_or_to_doc,
             r#"
-            fn main() {
+            mod mymod {
                 /*! visible$0 docs */
-                foo();
+                type Int = i32;
             }
             "#,
             r#"
-            fn main() {
+            mod mymod {
                 /* visible docs */
-                foo();
+                type Int = i32;
             }
             "#,
         );
@@ -611,21 +564,21 @@ mod tests {
         check_assist(
             convert_comment_from_or_to_doc,
             r#"
-            fn main() {
+            mod mymod {
                 /*! visible$0 docs
                 *   Hide me!
                 */
-                foo();
+                type Int = i32;
             }
             "#,
             r#"
-            fn main() {
+            mod mymod {
                 /* visible docs
                 *  Hide me!
                 */
-                foo();
+                type Int = i32;
             }
-        "#,
+            "#,
         );
     }
 
@@ -642,4 +595,16 @@ mod tests {
             "#,
         );
     }
+
+    #[test]
+    fn no_inner_comments() {
+        check_assist_not_applicable(
+            convert_comment_from_or_to_doc,
+            r#"
+            mod mymod {
+                // aaa$0aa
+            }
+            "#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index bd841d72e6c..5ecce3cbb68 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -350,11 +350,11 @@ fn doctest_comment_to_doc() {
     check_doc_test(
         "comment_to_doc",
         r#####"
-// Wow what $0a nice function
+// Wow what $0a nice module
 // I sure hope this shows up when I hover over it
 "#####,
         r#####"
-//! Wow what a nice function
+//! Wow what a nice module
 //! I sure hope this shows up when I hover over it
 "#####,
     )