1
- pub use CommentStyle :: * ;
2
-
3
- use crate :: ast;
1
+ use crate :: ast:: AttrStyle ;
4
2
use rustc_span:: source_map:: SourceMap ;
5
3
use rustc_span:: { BytePos , CharPos , FileName , Pos , Symbol } ;
6
4
7
- use log:: debug;
8
-
9
5
#[ cfg( test) ]
10
6
mod tests;
11
7
@@ -28,43 +24,48 @@ pub struct Comment {
28
24
pub pos : BytePos ,
29
25
}
30
26
31
- pub fn is_line_doc_comment ( s : & str ) -> bool {
32
- let res = ( s. starts_with ( "///" ) && * s. as_bytes ( ) . get ( 3 ) . unwrap_or ( & b' ' ) != b'/' )
33
- || s. starts_with ( "//!" ) ;
34
- debug ! ( "is {:?} a doc comment? {}" , s, res) ;
35
- res
36
- }
37
-
38
- pub fn is_block_doc_comment ( s : & str ) -> bool {
39
- // Prevent `/**/` from being parsed as a doc comment
40
- let res = ( ( s. starts_with ( "/**" ) && * s. as_bytes ( ) . get ( 3 ) . unwrap_or ( & b' ' ) != b'*' )
41
- || s. starts_with ( "/*!" ) )
42
- && s. len ( ) >= 5 ;
43
- debug ! ( "is {:?} a doc comment? {}" , s, res) ;
44
- res
45
- }
46
-
47
- // FIXME(#64197): Try to privatize this again.
48
- pub fn is_doc_comment ( s : & str ) -> bool {
49
- ( s. starts_with ( "///" ) && is_line_doc_comment ( s) )
50
- || s. starts_with ( "//!" )
51
- || ( s. starts_with ( "/**" ) && is_block_doc_comment ( s) )
52
- || s. starts_with ( "/*!" )
27
+ /// For a full line comment string returns its doc comment style if it's a doc comment
28
+ /// and returns `None` if it's a regular comment.
29
+ pub fn line_doc_comment_style ( line_comment : & str ) -> Option < AttrStyle > {
30
+ let line_comment = line_comment. as_bytes ( ) ;
31
+ assert ! ( line_comment. starts_with( b"//" ) ) ;
32
+ match line_comment. get ( 2 ) {
33
+ // `//!` is an inner line doc comment.
34
+ Some ( b'!' ) => Some ( AttrStyle :: Inner ) ,
35
+ Some ( b'/' ) => match line_comment. get ( 3 ) {
36
+ // `////` (more than 3 slashes) is not considered a doc comment.
37
+ Some ( b'/' ) => None ,
38
+ // Otherwise `///` is an outer line doc comment.
39
+ _ => Some ( AttrStyle :: Outer ) ,
40
+ } ,
41
+ _ => None ,
42
+ }
53
43
}
54
44
55
- pub fn doc_comment_style ( comment : Symbol ) -> ast:: AttrStyle {
56
- let comment = & comment. as_str ( ) ;
57
- assert ! ( is_doc_comment( comment) ) ;
58
- if comment. starts_with ( "//!" ) || comment. starts_with ( "/*!" ) {
59
- ast:: AttrStyle :: Inner
60
- } else {
61
- ast:: AttrStyle :: Outer
45
+ /// For a full block comment string returns its doc comment style if it's a doc comment
46
+ /// and returns `None` if it's a regular comment.
47
+ pub fn block_doc_comment_style ( block_comment : & str , terminated : bool ) -> Option < AttrStyle > {
48
+ let block_comment = block_comment. as_bytes ( ) ;
49
+ assert ! ( block_comment. starts_with( b"/*" ) ) ;
50
+ assert ! ( !terminated || block_comment. ends_with( b"*/" ) ) ;
51
+ match block_comment. get ( 2 ) {
52
+ // `/*!` is an inner block doc comment.
53
+ Some ( b'!' ) => Some ( AttrStyle :: Inner ) ,
54
+ Some ( b'*' ) => match block_comment. get ( 3 ) {
55
+ // `/***` (more than 2 stars) is not considered a doc comment.
56
+ Some ( b'*' ) => None ,
57
+ // `/**/` is not considered a doc comment.
58
+ Some ( b'/' ) if block_comment. len ( ) == 4 => None ,
59
+ // Otherwise `/**` is an outer block doc comment.
60
+ _ => Some ( AttrStyle :: Outer ) ,
61
+ } ,
62
+ _ => None ,
62
63
}
63
64
}
64
65
65
- pub fn strip_doc_comment_decoration ( comment : Symbol ) -> String {
66
- let comment = & comment . as_str ( ) ;
67
-
66
+ /// Makes a doc string more presentable to users.
67
+ /// Used by rustdoc and perhaps other tools, but not by rustc.
68
+ pub fn beautify_doc_string ( data : Symbol ) -> String {
68
69
/// remove whitespace-only lines from the start/end of lines
69
70
fn vertical_trim ( lines : Vec < String > ) -> Vec < String > {
70
71
let mut i = 0 ;
@@ -126,26 +127,15 @@ pub fn strip_doc_comment_decoration(comment: Symbol) -> String {
126
127
}
127
128
}
128
129
129
- // one-line comments lose their prefix
130
- const ONELINERS : & [ & str ] = & [ "///!" , "///" , "//!" , "//" ] ;
131
-
132
- for prefix in ONELINERS {
133
- if comment. starts_with ( * prefix) {
134
- return ( & comment[ prefix. len ( ) ..] ) . to_string ( ) ;
135
- }
136
- }
137
-
138
- if comment. starts_with ( "/*" ) {
139
- let lines =
140
- comment[ 3 ..comment. len ( ) - 2 ] . lines ( ) . map ( |s| s. to_string ( ) ) . collect :: < Vec < String > > ( ) ;
141
-
130
+ let data = data. as_str ( ) ;
131
+ if data. contains ( '\n' ) {
132
+ let lines = data. lines ( ) . map ( |s| s. to_string ( ) ) . collect :: < Vec < String > > ( ) ;
142
133
let lines = vertical_trim ( lines) ;
143
134
let lines = horizontal_trim ( lines) ;
144
-
145
- return lines. join ( "\n " ) ;
135
+ lines. join ( "\n " )
136
+ } else {
137
+ data. to_string ( )
146
138
}
147
-
148
- panic ! ( "not a doc-comment: {}" , comment) ;
149
139
}
150
140
151
141
/// Returns `None` if the first `col` chars of `s` contain a non-whitespace char.
@@ -203,7 +193,7 @@ pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comme
203
193
204
194
if let Some ( shebang_len) = rustc_lexer:: strip_shebang ( text) {
205
195
comments. push ( Comment {
206
- style : Isolated ,
196
+ style : CommentStyle :: Isolated ,
207
197
lines : vec ! [ text[ ..shebang_len] . to_string( ) ] ,
208
198
pos : start_bpos,
209
199
} ) ;
@@ -219,23 +209,23 @@ pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comme
219
209
while let Some ( next_newline) = & token_text[ idx + 1 ..] . find ( '\n' ) {
220
210
idx = idx + 1 + next_newline;
221
211
comments. push ( Comment {
222
- style : BlankLine ,
212
+ style : CommentStyle :: BlankLine ,
223
213
lines : vec ! [ ] ,
224
214
pos : start_bpos + BytePos ( ( pos + idx) as u32 ) ,
225
215
} ) ;
226
216
}
227
217
}
228
218
}
229
- rustc_lexer:: TokenKind :: BlockComment { terminated : _ } => {
230
- if ! is_block_doc_comment ( token_text) {
219
+ rustc_lexer:: TokenKind :: BlockComment { terminated } => {
220
+ if block_doc_comment_style ( token_text, terminated ) . is_none ( ) {
231
221
let code_to_the_right = match text[ pos + token. len ..] . chars ( ) . next ( ) {
232
222
Some ( '\r' | '\n' ) => false ,
233
223
_ => true ,
234
224
} ;
235
225
let style = match ( code_to_the_left, code_to_the_right) {
236
- ( _, true ) => Mixed ,
237
- ( false , false ) => Isolated ,
238
- ( true , false ) => Trailing ,
226
+ ( _, true ) => CommentStyle :: Mixed ,
227
+ ( false , false ) => CommentStyle :: Isolated ,
228
+ ( true , false ) => CommentStyle :: Trailing ,
239
229
} ;
240
230
241
231
// Count the number of chars since the start of the line by rescanning.
@@ -249,9 +239,13 @@ pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comme
249
239
}
250
240
}
251
241
rustc_lexer:: TokenKind :: LineComment => {
252
- if ! is_doc_comment ( token_text) {
242
+ if line_doc_comment_style ( token_text) . is_none ( ) {
253
243
comments. push ( Comment {
254
- style : if code_to_the_left { Trailing } else { Isolated } ,
244
+ style : if code_to_the_left {
245
+ CommentStyle :: Trailing
246
+ } else {
247
+ CommentStyle :: Isolated
248
+ } ,
255
249
lines : vec ! [ token_text. to_string( ) ] ,
256
250
pos : start_bpos + BytePos ( pos as u32 ) ,
257
251
} )
0 commit comments