@@ -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,100 @@ 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
+ lexer -> mark_end (lexer );
170
+ advance (lexer );
171
+ goto finished_doc_comment_line ;
172
+ }
173
+ case 0 : {
174
+ goto doc_comment_exit ;
175
+ }
176
+ default : {
177
+ advance (lexer );
178
+ }
179
+ }
180
+ }
181
+
182
+ finished_doc_comment_line :
183
+
184
+ // Go forward until a newline or non-whitespace character is found.
185
+ // That will be either the start of another node or the
186
+ // continuation of this comment.
187
+ while (lexer -> lookahead != '\n' && iswspace (lexer -> lookahead )) {
188
+ lexer -> advance (lexer , false);
189
+ };
190
+
191
+ if (lexer -> lookahead == '\n' ) {
192
+ // Even if there's another comment ahead, it'll be part of a
193
+ // separate node. Break here.
194
+ break ;
195
+ }
196
+
197
+ if (lexer -> lookahead == '/' ) {
198
+ advance (lexer );
199
+ if (lexer -> lookahead == '/' ) {
200
+ advance (lexer );
201
+ if (started_with_slash ) {
202
+ if (lexer -> lookahead == '/' ) {
203
+ advance (lexer );
204
+ // If a fourth slash is found, the line turns back to a normal comment
205
+ if (lexer -> lookahead == '/' ) {
206
+ break ;
207
+ }
208
+ } else {
209
+ break ;
210
+ }
211
+ } else if (lexer -> lookahead != '!' ) {
212
+ break ;
213
+ }
214
+ } else {
215
+ break ;
216
+ }
217
+ } else {
218
+ break ;
219
+ }
220
+ }
221
+ }
222
+
223
+ break ;
224
+ }
225
+ }
226
+
227
+ doc_comment_exit :
228
+
229
+ // Might have already processed a doc comment in the loop above
230
+ if (lexer -> result_symbol != DOC_COMMENT ) {
231
+ lexer -> result_symbol = LINE_COMMENT ;
232
+ while (lexer -> lookahead != '\n' && lexer -> lookahead != 0 ) {
233
+ advance (lexer );
234
+ }
235
+ }
236
+
237
+ return true;
238
+ }
239
+
146
240
if (lexer -> lookahead != '*' ) return false;
241
+
147
242
advance (lexer );
148
243
149
244
bool after_star = false;
0 commit comments