Skip to content

Commit

Permalink
fix(js_parser): desambigaute JSX and const type param of arrow function
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Nov 23, 2023
1 parent 45e29db commit 38a29ab
Show file tree
Hide file tree
Showing 5 changed files with 375 additions and 175 deletions.
35 changes: 23 additions & 12 deletions crates/biome_js_parser/src/syntax/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,29 +754,34 @@ fn is_parenthesized_arrow_function_expression_impl(
}
// potential start of type parameters
T![<] => {
if is_nth_at_type_parameter_modifier(p, n + 1) && !JsSyntaxFeature::Jsx.is_supported(p)
{
// <const T>...
IsParenthesizedArrowFunctionExpression::True
} else if !is_nth_at_identifier(p, n + 1) {
// <5...
IsParenthesizedArrowFunctionExpression::False
}
// test jsx jsx_type_arguments
// // These may look like a valid arrows but are JSX
// <A extends>() =</A>;
// <A extends="B">() =</A>;
// <A extends ok>() =</A>;
// <const A>() =</const>;

// test tsx tsx_type_arguments
// // These are valid type arguments
// <A,>() => {};
// <const A,>() => {};
// <A extends B>() => {};
// <A=string>() => {};
// <A, B>() => {};
// <A extends B<C>>() => {}

// <a... JSX override
else if JsSyntaxFeature::Jsx.is_supported(p) {
// <A extends B<C>>() => {};

if JsSyntaxFeature::Jsx.is_supported(p) {
// Disambiguate between JSX and type parameters
// Type parameters of arrow functions accept only the `const` modifier.
let n = if p.nth(n + 1) == T![const] {
n + 1
} else {
n
};
if !is_nth_at_identifier(p, n + 1) {
// <5...
return IsParenthesizedArrowFunctionExpression::False;
};
match p.nth(n + 2) {
T![extends] => {
// `<a extends=` OR `<a extends>` is a JSX start element
Expand All @@ -796,6 +801,12 @@ fn is_parenthesized_arrow_function_expression_impl(
T![=] | T![,] => IsParenthesizedArrowFunctionExpression::True,
_ => IsParenthesizedArrowFunctionExpression::False,
}
} else if is_nth_at_type_parameter_modifier(p, n + 1) {
// <const T>...
IsParenthesizedArrowFunctionExpression::True
} else if !is_nth_at_identifier(p, n + 1) {
// <5...
IsParenthesizedArrowFunctionExpression::False
} else {
// <a...
IsParenthesizedArrowFunctionExpression::Unknown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
<A extends>() =</A>;
<A extends="B">() =</A>;
<A extends ok>() =</A>;
<const A>() =</const>;
68 changes: 64 additions & 4 deletions crates/biome_js_parser/test_data/inline/ok/jsx_type_arguments.rast
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,51 @@ JsModule {
},
semicolon_token: [email protected] ";" [] [],
},
JsExpressionStatement {
expression: JsxTagExpression {
tag: JsxElement {
opening_element: JsxOpeningElement {
l_angle_token: [email protected] "<" [Newline("\n")] [],
name: JsxName {
value_token: [email protected] "const" [] [Whitespace(" ")],
},
type_arguments: missing (optional),
attributes: JsxAttributeList [
JsxAttribute {
name: JsxName {
value_token: [email protected] "A" [] [],
},
initializer: missing (optional),
},
],
r_angle_token: [email protected] ">" [] [],
},
children: JsxChildList [
JsxText {
value_token: [email protected] "() =" [] [],
},
],
closing_element: JsxClosingElement {
l_angle_token: [email protected] "<" [] [],
slash_token: [email protected] "/" [] [],
name: JsxName {
value_token: [email protected] "const" [] [],
},
r_angle_token: [email protected] ">" [] [],
},
},
},
semicolon_token: [email protected] ";" [] [],
},
],
eof_token: EOF@119..120 "" [Newline("\n")] [],
eof_token: EOF@142..143 "" [Newline("\n")] [],
}

0: JS_MODULE@0..120
0: JS_MODULE@0..143
0: (empty)
1: (empty)
2: [email protected]
3: JS_MODULE_ITEM_LIST@0..119
3: JS_MODULE_ITEM_LIST@0..142
0: [email protected]
0: [email protected]
0: [email protected]
Expand Down Expand Up @@ -210,4 +246,28 @@ JsModule {
0: [email protected] "A" [] []
3: [email protected] ">" [] []
1: [email protected] ";" [] []
4: [email protected] "" [Newline("\n")] []
3: [email protected]
0: [email protected]
0: [email protected]
0: [email protected]
0: [email protected] "<" [Newline("\n")] []
1: [email protected]
0: [email protected] "const" [] [Whitespace(" ")]
2: (empty)
3: [email protected]
0: [email protected]
0: [email protected]
0: [email protected] "A" [] []
1: (empty)
4: [email protected] ">" [] []
1: [email protected]
0: [email protected]
0: [email protected] "() =" [] []
2: [email protected]
0: [email protected] "<" [] []
1: [email protected] "/" [] []
2: [email protected]
0: [email protected] "const" [] []
3: [email protected] ">" [] []
1: [email protected] ";" [] []
4: [email protected] "" [Newline("\n")] []
Loading

0 comments on commit 38a29ab

Please sign in to comment.