Skip to content

Commit d8015ac

Browse files
committed
designate doc comments
1 parent 5993f53 commit d8015ac

File tree

3 files changed

+104
-10
lines changed

3 files changed

+104
-10
lines changed

corpus/source_files.txt

+30
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,36 @@ Line comments
5555
(source_file
5656
(line_comment))
5757

58+
============================================
59+
Doc comments
60+
============================================
61+
62+
/// Doc
63+
/// Comment
64+
// / Now a line comment (note the space separating the third slash)
65+
66+
/// Doc
67+
/// Comment
68+
//// Four slashes makes the line a normal comment
69+
/// Doc comment got interrupted by the line above
70+
71+
//! Inner doc comment line 1
72+
//! Inner doc comment line 2
73+
/// This is different doc comment since the line starts differently
74+
//! Back to inner doc comment
75+
76+
----
77+
78+
(source_file
79+
(doc_comment)
80+
(line_comment)
81+
(doc_comment)
82+
(line_comment)
83+
(doc_comment)
84+
(doc_comment)
85+
(doc_comment)
86+
(doc_comment))
87+
5888
=====================================
5989
Greek letters in identifiers
6090
=====================================

grammar.js

+3-10
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ const primitive_types = numeric_types.concat(['bool', 'str', 'char'])
3838
module.exports = grammar({
3939
name: 'rust',
4040

41-
extras: $ => [/\s/, $.line_comment, $.block_comment],
41+
extras: $ => [/\s/, $.line_comment, $.block_comment, $.doc_comment],
4242

4343
externals: $ => [
4444
$._string_content,
4545
$.raw_string_literal,
4646
$.float_literal,
4747
$.block_comment,
48+
$.line_comment,
49+
$.doc_comment
4850
],
4951

5052
supertypes: $ => [
@@ -1426,15 +1428,6 @@ module.exports = grammar({
14261428

14271429
boolean_literal: $ => choice('true', 'false'),
14281430

1429-
comment: $ => choice(
1430-
$.line_comment,
1431-
$.block_comment
1432-
),
1433-
1434-
line_comment: $ => token(seq(
1435-
'//', /.*/
1436-
)),
1437-
14381431
_path: $ => choice(
14391432
$.self,
14401433
alias(choice(...primitive_types), $.identifier),

src/scanner.c

+71
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ enum TokenType {
66
RAW_STRING_LITERAL,
77
FLOAT_LITERAL,
88
BLOCK_COMMENT,
9+
LINE_COMMENT,
10+
DOC_COMMENT,
911
};
1012

1113
void *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

Comments
 (0)