@@ -6,6 +6,8 @@ enum TokenType {
6
6
RAW_STRING_LITERAL ,
7
7
FLOAT_LITERAL ,
8
8
BLOCK_COMMENT ,
9
+ LINE_COMMENT ,
10
+ DOC_COMMENT ,
9
11
};
10
12
11
13
void * tree_sitter_rust_external_scanner_create () { return NULL ; }
@@ -143,7 +145,87 @@ bool tree_sitter_rust_external_scanner_scan(void *payload, TSLexer *lexer,
143
145
144
146
if (lexer -> lookahead == '/' ) {
145
147
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
+
165
+ while (true) {
166
+ while (true) {
167
+ switch (lexer -> lookahead ) {
168
+ case '\n' : {
169
+ goto finished_doc_comment_line ;
170
+ }
171
+ case 0 : {
172
+ goto doc_comment_exit ;
173
+ }
174
+ default : {
175
+ advance (lexer );
176
+ }
177
+ }
178
+ }
179
+
180
+ finished_doc_comment_line :
181
+
182
+ lexer -> mark_end (lexer );
183
+ advance (lexer );
184
+ if (lexer -> lookahead == '/' ) {
185
+ advance (lexer );
186
+ if (lexer -> lookahead == '/' ) {
187
+ advance (lexer );
188
+ if (started_with_slash ) {
189
+ if (lexer -> lookahead == '/' ) {
190
+ advance (lexer );
191
+ // If a fourth slash is found, the line turns back to a normal comment
192
+ if (lexer -> lookahead == '/' ) {
193
+ break ;
194
+ }
195
+ } else {
196
+ break ;
197
+ }
198
+ } else if (lexer -> lookahead != '!' ) {
199
+ break ;
200
+ }
201
+ } else {
202
+ break ;
203
+ }
204
+ } else {
205
+ break ;
206
+ }
207
+ }
208
+ }
209
+
210
+ break ;
211
+ }
212
+ }
213
+
214
+ doc_comment_exit :
215
+
216
+ // Might have already processed a doc comment in the loop above
217
+ if (lexer -> result_symbol != DOC_COMMENT ) {
218
+ lexer -> result_symbol = LINE_COMMENT ;
219
+ while (lexer -> lookahead != '\n' && lexer -> lookahead != 0 ) {
220
+ advance (lexer );
221
+ }
222
+ }
223
+
224
+ return true;
225
+ }
226
+
146
227
if (lexer -> lookahead != '*' ) return false;
228
+
147
229
advance (lexer );
148
230
149
231
bool after_star = false;
0 commit comments