Skip to content

Commit 952e530

Browse files
committed
fix(lex): parse let f = (): RT<T>=>null;
Test Plan: `let f = (): RT<T>=>null;` Fixes #1169
1 parent 1f9d30b commit 952e530

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/quick-lint-js/fe/lex.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,13 @@ void Lexer::skip_less_less_as_less() {
998998
void Lexer::skip_as_greater() {
999999
switch (this->last_token_.type) {
10001000
case Token_Type::greater_equal:
1001-
this->last_token_.type = Token_Type::equal;
1001+
if (this->input_[0] == '>') {
1002+
// >=> ➤ > =>
1003+
this->last_token_.type = Token_Type::equal_greater;
1004+
this->input_ += 1;
1005+
} else {
1006+
this->last_token_.type = Token_Type::equal;
1007+
}
10021008
break;
10031009
case Token_Type::greater_greater_equal:
10041010
this->last_token_.type = Token_Type::greater_equal;
@@ -1018,6 +1024,7 @@ void Lexer::skip_as_greater() {
10181024
}
10191025
this->last_token_.has_leading_newline = false;
10201026
this->last_token_.begin += 1;
1027+
this->last_token_.end = this->input_;
10211028
this->last_last_token_end_ = this->last_token_.begin;
10221029
}
10231030

test/test-parse-typescript-generic.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,60 @@ TEST_F(
10981098
}
10991099
}
11001100

1101+
TEST_F(Test_Parse_TypeScript_Generic,
1102+
greater_equal_greater_is_split_into_two_tokens) {
1103+
{
1104+
Spy_Visitor p = test_parse_and_visit_statement(
1105+
u8"let f = (): RT<T>=>{};"_sv, no_diags, typescript_options);
1106+
EXPECT_THAT(p.visits, ElementsAreArray({
1107+
"visit_enter_function_scope", //
1108+
"visit_enter_type_scope", // :
1109+
"visit_variable_type_use", // RT
1110+
"visit_variable_type_use", // T
1111+
"visit_exit_type_scope", //
1112+
"visit_enter_function_scope_body", // {
1113+
"visit_exit_function_scope", // }
1114+
"visit_variable_declaration", // let f
1115+
}));
1116+
}
1117+
{
1118+
Spy_Visitor p = test_parse_and_visit_statement(
1119+
u8"let f = (): RT<RT<T>>=> {};"_sv, no_diags, typescript_options);
1120+
EXPECT_THAT(p.visits, ElementsAreArray({
1121+
"visit_enter_function_scope", //
1122+
"visit_enter_type_scope", // :
1123+
"visit_variable_type_use", // RT
1124+
"visit_variable_type_use", // RT
1125+
"visit_variable_type_use", // T
1126+
"visit_exit_type_scope", //
1127+
"visit_enter_function_scope_body", // {
1128+
"visit_exit_function_scope", // }
1129+
"visit_variable_declaration", // let f
1130+
}));
1131+
}
1132+
{
1133+
Spy_Visitor p = test_parse_and_visit_statement(
1134+
u8"class C<T> { method(): C<T>=> {} }"_sv, //
1135+
u8" ^^ Diag_Functions_Or_Methods_Should_Not_Have_Arrow_Operator"_diag,
1136+
typescript_options);
1137+
EXPECT_THAT(p.visits, ElementsAreArray({
1138+
"visit_enter_class_scope", //
1139+
"visit_variable_declaration",
1140+
"visit_enter_class_scope_body", //
1141+
"visit_enter_function_scope", //
1142+
"visit_enter_type_scope", // :
1143+
"visit_variable_type_use", // T
1144+
"visit_variable_type_use", // C
1145+
"visit_exit_type_scope", //
1146+
"visit_enter_function_scope_body", //
1147+
"visit_exit_function_scope", //
1148+
"visit_property_declaration", // method
1149+
"visit_exit_class_scope",
1150+
"visit_variable_declaration", // C
1151+
}));
1152+
}
1153+
}
1154+
11011155
TEST_F(Test_Parse_TypeScript_Generic,
11021156
unambiguous_generic_arguments_are_parsed_in_javascript) {
11031157
{

0 commit comments

Comments
 (0)