Skip to content

Commit 2ea8012

Browse files
committed
Warn on redundant semicolon after else
1 parent 06af6e3 commit 2ea8012

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

src/quick-lint-js/error.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,12 @@
11391139
{ source_code_span continue_statement; }, \
11401140
.error(QLJS_TRANSLATABLE("continue can only be used inside of a loop"), \
11411141
continue_statement)) \
1142+
\
1143+
QLJS_ERROR_TYPE( \
1144+
error_redundant_semicolon_after_else, "E202", \
1145+
{ source_code_span semicolon; }, \
1146+
.warning(QLJS_TRANSLATABLE("redundant semicolon after else"), \
1147+
semicolon)) \
11421148
/* END */
11431149

11441150
namespace quick_lint_js {

src/quick-lint-js/parse.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,6 +2516,13 @@ class parser {
25162516

25172517
if (this->peek().type == token_type::kw_else) {
25182518
this->skip();
2519+
if (this->peek().type == token_type::semicolon) {
2520+
source_code_span semicolon = this->peek().span();
2521+
this->error_reporter_->report(error_redundant_semicolon_after_else{
2522+
.semicolon = source_code_span(
2523+
semicolon.begin(), semicolon.end()),
2524+
});
2525+
}
25192526
parse_and_visit_body();
25202527
}
25212528
}

test/test-parse-statement.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,22 @@ TEST(test_parse, else_without_if) {
578578
}
579579
}
580580

581+
TEST(test_parse, else_redundant_semicolon) {
582+
{
583+
spy_visitor v;
584+
padded_string code(u8"if (cond) { body; } else; { body; }"_sv);
585+
parser p(&code, &v);
586+
EXPECT_TRUE(p.parse_and_visit_statement(v));
587+
EXPECT_THAT(v.visits, ElementsAre("visit_variable_use", // cond
588+
"visit_enter_block_scope", // (if)
589+
"visit_variable_use", // body
590+
"visit_exit_block_scope")); // (else)
591+
EXPECT_THAT(v.errors, ElementsAre(ERROR_TYPE_FIELD(
592+
error_redundant_semicolon_after_else, semicolon,
593+
offsets_matcher(&code, strlen(u8"if (cond) { body; } else"), u8";"))));
594+
}
595+
}
596+
581597
TEST(test_parse, block_statement) {
582598
{
583599
spy_visitor v = parse_and_visit_statement(u8"{ }"_sv);

0 commit comments

Comments
 (0)