Skip to content

Fix: Comment optimization should not cause automatic-semi insert for single-line block #326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
33 changes: 27 additions & 6 deletions src/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,18 @@ static bool scan_template_chars(TSLexer *lexer) {
}
}

static bool scan_whitespace_and_comments(TSLexer *lexer, bool *scanned_comment) {
typedef enum {
REJECT, // Semicolon is illegal, ie a syntax error occurred
NO_NEWLINE, // Unclear if semicolon will be legal, continue
ACCEPT, // Semicolon is legal, assuming a comment was encountered
} WhitespaceResult;

/**
* @param consume If false, only consume enough to check if comment indicates semicolon-legality
*/
static WhitespaceResult scan_whitespace_and_comments(TSLexer *lexer, bool *scanned_comment, bool consume) {
bool saw_block_newline = false;

for (;;) {
while (iswspace(lexer->lookahead)) {
skip(lexer);
Expand All @@ -71,17 +82,25 @@ static bool scan_whitespace_and_comments(TSLexer *lexer, bool *scanned_comment)
if (lexer->lookahead == '/') {
skip(lexer);
*scanned_comment = true;

if (lexer->lookahead != '/' && !consume) {
return saw_block_newline ? ACCEPT : NO_NEWLINE;
}

break;
}
} else if (lexer->lookahead == '\n' || lexer->lookahead == 0x2028 || lexer->lookahead == 0x2029) {
saw_block_newline = true;
skip(lexer);
} else {
skip(lexer);
}
}
} else {
return false;
return REJECT;
}
} else {
return true;
return ACCEPT;
}
}
}
Expand All @@ -96,10 +115,12 @@ static bool scan_automatic_semicolon(TSLexer *lexer, bool comment_condition, boo
}

if (lexer->lookahead == '/') {
if (!scan_whitespace_and_comments(lexer, scanned_comment)) {
WhitespaceResult result = scan_whitespace_and_comments(lexer, scanned_comment, false);
if (result == REJECT) {
return false;
}
if (comment_condition && lexer->lookahead != ',' && lexer->lookahead != '=') {

if (result == ACCEPT && comment_condition && lexer->lookahead != ',' && lexer->lookahead != '=') {
return true;
}
}
Expand All @@ -125,7 +146,7 @@ static bool scan_automatic_semicolon(TSLexer *lexer, bool comment_condition, boo

skip(lexer);

if (!scan_whitespace_and_comments(lexer, scanned_comment)) {
if (scan_whitespace_and_comments(lexer, scanned_comment, true) == REJECT) {
return false;
}

Expand Down
22 changes: 21 additions & 1 deletion test/corpus/semicolon_insertion.txt
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,16 @@ let b /* comment between declarators */, c

let d

let e
/* back to back *//* comments */

class C {
method/*comment*/() {}
}

b
/* interleaved non-semi-insertion */
.c
---

(program
Expand All @@ -286,4 +296,14 @@ let d
(comment)
(comment)
(comment)
(lexical_declaration (variable_declarator (identifier))))
(lexical_declaration (variable_declarator (identifier)))
(lexical_declaration (variable_declarator (identifier)))
(comment)
(comment)
(class_declaration (identifier) (class_body (method_definition
(property_identifier)
(comment)
(formal_parameters)
(statement_block))))
(expression_statement
(member_expression (identifier) (comment) (property_identifier))))