@@ -22,8 +22,8 @@ pub enum Token<'a> {
22
22
Arrow ,
23
23
Unknown ( char ) ,
24
24
Trivia ,
25
- Comment ( & ' a str ) ,
26
- CommentModule ( & ' a str ) ,
25
+ CommentDoc ( & ' a str ) ,
26
+ CommentDocModule ( & ' a str ) ,
27
27
End ,
28
28
}
29
29
@@ -83,46 +83,64 @@ fn consume_token(input: &str, generic: bool, save_comments: bool) -> (Token<'_>,
83
83
let og_chars = chars. as_str ( ) ;
84
84
match chars. next ( ) {
85
85
Some ( '/' ) => {
86
- if let Some ( end_position) = input
87
- . char_indices ( )
88
- . find ( |char_indices| is_comment_end ( char_indices. 1 ) )
89
- {
90
- if !save_comments {
91
- return ( Token :: Trivia , & input[ end_position. 0 ..] ) ;
86
+ let end_position = {
87
+ if let Some ( end_position) = input
88
+ . char_indices ( )
89
+ . find ( |char_indices| is_comment_end ( char_indices. 1 ) )
90
+ {
91
+ end_position. 0
92
+ } else {
93
+ input. len ( )
92
94
}
93
- let end_position = end_position. 0 ;
94
- return (
95
- if chars. next ( ) == Some ( '!' ) {
96
- Token :: CommentModule ( & input[ ..end_position] )
97
- } else {
98
- Token :: Comment ( & input[ ..end_position] )
99
- } ,
100
- & input[ end_position..] ,
101
- ) ;
102
- }
95
+ } ;
103
96
if !save_comments {
104
- return ( Token :: Trivia , "" ) ;
97
+ return ( Token :: Trivia , & input [ end_position.. ] ) ;
105
98
}
106
- ( Token :: Comment ( input) , "" )
99
+ let next_char = chars. next ( ) ;
100
+ (
101
+ match next_char {
102
+ Some ( '/' ) => Token :: CommentDoc ( & input[ ..end_position] ) ,
103
+ Some ( '!' ) => Token :: CommentDocModule ( & input[ ..end_position] ) ,
104
+ _ => Token :: Trivia ,
105
+ } ,
106
+ & input[ end_position..] ,
107
+ )
107
108
}
108
109
Some ( '*' ) => {
109
110
let mut depth = 1 ;
110
111
let mut prev = None ;
111
112
let mut char_indices = input. char_indices ( ) ;
113
+
112
114
// Skip '/' and '*'
113
115
char_indices. next ( ) ;
114
116
char_indices. next ( ) ;
117
+
118
+ let mut constructing_token = if !save_comments {
119
+ Token :: Trivia
120
+ } else {
121
+ let mut peeker = char_indices. clone ( ) . peekable ( ) ;
122
+ let peeked_next_char = peeker. peek ( ) ;
123
+ let peeked_next_char =
124
+ peeked_next_char. map ( |peeked_next_char| peeked_next_char. 1 ) ;
125
+ match peeked_next_char {
126
+ Some ( '*' ) => Token :: CommentDoc ( "" ) ,
127
+ Some ( '!' ) => Token :: CommentDocModule ( "" ) ,
128
+ _ => Token :: Trivia ,
129
+ }
130
+ } ;
115
131
for ( index, c) in char_indices {
116
132
match ( prev, c) {
117
133
( Some ( '*' ) , '/' ) => {
118
134
prev = None ;
119
135
depth -= 1 ;
120
136
if depth == 0 {
121
- if !save_comments {
122
- return ( Token :: Trivia , & input[ ( index + 1 ) ..] ) ;
137
+ if let Token :: CommentDoc ( ref mut doc)
138
+ | Token :: CommentDocModule ( ref mut doc) = constructing_token
139
+ {
140
+ * doc = & input[ ..=index] ;
123
141
}
124
- let doc = & input [ ..=index ] ;
125
- return ( Token :: Comment ( doc ) , & input[ ( index + 1 ) ..] ) ;
142
+
143
+ return ( constructing_token , & input[ ( index + 1 ) ..] ) ;
126
144
}
127
145
}
128
146
( Some ( '/' ) , '*' ) => {
@@ -288,7 +306,7 @@ impl<'a> Lexer<'a> {
288
306
loop {
289
307
// Eat all trivia because `next` doesn't eat trailing trivia.
290
308
let ( token, rest) = consume_token ( self . input , false , self . save_comments ) ;
291
- if let Token :: Trivia | Token :: Comment ( _) | Token :: CommentModule ( _) = token {
309
+ if let Token :: Trivia | Token :: CommentDoc ( _) | Token :: CommentDocModule ( _) = token {
292
310
self . input = rest;
293
311
} else {
294
312
return self . current_byte_offset ( ) ;
@@ -311,13 +329,13 @@ impl<'a> Lexer<'a> {
311
329
let start = self . current_byte_offset ( ) ;
312
330
// Eat all trivia because `next` doesn't eat trailing trivia.
313
331
let ( token, rest) = consume_token ( self . input , false , self . save_comments ) ;
314
- if let Token :: Comment ( _) = token {
332
+ if let Token :: CommentDoc ( _) = token {
315
333
self . input = rest;
316
334
let next = self . current_byte_offset ( ) ;
317
335
comments. push ( Span :: new ( start as u32 , next as u32 ) ) ;
318
336
} else if let Token :: Trivia = token {
319
337
self . input = rest;
320
- } else if let Token :: CommentModule ( _) = token {
338
+ } else if let Token :: CommentDocModule ( _) = token {
321
339
self . input = rest;
322
340
} else {
323
341
return self . current_byte_offset ( ) ;
@@ -359,7 +377,7 @@ impl<'a> Lexer<'a> {
359
377
|token| {
360
378
!matches ! (
361
379
token,
362
- Token :: Trivia | Token :: Comment ( _) | Token :: CommentModule ( _)
380
+ Token :: Trivia | Token :: CommentDoc ( _) | Token :: CommentDocModule ( _)
363
381
)
364
382
} ,
365
383
generic,
@@ -564,7 +582,7 @@ fn sub_test_with_and_without_comments(source: &str, expected_tokens: &[Token]) {
564
582
source,
565
583
expected_tokens
566
584
. iter ( )
567
- . filter ( |v| !matches ! ( v, Token :: Comment ( _) | Token :: CommentModule ( _) ) )
585
+ . filter ( |v| !matches ! ( * * v, Token :: CommentDoc ( _) | Token :: CommentDocModule ( _) ) )
568
586
. cloned ( )
569
587
. collect :: < Vec < _ > > ( )
570
588
. as_slice ( ) ,
@@ -801,9 +819,8 @@ fn test_tokens() {
801
819
"*/*/***/*//=/*****//" ,
802
820
& [
803
821
Token :: Operation ( '*' ) ,
804
- Token :: Comment ( "/*/***/*/" ) ,
805
822
Token :: AssignmentOperation ( '/' ) ,
806
- Token :: Comment ( "/*****/" ) ,
823
+ Token :: CommentDoc ( "/*****/" ) ,
807
824
Token :: Operation ( '/' ) ,
808
825
] ,
809
826
) ;
@@ -871,47 +888,70 @@ fn test_variable_decl() {
871
888
}
872
889
873
890
#[ test]
874
- fn test_comments ( ) {
875
- sub_test_with_and_without_comments ( "// Single comment" , & [ Token :: Comment ( "// Single comment" ) ] ) ;
891
+ fn test_comments_trivia ( ) {
892
+ sub_test_with_and_without_comments ( "// Single comment" , & [ ] ) ;
893
+
876
894
sub_test_with_and_without_comments (
877
895
"/* multi
878
896
line
879
897
comment */" ,
880
- & [ Token :: Comment (
881
- "/* multi
898
+ & [ ] ,
899
+ ) ;
900
+ sub_test_with_and_without_comments (
901
+ "/* multi
902
+ line
903
+ comment */
904
+ // and another" ,
905
+ & [ ] ,
906
+ ) ;
907
+ }
908
+
909
+ #[ test]
910
+ fn test_comments ( ) {
911
+ sub_test_with_and_without_comments (
912
+ "/// Single comment" ,
913
+ & [ Token :: CommentDoc ( "/// Single comment" ) ] ,
914
+ ) ;
915
+
916
+ sub_test_with_and_without_comments (
917
+ "/** multi
918
+ line
919
+ comment */" ,
920
+ & [ Token :: CommentDoc (
921
+ "/** multi
882
922
line
883
923
comment */" ,
884
924
) ] ,
885
925
) ;
886
926
sub_test_with_and_without_comments (
887
- "/* multi
927
+ "/** multi
888
928
line
889
929
comment */
890
- // and another" ,
930
+ /// and another" ,
891
931
& [
892
- Token :: Comment (
893
- "/* multi
932
+ Token :: CommentDoc (
933
+ "/** multi
894
934
line
895
935
comment */" ,
896
936
) ,
897
- Token :: Comment ( " // and another") ,
937
+ Token :: CommentDoc ( "/ // and another") ,
898
938
] ,
899
939
) ;
900
940
}
901
941
902
942
#[ test]
903
943
fn test_comment_nested ( ) {
904
944
sub_test_with_and_without_comments (
905
- "/*
906
- a comment with nested one /*
945
+ "/**
946
+ a comment with nested one /**
907
947
nested comment
908
948
*/
909
949
*/
910
950
const a : i32 = 2;" ,
911
951
& [
912
- Token :: Comment (
913
- "/*
914
- a comment with nested one /*
952
+ Token :: CommentDoc (
953
+ "/**
954
+ a comment with nested one /**
915
955
nested comment
916
956
*/
917
957
*/" ,
@@ -930,14 +970,14 @@ fn test_comment_nested() {
930
970
#[ test]
931
971
fn test_comment_long_character ( ) {
932
972
sub_test_with_and_without_comments (
933
- "// π/2
934
- // D(𝐡) = ───────────────────────────────────────────────────
935
- // παₜα_b((𝐡 ⋅ 𝐭)² / αₜ²) + (𝐡 ⋅ 𝐛)² / α_b² +`
973
+ "/// π/2
974
+ /// D(𝐡) = ───────────────────────────────────────────────────
975
+ /// παₜα_b((𝐡 ⋅ 𝐭)² / αₜ²) + (𝐡 ⋅ 𝐛)² / α_b² +`
936
976
const a : i32 = 2;" ,
937
977
& [
938
- Token :: Comment ( " // π/2") ,
939
- Token :: Comment ( " // D(𝐡) = ───────────────────────────────────────────────────") ,
940
- Token :: Comment ( " // παₜα_b((𝐡 ⋅ 𝐭)² / αₜ²) + (𝐡 ⋅ 𝐛)² / α_b² +`") ,
978
+ Token :: CommentDoc ( "/ // π/2") ,
979
+ Token :: CommentDoc ( "/ // D(𝐡) = ───────────────────────────────────────────────────") ,
980
+ Token :: CommentDoc ( "/ // παₜα_b((𝐡 ⋅ 𝐭)² / αₜ²) + (𝐡 ⋅ 𝐛)² / α_b² +`") ,
941
981
Token :: Word ( "const" ) ,
942
982
Token :: Word ( "a" ) ,
943
983
Token :: Separator ( ':' ) ,
@@ -950,22 +990,27 @@ fn test_comment_long_character() {
950
990
}
951
991
952
992
#[ test]
953
- fn test_module_comments ( ) {
993
+ fn test_comments_module ( ) {
954
994
sub_test_with_and_without_comments (
955
995
"//! Comment Module
956
996
//! Another one.
957
- // Trying to break module comment
997
+ /*! Different module comment */
998
+ /// Trying to break module comment
999
+ // Trying to break module comment again
958
1000
//! After a regular comment is ok.
1001
+ /*! Different module comment again */
959
1002
960
1003
//! After a break is supported.
961
1004
const
962
1005
//! After anything else is not." ,
963
1006
& [
964
- Token :: CommentModule ( "//! Comment Module" ) ,
965
- Token :: CommentModule ( "//! Another one." ) ,
966
- Token :: Comment ( "// Trying to break module comment" ) ,
967
- Token :: CommentModule ( "//! After a regular comment is ok." ) ,
968
- Token :: CommentModule ( "//! After a break is supported." ) ,
1007
+ Token :: CommentDocModule ( "//! Comment Module" ) ,
1008
+ Token :: CommentDocModule ( "//! Another one." ) ,
1009
+ Token :: CommentDocModule ( "/*! Different module comment */" ) ,
1010
+ Token :: CommentDoc ( "/// Trying to break module comment" ) ,
1011
+ Token :: CommentDocModule ( "//! After a regular comment is ok." ) ,
1012
+ Token :: CommentDocModule ( "/*! Different module comment again */" ) ,
1013
+ Token :: CommentDocModule ( "//! After a break is supported." ) ,
969
1014
Token :: Word ( "const" ) ,
970
1015
] ,
971
1016
) ;
0 commit comments