@@ -6,6 +6,8 @@ enum TokenType {
66 RAW_STRING_LITERAL ,
77 FLOAT_LITERAL ,
88 BLOCK_COMMENT ,
9+ LINE_COMMENT ,
10+ DOC_COMMENT ,
911};
1012
1113void * tree_sitter_rust_external_scanner_create () { return NULL ; }
@@ -143,7 +145,76 @@ bool tree_sitter_rust_external_scanner_scan(void *payload, TSLexer *lexer,
143145
144146 if (lexer -> lookahead == '/' ) {
145147 advance (lexer );
148+
149+ if ((valid_symbols [LINE_COMMENT ] || valid_symbols [DOC_COMMENT ]) && lexer -> lookahead == '/' ) {
150+ advance (lexer );
151+
152+ bool started_with_slash = lexer -> lookahead == '/' ;
153+ switch (lexer -> lookahead ) {
154+ case '!' :
155+ case '/' : {
156+ advance (lexer );
157+
158+ // If three consecutive slashes were seen and this is the fourth one,
159+ // the line turns back to a normal comment.
160+ // The above rule does not apply for "//!" which is also a doc
161+ // comment, hence why it is relevant to track started_with_slash.
162+ if (started_with_slash == false || lexer -> lookahead != '/' ) {
163+ lexer -> result_symbol = DOC_COMMENT ;
164+ while (true) {
165+ while (lexer -> lookahead != '\n' ) {
166+ advance (lexer );
167+ }
168+ if (lexer -> lookahead == 0 ) {
169+ break ;
170+ }
171+
172+ lexer -> mark_end (lexer );
173+ advance (lexer );
174+ if (lexer -> lookahead == '/' ) {
175+ advance (lexer );
176+ if (lexer -> lookahead == '/' ) {
177+ advance (lexer );
178+ if (started_with_slash ) {
179+ if (lexer -> lookahead == '/' ) {
180+ advance (lexer );
181+ // If a fourth slash is found, the line turns back to a normal comment
182+ if (lexer -> lookahead == '/' ) {
183+ break ;
184+ }
185+ } else {
186+ break ;
187+ }
188+ } else if (lexer -> lookahead != '!' ) {
189+ break ;
190+ }
191+ } else {
192+ break ;
193+ }
194+ } else {
195+ break ;
196+ }
197+ }
198+ }
199+ break ;
200+ }
201+ }
202+
203+
204+ // Might have broken from the loop above having already processed a doc
205+ // comment
206+ if (lexer -> result_symbol != DOC_COMMENT ) {
207+ lexer -> result_symbol = LINE_COMMENT ;
208+ while (lexer -> lookahead != '\n' && lexer -> lookahead != 0 ) {
209+ advance (lexer );
210+ }
211+ }
212+
213+ return true;
214+ }
215+
146216 if (lexer -> lookahead != '*' ) return false;
217+
147218 advance (lexer );
148219
149220 bool after_star = false;
0 commit comments