Skip to content

Commit e4b6abb

Browse files
committed
fix(typescript): don't assume : after '=> ()' is part of '? :'
In the following two TypeScript examples, the treatment of ':' after '=> (somevar)' differs: true ? () => (somevar) : thing => { }; () => (somevar) : thing => { }; When parsing an arrow function body, quick-lint-js assumes that a ':' is *not* a type annotation. This works well for the first case, but causes quick-lint-js to misunderstand the second case. Teach arrow function body parsing to behave differently depending on whether we're inside the truthy branch of a conditional expression. Parsing of the truthy branch (parse-expression.cpp line 1801) sets .colon_type_annotation = allow_type_annotations::never, so pass that along; whereas calls which should treat the ':' as an type annotation set .colon_type_annotation = allow_type_annotations::typescript_only (default), so pass that along too.
1 parent 88ff5c0 commit e4b6abb

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2465,7 +2465,7 @@ expression* parser::parse_arrow_function_body_no_scope(
24652465
v, precedence{
24662466
.commas = false,
24672467
.in_operator = prec.in_operator,
2468-
.colon_type_annotation = allow_type_annotations::never,
2468+
.colon_type_annotation = prec.colon_type_annotation,
24692469
});
24702470
}
24712471

test/test-parse-typescript-function.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,27 @@ TEST_F(test_parse_typescript_function,
364364
}
365365
}
366366

367+
TEST_F(test_parse_typescript_function, arrow_with_arrow_body) {
368+
{
369+
// This used to confuse the quick-lint-js parser.
370+
test_parser p(u8"() => (): ReturnType => myVariable"_sv,
371+
typescript_options);
372+
p.parse_and_visit_expression();
373+
EXPECT_THAT(p.visits, ElementsAreArray({
374+
"visit_enter_function_scope", //
375+
"visit_enter_function_scope_body", //
376+
"visit_enter_function_scope", //
377+
"visit_variable_type_use", // ReturnType
378+
"visit_enter_function_scope_body", //
379+
"visit_variable_use", // myVariable
380+
"visit_exit_function_scope", //
381+
"visit_exit_function_scope", //
382+
}));
383+
EXPECT_THAT(p.variable_uses,
384+
ElementsAreArray({u8"ReturnType", u8"myVariable"}));
385+
}
386+
}
387+
367388
TEST_F(test_parse_typescript_function, object_method_return_type_annotation) {
368389
{
369390
test_parser p(u8"({ method(param): C {} })"_sv, typescript_options);

0 commit comments

Comments
 (0)