Skip to content

Commit e0d1092

Browse files
committed
cosmetic and performance fixes, and drop support for adding //! comments anywhere, except
for at the top of files.
1 parent ab86352 commit e0d1092

File tree

2 files changed

+78
-113
lines changed

2 files changed

+78
-113
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs

Lines changed: 76 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
1111
// Converts comments to documentation.
1212
//
1313
// ```
14-
// // Wow what $0a nice function
14+
// // Wow what $0a nice module
1515
// // I sure hope this shows up when I hover over it
1616
// ```
1717
// ->
1818
// ```
19-
// //! Wow what a nice function
19+
// //! Wow what a nice module
2020
// //! I sure hope this shows up when I hover over it
2121
// ```
2222
pub(crate) fn convert_comment_from_or_to_doc(
@@ -43,7 +43,7 @@ fn doc_to_comment(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
4343

4444
acc.add(
4545
AssistId("doc_to_comment", AssistKind::RefactorRewrite),
46-
"Replace a comment with doc comment",
46+
"Replace comment with doc comment",
4747
target,
4848
|edit| {
4949
// 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<()> {
5252
ast::CommentShape::Line => {
5353
let indentation = IndentLevel::from_token(comment.syntax());
5454
let line_start = comment.prefix();
55+
let prefix = format!("{indentation}//");
5556
relevant_line_comments(&comment)
5657
.iter()
5758
.map(|comment| comment.text())
5859
.flat_map(|text| text.lines())
59-
.map(|line| indentation.to_string() + &line.replacen(line_start, "//", 1))
60+
.map(|line| line.replacen(line_start, &prefix, 1))
6061
.join("\n")
6162
}
6263
ast::CommentShape::Block => {
@@ -89,23 +90,23 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
8990

9091
acc.add(
9192
AssistId("comment_to_doc", AssistKind::RefactorRewrite),
92-
"Replace a doc comment with comment",
93+
"Replace doc comment with comment",
9394
target,
9495
|edit| {
9596
// We need to either replace the first occurrence of /* with /***, or we need to replace
9697
// the occurrences // at the start of each line with ///
9798
let output = match comment.kind().shape {
9899
ast::CommentShape::Line => {
100+
let indentation = IndentLevel::from_token(comment.syntax());
99101
let line_start = match style {
100-
CommentPlacement::Inner => "//!",
101-
CommentPlacement::Outer => "///",
102+
CommentPlacement::Inner => format!("{indentation}//!"),
103+
CommentPlacement::Outer => format!("{indentation}///"),
102104
};
103-
let indentation = IndentLevel::from_token(comment.syntax());
104105
relevant_line_comments(&comment)
105106
.iter()
106107
.map(|comment| comment.text())
107108
.flat_map(|text| text.lines())
108-
.map(|line| indentation.to_string() + &line.replacen("//", line_start, 1))
109+
.map(|line| line.replacen("//", &line_start, 1))
109110
.join("\n")
110111
}
111112
ast::CommentShape::Block => {
@@ -139,29 +140,45 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
139140
/// Not all comments are valid candidates for conversion into doc comments. For example, the
140141
/// comments in the code:
141142
/// ```rust
142-
/// // foos the bar
143-
/// fn foo_bar(foo: Foo) -> Bar {
144-
/// // Bar the foo
145-
/// foo.into_bar()
146-
/// }
143+
/// // Brilliant module right here
147144
///
148-
/// trait A {
149-
/// // The A trait
145+
/// // Really good right
146+
/// fn good_function(foo: Foo) -> Bar {
147+
/// foo.into_bar()
150148
/// }
149+
///
150+
/// // So nice
151+
/// mod nice_module {}
151152
/// ```
152153
/// can be converted to doc comments. However, the comments in this example:
153154
/// ```rust
154155
/// fn foo_bar(foo: Foo /* not bar yet */) -> Bar {
155-
/// foo.into_bar()
156-
/// // Nicely done
156+
/// foo.into_bar()
157+
/// // Nicely done
157158
/// }
158159
/// // end of function
159160
///
160161
/// struct S {
161162
/// // The S struct
162163
/// }
163164
/// ```
164-
/// are not allowed to become doc comments.
165+
/// are not allowed to become doc comments. Moreover, some comments _are_ allowed, but aren't common
166+
/// style in Rust. For example, the following comments are allowed to be doc comments, but it is not
167+
/// common style for them to be:
168+
/// ```rust
169+
/// fn foo_bar(foo: Foo) -> Bar {
170+
/// // this could be an inner comment with //!
171+
/// foo.into_bar()
172+
/// }
173+
///
174+
/// trait T {
175+
/// // The T struct could also be documented from within
176+
/// }
177+
///
178+
/// mod mymod {
179+
/// // Modules only normally get inner documentation when they are defined as a separate file.
180+
/// }
181+
/// ```
165182
fn can_be_doc_comment(comment: &ast::Comment) -> Option<CommentPlacement> {
166183
use syntax::SyntaxKind::*;
167184

@@ -175,38 +192,12 @@ fn can_be_doc_comment(comment: &ast::Comment) -> Option<CommentPlacement> {
175192
None => return Some(CommentPlacement::Inner),
176193
}
177194

178-
// check if comment is followed by: `struct`, `trait`, `mod`, `fn`, `type`, `extern crate`, `use`, `const`
195+
// check if comment is followed by: `struct`, `trait`, `mod`, `fn`, `type`, `extern crate`,
196+
// `use` or `const`.
179197
let parent = comment.syntax().parent();
180198
let parent_kind = parent.as_ref().map(|parent| parent.kind());
181-
if matches!(
182-
parent_kind,
183-
Some(STRUCT | TRAIT | MODULE | FN | TYPE_KW | EXTERN_CRATE | USE | CONST)
184-
) {
185-
return Some(CommentPlacement::Outer);
186-
}
187-
188-
// check if comment is preceded by: `fn f() {`, `trait T {`, `mod M {`:
189-
let third_parent_kind = comment
190-
.syntax()
191-
.parent()
192-
.and_then(|p| p.parent())
193-
.and_then(|p| p.parent())
194-
.map(|parent| parent.kind());
195-
let is_first_item_in_parent = comment
196-
.syntax()
197-
.siblings_with_tokens(Direction::Prev)
198-
.filter_map(|not| not.into_node())
199-
.next()
200-
.is_none();
201-
202-
if matches!(parent_kind, Some(STMT_LIST))
203-
&& is_first_item_in_parent
204-
&& matches!(third_parent_kind, Some(FN | TRAIT | MODULE))
205-
{
206-
return Some(CommentPlacement::Inner);
207-
}
208-
209-
None
199+
matches!(parent_kind, Some(STRUCT | TRAIT | MODULE | FN | TYPE_KW | EXTERN_CRATE | USE | CONST))
200+
.then_some(CommentPlacement::Outer)
210201
}
211202

212203
/// The line -> block assist can be invoked from anywhere within a sequence of line comments.
@@ -467,39 +458,26 @@ mod tests {
467458

468459
#[test]
469460
fn single_inner_line_comment_to_doc() {
470-
check_assist(
461+
check_assist_not_applicable(
471462
convert_comment_from_or_to_doc,
472463
r#"
473-
fn main() {
464+
mod mymod {
474465
// unseen$0 docs
475466
foo();
476467
}
477468
"#,
478-
r#"
479-
fn main() {
480-
//! unseen docs
481-
foo();
482-
}
483-
"#,
484469
);
485470
}
486471

487472
#[test]
488473
fn multi_inner_line_comment_to_doc() {
489-
check_assist(
474+
check_assist_not_applicable(
490475
convert_comment_from_or_to_doc,
491476
r#"
492-
fn main() {
477+
mod mymod {
493478
// unseen$0 docs
494479
// make me seen!
495-
foo();
496-
}
497-
"#,
498-
r#"
499-
fn main() {
500-
//! unseen docs
501-
//! make me seen!
502-
foo();
480+
type Int = i32;
503481
}
504482
"#,
505483
);
@@ -510,13 +488,13 @@ mod tests {
510488
check_assist(
511489
convert_comment_from_or_to_doc,
512490
r#"
513-
fn main() {
491+
mod mymod {
514492
//! visible$0 docs
515493
foo();
516494
}
517495
"#,
518496
r#"
519-
fn main() {
497+
mod mymod {
520498
// visible docs
521499
foo();
522500
}
@@ -529,58 +507,33 @@ mod tests {
529507
check_assist(
530508
convert_comment_from_or_to_doc,
531509
r#"
532-
fn main() {
510+
mod mymod {
533511
//! visible$0 docs
534512
//! Hide me!
535513
foo();
536514
}
537515
"#,
538516
r#"
539-
fn main() {
517+
mod mymod {
540518
// visible docs
541519
// Hide me!
542520
foo();
543521
}
544522
"#,
545523
);
546-
}
547-
548-
#[test]
549-
fn single_inner_line_block_comment_to_doc() {
550-
check_assist(
551-
convert_comment_from_or_to_doc,
552-
r#"
553-
fn main() {
554-
/* unseen$0 docs */
555-
foo();
556-
}
557-
"#,
558-
r#"
559-
fn main() {
560-
/*! unseen docs */
561-
foo();
562-
}
563-
"#,
564-
);
565-
}
566-
567-
#[test]
568-
fn multi_inner_line_block_comment_to_doc() {
569524
check_assist(
570525
convert_comment_from_or_to_doc,
571526
r#"
572-
fn main() {
573-
/* unseen$0 docs
574-
* make me seen!
575-
*/
527+
mod mymod {
528+
/// visible$0 docs
529+
/// Hide me!
576530
foo();
577531
}
578532
"#,
579533
r#"
580-
fn main() {
581-
/*! unseen docs
582-
* make me seen!
583-
*/
534+
mod mymod {
535+
// visible docs
536+
// Hide me!
584537
foo();
585538
}
586539
"#,
@@ -592,15 +545,15 @@ mod tests {
592545
check_assist(
593546
convert_comment_from_or_to_doc,
594547
r#"
595-
fn main() {
548+
mod mymod {
596549
/*! visible$0 docs */
597-
foo();
550+
type Int = i32;
598551
}
599552
"#,
600553
r#"
601-
fn main() {
554+
mod mymod {
602555
/* visible docs */
603-
foo();
556+
type Int = i32;
604557
}
605558
"#,
606559
);
@@ -611,21 +564,21 @@ mod tests {
611564
check_assist(
612565
convert_comment_from_or_to_doc,
613566
r#"
614-
fn main() {
567+
mod mymod {
615568
/*! visible$0 docs
616569
* Hide me!
617570
*/
618-
foo();
571+
type Int = i32;
619572
}
620573
"#,
621574
r#"
622-
fn main() {
575+
mod mymod {
623576
/* visible docs
624577
* Hide me!
625578
*/
626-
foo();
579+
type Int = i32;
627580
}
628-
"#,
581+
"#,
629582
);
630583
}
631584

@@ -642,4 +595,16 @@ mod tests {
642595
"#,
643596
);
644597
}
598+
599+
#[test]
600+
fn no_inner_comments() {
601+
check_assist_not_applicable(
602+
convert_comment_from_or_to_doc,
603+
r#"
604+
mod mymod {
605+
// aaa$0aa
606+
}
607+
"#,
608+
);
609+
}
645610
}

src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,11 @@ fn doctest_comment_to_doc() {
350350
check_doc_test(
351351
"comment_to_doc",
352352
r#####"
353-
// Wow what $0a nice function
353+
// Wow what $0a nice module
354354
// I sure hope this shows up when I hover over it
355355
"#####,
356356
r#####"
357-
//! Wow what a nice function
357+
//! Wow what a nice module
358358
//! I sure hope this shows up when I hover over it
359359
"#####,
360360
)

0 commit comments

Comments
 (0)