Skip to content

Commit d24e7ab

Browse files
committed
feat(typescript): require semicolon (or ASI) after 'declare function ...'
1 parent dc250c6 commit d24e7ab

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/quick-lint-js/fe/parse-statement.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4671,6 +4671,7 @@ void parser::parse_and_visit_declare_statement(
46714671

46724672
case function_parameter_parse_result::missing_parameters_ignore_body:
46734673
case function_parameter_parse_result::parsed_parameters_missing_body:
4674+
this->consume_semicolon_after_statement();
46744675
break;
46754676
}
46764677
}

test/test-parse-typescript-declare-function.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,24 @@ TEST_F(test_parse_typescript_declare_function,
8282
declare_keyword, strlen(u8""), u8"declare"_sv),
8383
}));
8484
}
85+
86+
{
87+
test_parser p(u8"declare function f() { } foo"_sv, typescript_options,
88+
capture_diags);
89+
p.parse_and_visit_module();
90+
EXPECT_THAT(p.visits, ElementsAreArray({
91+
"visit_variable_declaration", // f
92+
"visit_enter_function_scope", // f
93+
"visit_enter_function_scope_body", // {
94+
"visit_exit_function_scope", // }
95+
"visit_variable_use", // foo
96+
"visit_end_of_module", //
97+
}));
98+
EXPECT_THAT(p.errors, ElementsAreArray({
99+
DIAG_TYPE(diag_declare_function_cannot_have_body),
100+
}))
101+
<< "should not receive a diag_missing_semicolon_after_statement";
102+
}
85103
}
86104

87105
TEST_F(test_parse_typescript_declare_function,
@@ -209,6 +227,43 @@ TEST_F(test_parse_typescript_declare_function,
209227
EXPECT_THAT(p.variable_uses, ElementsAreArray({u8"declare"_sv}));
210228
}
211229
}
230+
231+
TEST_F(test_parse_typescript_declare_function,
232+
declare_function_requires_semicolon) {
233+
{
234+
test_parser p(u8"declare function f() foo"_sv, typescript_options,
235+
capture_diags);
236+
p.parse_and_visit_module();
237+
EXPECT_THAT(p.visits, ElementsAreArray({
238+
"visit_variable_declaration", // f
239+
"visit_enter_function_scope", // f
240+
"visit_exit_function_scope", // f
241+
"visit_variable_use", // foo
242+
"visit_end_of_module", //
243+
}));
244+
EXPECT_THAT(
245+
p.errors,
246+
ElementsAreArray({
247+
DIAG_TYPE_OFFSETS(p.code,
248+
diag_missing_semicolon_after_statement, //
249+
where, strlen(u8"declare function f()"), u8""_sv),
250+
}));
251+
}
252+
}
253+
254+
TEST_F(test_parse_typescript_declare_function, declare_function_performs_asi) {
255+
{
256+
test_parser p(u8"declare function f()\nfoo"_sv, typescript_options);
257+
p.parse_and_visit_module();
258+
EXPECT_THAT(p.visits, ElementsAreArray({
259+
"visit_variable_declaration", // f
260+
"visit_enter_function_scope", // f
261+
"visit_exit_function_scope", // f
262+
"visit_variable_use", // foo
263+
"visit_end_of_module", //
264+
}));
265+
}
266+
}
212267
}
213268
}
214269

0 commit comments

Comments
 (0)