@@ -11,12 +11,12 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
11
11
// Converts comments to documentation.
12
12
//
13
13
// ```
14
- // // Wow what $0a nice function
14
+ // // Wow what $0a nice module
15
15
// // I sure hope this shows up when I hover over it
16
16
// ```
17
17
// ->
18
18
// ```
19
- // //! Wow what a nice function
19
+ // //! Wow what a nice module
20
20
// //! I sure hope this shows up when I hover over it
21
21
// ```
22
22
pub ( crate ) fn convert_comment_from_or_to_doc (
@@ -43,7 +43,7 @@ fn doc_to_comment(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
43
43
44
44
acc. add (
45
45
AssistId ( "doc_to_comment" , AssistKind :: RefactorRewrite ) ,
46
- "Replace a comment with doc comment" ,
46
+ "Replace comment with doc comment" ,
47
47
target,
48
48
|edit| {
49
49
// 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<()> {
52
52
ast:: CommentShape :: Line => {
53
53
let indentation = IndentLevel :: from_token ( comment. syntax ( ) ) ;
54
54
let line_start = comment. prefix ( ) ;
55
+ let prefix = format ! ( "{indentation}//" ) ;
55
56
relevant_line_comments ( & comment)
56
57
. iter ( )
57
58
. map ( |comment| comment. text ( ) )
58
59
. 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 ) )
60
61
. join ( "\n " )
61
62
}
62
63
ast:: CommentShape :: Block => {
@@ -89,23 +90,23 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
89
90
90
91
acc. add (
91
92
AssistId ( "comment_to_doc" , AssistKind :: RefactorRewrite ) ,
92
- "Replace a doc comment with comment" ,
93
+ "Replace doc comment with comment" ,
93
94
target,
94
95
|edit| {
95
96
// We need to either replace the first occurrence of /* with /***, or we need to replace
96
97
// the occurrences // at the start of each line with ///
97
98
let output = match comment. kind ( ) . shape {
98
99
ast:: CommentShape :: Line => {
100
+ let indentation = IndentLevel :: from_token ( comment. syntax ( ) ) ;
99
101
let line_start = match style {
100
- CommentPlacement :: Inner => " //!",
101
- CommentPlacement :: Outer => " ///",
102
+ CommentPlacement :: Inner => format ! ( "{indentation} //!") ,
103
+ CommentPlacement :: Outer => format ! ( "{indentation} ///") ,
102
104
} ;
103
- let indentation = IndentLevel :: from_token ( comment. syntax ( ) ) ;
104
105
relevant_line_comments ( & comment)
105
106
. iter ( )
106
107
. map ( |comment| comment. text ( ) )
107
108
. flat_map ( |text| text. lines ( ) )
108
- . map ( |line| indentation . to_string ( ) + & line. replacen ( "//" , line_start, 1 ) )
109
+ . map ( |line| line. replacen ( "//" , & line_start, 1 ) )
109
110
. join ( "\n " )
110
111
}
111
112
ast:: CommentShape :: Block => {
@@ -139,29 +140,45 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
139
140
/// Not all comments are valid candidates for conversion into doc comments. For example, the
140
141
/// comments in the code:
141
142
/// ```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
147
144
///
148
- /// trait A {
149
- /// // The A trait
145
+ /// // Really good right
146
+ /// fn good_function(foo: Foo) -> Bar {
147
+ /// foo.into_bar()
150
148
/// }
149
+ ///
150
+ /// // So nice
151
+ /// mod nice_module {}
151
152
/// ```
152
153
/// can be converted to doc comments. However, the comments in this example:
153
154
/// ```rust
154
155
/// fn foo_bar(foo: Foo /* not bar yet */) -> Bar {
155
- /// foo.into_bar()
156
- /// // Nicely done
156
+ /// foo.into_bar()
157
+ /// // Nicely done
157
158
/// }
158
159
/// // end of function
159
160
///
160
161
/// struct S {
161
162
/// // The S struct
162
163
/// }
163
164
/// ```
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
+ /// ```
165
182
fn can_be_doc_comment ( comment : & ast:: Comment ) -> Option < CommentPlacement > {
166
183
use syntax:: SyntaxKind :: * ;
167
184
@@ -175,38 +192,12 @@ fn can_be_doc_comment(comment: &ast::Comment) -> Option<CommentPlacement> {
175
192
None => return Some ( CommentPlacement :: Inner ) ,
176
193
}
177
194
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`.
179
197
let parent = comment. syntax ( ) . parent ( ) ;
180
198
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 )
210
201
}
211
202
212
203
/// The line -> block assist can be invoked from anywhere within a sequence of line comments.
@@ -467,39 +458,26 @@ mod tests {
467
458
468
459
#[ test]
469
460
fn single_inner_line_comment_to_doc ( ) {
470
- check_assist (
461
+ check_assist_not_applicable (
471
462
convert_comment_from_or_to_doc,
472
463
r#"
473
- fn main() {
464
+ mod mymod {
474
465
// unseen$0 docs
475
466
foo();
476
467
}
477
468
"# ,
478
- r#"
479
- fn main() {
480
- //! unseen docs
481
- foo();
482
- }
483
- "# ,
484
469
) ;
485
470
}
486
471
487
472
#[ test]
488
473
fn multi_inner_line_comment_to_doc ( ) {
489
- check_assist (
474
+ check_assist_not_applicable (
490
475
convert_comment_from_or_to_doc,
491
476
r#"
492
- fn main() {
477
+ mod mymod {
493
478
// unseen$0 docs
494
479
// 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;
503
481
}
504
482
"# ,
505
483
) ;
@@ -510,13 +488,13 @@ mod tests {
510
488
check_assist (
511
489
convert_comment_from_or_to_doc,
512
490
r#"
513
- fn main() {
491
+ mod mymod {
514
492
//! visible$0 docs
515
493
foo();
516
494
}
517
495
"# ,
518
496
r#"
519
- fn main() {
497
+ mod mymod {
520
498
// visible docs
521
499
foo();
522
500
}
@@ -529,58 +507,33 @@ mod tests {
529
507
check_assist (
530
508
convert_comment_from_or_to_doc,
531
509
r#"
532
- fn main() {
510
+ mod mymod {
533
511
//! visible$0 docs
534
512
//! Hide me!
535
513
foo();
536
514
}
537
515
"# ,
538
516
r#"
539
- fn main() {
517
+ mod mymod {
540
518
// visible docs
541
519
// Hide me!
542
520
foo();
543
521
}
544
522
"# ,
545
523
) ;
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 ( ) {
569
524
check_assist (
570
525
convert_comment_from_or_to_doc,
571
526
r#"
572
- fn main() {
573
- /* unseen$0 docs
574
- * make me seen!
575
- */
527
+ mod mymod {
528
+ /// visible$0 docs
529
+ /// Hide me!
576
530
foo();
577
531
}
578
532
"# ,
579
533
r#"
580
- fn main() {
581
- /*! unseen docs
582
- * make me seen!
583
- */
534
+ mod mymod {
535
+ // visible docs
536
+ // Hide me!
584
537
foo();
585
538
}
586
539
"# ,
@@ -592,15 +545,15 @@ mod tests {
592
545
check_assist (
593
546
convert_comment_from_or_to_doc,
594
547
r#"
595
- fn main() {
548
+ mod mymod {
596
549
/*! visible$0 docs */
597
- foo() ;
550
+ type Int = i32 ;
598
551
}
599
552
"# ,
600
553
r#"
601
- fn main() {
554
+ mod mymod {
602
555
/* visible docs */
603
- foo() ;
556
+ type Int = i32 ;
604
557
}
605
558
"# ,
606
559
) ;
@@ -611,21 +564,21 @@ mod tests {
611
564
check_assist (
612
565
convert_comment_from_or_to_doc,
613
566
r#"
614
- fn main() {
567
+ mod mymod {
615
568
/*! visible$0 docs
616
569
* Hide me!
617
570
*/
618
- foo() ;
571
+ type Int = i32 ;
619
572
}
620
573
"# ,
621
574
r#"
622
- fn main() {
575
+ mod mymod {
623
576
/* visible docs
624
577
* Hide me!
625
578
*/
626
- foo() ;
579
+ type Int = i32 ;
627
580
}
628
- "# ,
581
+ "# ,
629
582
) ;
630
583
}
631
584
@@ -642,4 +595,16 @@ mod tests {
642
595
"# ,
643
596
) ;
644
597
}
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
+ }
645
610
}
0 commit comments