1- pub use CommentStyle :: * ;
2-
3- use crate :: ast;
1+ use crate :: ast:: AttrStyle ;
42use rustc_span:: source_map:: SourceMap ;
53use rustc_span:: { BytePos , CharPos , FileName , Pos , Symbol } ;
64
7- use log:: debug;
8-
95#[ cfg( test) ]
106mod tests;
117
@@ -28,43 +24,48 @@ pub struct Comment {
2824 pub pos : BytePos ,
2925}
3026
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+ }
5343}
5444
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 ,
6263 }
6364}
6465
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 {
6869 /// remove whitespace-only lines from the start/end of lines
6970 fn vertical_trim ( lines : Vec < String > ) -> Vec < String > {
7071 let mut i = 0 ;
@@ -126,26 +127,15 @@ pub fn strip_doc_comment_decoration(comment: Symbol) -> String {
126127 }
127128 }
128129
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 > > ( ) ;
142133 let lines = vertical_trim ( lines) ;
143134 let lines = horizontal_trim ( lines) ;
144-
145- return lines. join ( "\n " ) ;
135+ lines. join ( "\n " )
136+ } else {
137+ data. to_string ( )
146138 }
147-
148- panic ! ( "not a doc-comment: {}" , comment) ;
149139}
150140
151141/// 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
203193
204194 if let Some ( shebang_len) = rustc_lexer:: strip_shebang ( text) {
205195 comments. push ( Comment {
206- style : Isolated ,
196+ style : CommentStyle :: Isolated ,
207197 lines : vec ! [ text[ ..shebang_len] . to_string( ) ] ,
208198 pos : start_bpos,
209199 } ) ;
@@ -219,23 +209,23 @@ pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comme
219209 while let Some ( next_newline) = & token_text[ idx + 1 ..] . find ( '\n' ) {
220210 idx = idx + 1 + next_newline;
221211 comments. push ( Comment {
222- style : BlankLine ,
212+ style : CommentStyle :: BlankLine ,
223213 lines : vec ! [ ] ,
224214 pos : start_bpos + BytePos ( ( pos + idx) as u32 ) ,
225215 } ) ;
226216 }
227217 }
228218 }
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 ( ) {
231221 let code_to_the_right = match text[ pos + token. len ..] . chars ( ) . next ( ) {
232222 Some ( '\r' | '\n' ) => false ,
233223 _ => true ,
234224 } ;
235225 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 ,
239229 } ;
240230
241231 // 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
249239 }
250240 }
251241 rustc_lexer:: TokenKind :: LineComment => {
252- if ! is_doc_comment ( token_text) {
242+ if line_doc_comment_style ( token_text) . is_none ( ) {
253243 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+ } ,
255249 lines : vec ! [ token_text. to_string( ) ] ,
256250 pos : start_bpos + BytePos ( pos as u32 ) ,
257251 } )
0 commit comments