diff --git a/CHANGELOG.md b/CHANGELOG.md index fb85d096d6c5..fd4ac4f2353d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,10 @@ Read our [guidelines for writing a good changelog entry](https://github.com/biom ### Parser +#### Bug fixes + +- Fix [#846](https://github.com/biomejs/biome/issues/846) that erroneously parsed `() => {}` as a JSX tag instead of an arrow function when both TypeScript and JSX are enabled. + ### VSCode ## 1.3.3 (2023-10-31) diff --git a/crates/biome_js_parser/src/syntax/function.rs b/crates/biome_js_parser/src/syntax/function.rs index 0a33c1a735da..8ae8ed081351 100644 --- a/crates/biome_js_parser/src/syntax/function.rs +++ b/crates/biome_js_parser/src/syntax/function.rs @@ -754,34 +754,37 @@ 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) - { - // ... - 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 // () =; // () =; // () =; + // () =; + // ; + // ; // test tsx tsx_type_arguments // // These are valid type arguments + // () => {}; + // () => {}; // () => {}; // () => {}; // () => {}; - // >() => {} - - // >() => {}; + + 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_at(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] => { - // `` is a JSX start element + // `` OR `` is a JSX element // and a `extends` type refinement: `` - if matches!(p.nth(n + 3), T![=] | T![>]) { + if matches!(p.nth(n + 3), T![=] | T![/] | T![>]) { IsParenthesizedArrowFunctionExpression::False } // `` Could be either @@ -796,6 +799,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) { + // ... + IsParenthesizedArrowFunctionExpression::True + } else if !is_nth_at_identifier(p, n + 1) { + // <5... + IsParenthesizedArrowFunctionExpression::False } else { // () =; () =; () =; +() =; +; +; diff --git a/crates/biome_js_parser/test_data/inline/ok/jsx_type_arguments.rast b/crates/biome_js_parser/test_data/inline/ok/jsx_type_arguments.rast index ce97a2ddb547..9851592e2225 100644 --- a/crates/biome_js_parser/test_data/inline/ok/jsx_type_arguments.rast +++ b/crates/biome_js_parser/test_data/inline/ok/jsx_type_arguments.rast @@ -122,15 +122,101 @@ JsModule { }, semicolon_token: SEMICOLON@118..119 ";" [] [], }, + JsExpressionStatement { + expression: JsxTagExpression { + tag: JsxElement { + opening_element: JsxOpeningElement { + l_angle_token: L_ANGLE@119..121 "<" [Newline("\n")] [], + name: JsxName { + value_token: JSX_IDENT@121..127 "const" [] [Whitespace(" ")], + }, + type_arguments: missing (optional), + attributes: JsxAttributeList [ + JsxAttribute { + name: JsxName { + value_token: JSX_IDENT@127..128 "A" [] [], + }, + initializer: missing (optional), + }, + ], + r_angle_token: R_ANGLE@128..129 ">" [] [], + }, + children: JsxChildList [ + JsxText { + value_token: JSX_TEXT_LITERAL@129..133 "() =" [] [], + }, + ], + closing_element: JsxClosingElement { + l_angle_token: L_ANGLE@133..134 "<" [] [], + slash_token: SLASH@134..135 "/" [] [], + name: JsxName { + value_token: JSX_IDENT@135..140 "const" [] [], + }, + r_angle_token: R_ANGLE@140..141 ">" [] [], + }, + }, + }, + semicolon_token: SEMICOLON@141..142 ";" [] [], + }, + JsExpressionStatement { + expression: JsxTagExpression { + tag: JsxSelfClosingElement { + l_angle_token: L_ANGLE@142..144 "<" [Newline("\n")] [], + name: JsxName { + value_token: JSX_IDENT@144..150 "const" [] [Whitespace(" ")], + }, + type_arguments: missing (optional), + attributes: JsxAttributeList [ + JsxAttribute { + name: JsxName { + value_token: JSX_IDENT@150..152 "A" [] [Whitespace(" ")], + }, + initializer: missing (optional), + }, + JsxAttribute { + name: JsxName { + value_token: JSX_IDENT@152..159 "extends" [] [], + }, + initializer: missing (optional), + }, + ], + slash_token: SLASH@159..160 "/" [] [], + r_angle_token: R_ANGLE@160..161 ">" [] [], + }, + }, + semicolon_token: SEMICOLON@161..162 ";" [] [], + }, + JsExpressionStatement { + expression: JsxTagExpression { + tag: JsxSelfClosingElement { + l_angle_token: L_ANGLE@162..164 "<" [Newline("\n")] [], + name: JsxReferenceIdentifier { + value_token: JSX_IDENT@164..166 "A" [] [Whitespace(" ")], + }, + type_arguments: missing (optional), + attributes: JsxAttributeList [ + JsxAttribute { + name: JsxName { + value_token: JSX_IDENT@166..173 "extends" [] [], + }, + initializer: missing (optional), + }, + ], + slash_token: SLASH@173..174 "/" [] [], + r_angle_token: R_ANGLE@174..175 ">" [] [], + }, + }, + semicolon_token: SEMICOLON@175..176 ";" [] [], + }, ], - eof_token: EOF@119..120 "" [Newline("\n")] [], + eof_token: EOF@176..177 "" [Newline("\n")] [], } -0: JS_MODULE@0..120 +0: JS_MODULE@0..177 0: (empty) 1: (empty) 2: JS_DIRECTIVE_LIST@0..0 - 3: JS_MODULE_ITEM_LIST@0..119 + 3: JS_MODULE_ITEM_LIST@0..176 0: JS_EXPRESSION_STATEMENT@0..70 0: JSX_TAG_EXPRESSION@0..69 0: JSX_ELEMENT@0..69 @@ -210,4 +296,62 @@ JsModule { 0: JSX_IDENT@116..117 "A" [] [] 3: R_ANGLE@117..118 ">" [] [] 1: SEMICOLON@118..119 ";" [] [] - 4: EOF@119..120 "" [Newline("\n")] [] + 3: JS_EXPRESSION_STATEMENT@119..142 + 0: JSX_TAG_EXPRESSION@119..141 + 0: JSX_ELEMENT@119..141 + 0: JSX_OPENING_ELEMENT@119..129 + 0: L_ANGLE@119..121 "<" [Newline("\n")] [] + 1: JSX_NAME@121..127 + 0: JSX_IDENT@121..127 "const" [] [Whitespace(" ")] + 2: (empty) + 3: JSX_ATTRIBUTE_LIST@127..128 + 0: JSX_ATTRIBUTE@127..128 + 0: JSX_NAME@127..128 + 0: JSX_IDENT@127..128 "A" [] [] + 1: (empty) + 4: R_ANGLE@128..129 ">" [] [] + 1: JSX_CHILD_LIST@129..133 + 0: JSX_TEXT@129..133 + 0: JSX_TEXT_LITERAL@129..133 "() =" [] [] + 2: JSX_CLOSING_ELEMENT@133..141 + 0: L_ANGLE@133..134 "<" [] [] + 1: SLASH@134..135 "/" [] [] + 2: JSX_NAME@135..140 + 0: JSX_IDENT@135..140 "const" [] [] + 3: R_ANGLE@140..141 ">" [] [] + 1: SEMICOLON@141..142 ";" [] [] + 4: JS_EXPRESSION_STATEMENT@142..162 + 0: JSX_TAG_EXPRESSION@142..161 + 0: JSX_SELF_CLOSING_ELEMENT@142..161 + 0: L_ANGLE@142..144 "<" [Newline("\n")] [] + 1: JSX_NAME@144..150 + 0: JSX_IDENT@144..150 "const" [] [Whitespace(" ")] + 2: (empty) + 3: JSX_ATTRIBUTE_LIST@150..159 + 0: JSX_ATTRIBUTE@150..152 + 0: JSX_NAME@150..152 + 0: JSX_IDENT@150..152 "A" [] [Whitespace(" ")] + 1: (empty) + 1: JSX_ATTRIBUTE@152..159 + 0: JSX_NAME@152..159 + 0: JSX_IDENT@152..159 "extends" [] [] + 1: (empty) + 4: SLASH@159..160 "/" [] [] + 5: R_ANGLE@160..161 ">" [] [] + 1: SEMICOLON@161..162 ";" [] [] + 5: JS_EXPRESSION_STATEMENT@162..176 + 0: JSX_TAG_EXPRESSION@162..175 + 0: JSX_SELF_CLOSING_ELEMENT@162..175 + 0: L_ANGLE@162..164 "<" [Newline("\n")] [] + 1: JSX_REFERENCE_IDENTIFIER@164..166 + 0: JSX_IDENT@164..166 "A" [] [Whitespace(" ")] + 2: (empty) + 3: JSX_ATTRIBUTE_LIST@166..173 + 0: JSX_ATTRIBUTE@166..173 + 0: JSX_NAME@166..173 + 0: JSX_IDENT@166..173 "extends" [] [] + 1: (empty) + 4: SLASH@173..174 "/" [] [] + 5: R_ANGLE@174..175 ">" [] [] + 1: SEMICOLON@175..176 ";" [] [] + 4: EOF@176..177 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.rast b/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.rast index 48200feb93f7..0b4bf787949b 100644 --- a/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.rast +++ b/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.rast @@ -12,13 +12,85 @@ JsModule { TsTypeParameter { modifiers: TsTypeParameterModifierList [], name: TsTypeParameterName { - ident_token: IDENT@35..37 "A" [] [Whitespace(" ")], + ident_token: IDENT@35..36 "A" [] [], + }, + constraint: missing (optional), + default: missing (optional), + }, + COMMA@36..37 "," [] [], + ], + r_angle_token: R_ANGLE@37..38 ">" [] [], + }, + parameters: JsParameters { + l_paren_token: L_PAREN@38..39 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@39..41 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + fat_arrow_token: FAT_ARROW@41..44 "=>" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@44..45 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@45..46 "}" [] [], + }, + }, + semicolon_token: SEMICOLON@46..47 ";" [] [], + }, + JsExpressionStatement { + expression: JsArrowFunctionExpression { + async_token: missing (optional), + type_parameters: TsTypeParameters { + l_angle_token: L_ANGLE@47..49 "<" [Newline("\n")] [], + items: TsTypeParameterList [ + TsTypeParameter { + modifiers: TsTypeParameterModifierList [ + TsConstModifier { + modifier_token: CONST_KW@49..55 "const" [] [Whitespace(" ")], + }, + ], + name: TsTypeParameterName { + ident_token: IDENT@55..56 "A" [] [], + }, + constraint: missing (optional), + default: missing (optional), + }, + COMMA@56..57 "," [] [], + ], + r_angle_token: R_ANGLE@57..58 ">" [] [], + }, + parameters: JsParameters { + l_paren_token: L_PAREN@58..59 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@59..61 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + fat_arrow_token: FAT_ARROW@61..64 "=>" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@64..65 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@65..66 "}" [] [], + }, + }, + semicolon_token: SEMICOLON@66..67 ";" [] [], + }, + JsExpressionStatement { + expression: JsArrowFunctionExpression { + async_token: missing (optional), + type_parameters: TsTypeParameters { + l_angle_token: L_ANGLE@67..69 "<" [Newline("\n")] [], + items: TsTypeParameterList [ + TsTypeParameter { + modifiers: TsTypeParameterModifierList [], + name: TsTypeParameterName { + ident_token: IDENT@69..71 "A" [] [Whitespace(" ")], }, constraint: TsTypeConstraintClause { - extends_token: EXTENDS_KW@37..45 "extends" [] [Whitespace(" ")], + extends_token: EXTENDS_KW@71..79 "extends" [] [Whitespace(" ")], ty: TsReferenceType { name: JsReferenceIdentifier { - value_token: IDENT@45..46 "B" [] [], + value_token: IDENT@79..80 "B" [] [], }, type_arguments: missing (optional), }, @@ -26,290 +98,344 @@ JsModule { default: missing (optional), }, ], - r_angle_token: R_ANGLE@46..47 ">" [] [], + r_angle_token: R_ANGLE@80..81 ">" [] [], }, parameters: JsParameters { - l_paren_token: L_PAREN@47..48 "(" [] [], + l_paren_token: L_PAREN@81..82 "(" [] [], items: JsParameterList [], - r_paren_token: R_PAREN@48..50 ")" [] [Whitespace(" ")], + r_paren_token: R_PAREN@82..84 ")" [] [Whitespace(" ")], }, return_type_annotation: missing (optional), - fat_arrow_token: FAT_ARROW@50..53 "=>" [] [Whitespace(" ")], + fat_arrow_token: FAT_ARROW@84..87 "=>" [] [Whitespace(" ")], body: JsFunctionBody { - l_curly_token: L_CURLY@53..54 "{" [] [], + l_curly_token: L_CURLY@87..88 "{" [] [], directives: JsDirectiveList [], statements: JsStatementList [], - r_curly_token: R_CURLY@54..55 "}" [] [], + r_curly_token: R_CURLY@88..89 "}" [] [], }, }, - semicolon_token: SEMICOLON@55..56 ";" [] [], + semicolon_token: SEMICOLON@89..90 ";" [] [], }, JsExpressionStatement { expression: JsArrowFunctionExpression { async_token: missing (optional), type_parameters: TsTypeParameters { - l_angle_token: L_ANGLE@56..58 "<" [Newline("\n")] [], + l_angle_token: L_ANGLE@90..92 "<" [Newline("\n")] [], items: TsTypeParameterList [ TsTypeParameter { modifiers: TsTypeParameterModifierList [], name: TsTypeParameterName { - ident_token: IDENT@58..59 "A" [] [], + ident_token: IDENT@92..93 "A" [] [], }, constraint: missing (optional), default: TsDefaultTypeClause { - eq_token: EQ@59..60 "=" [] [], + eq_token: EQ@93..94 "=" [] [], ty: TsStringType { - string_token: STRING_KW@60..66 "string" [] [], + string_token: STRING_KW@94..100 "string" [] [], }, }, }, ], - r_angle_token: R_ANGLE@66..67 ">" [] [], + r_angle_token: R_ANGLE@100..101 ">" [] [], }, parameters: JsParameters { - l_paren_token: L_PAREN@67..68 "(" [] [], + l_paren_token: L_PAREN@101..102 "(" [] [], items: JsParameterList [], - r_paren_token: R_PAREN@68..70 ")" [] [Whitespace(" ")], + r_paren_token: R_PAREN@102..104 ")" [] [Whitespace(" ")], }, return_type_annotation: missing (optional), - fat_arrow_token: FAT_ARROW@70..73 "=>" [] [Whitespace(" ")], + fat_arrow_token: FAT_ARROW@104..107 "=>" [] [Whitespace(" ")], body: JsFunctionBody { - l_curly_token: L_CURLY@73..74 "{" [] [], + l_curly_token: L_CURLY@107..108 "{" [] [], directives: JsDirectiveList [], statements: JsStatementList [], - r_curly_token: R_CURLY@74..75 "}" [] [], + r_curly_token: R_CURLY@108..109 "}" [] [], }, }, - semicolon_token: SEMICOLON@75..76 ";" [] [], + semicolon_token: SEMICOLON@109..110 ";" [] [], }, JsExpressionStatement { expression: JsArrowFunctionExpression { async_token: missing (optional), type_parameters: TsTypeParameters { - l_angle_token: L_ANGLE@76..78 "<" [Newline("\n")] [], + l_angle_token: L_ANGLE@110..112 "<" [Newline("\n")] [], items: TsTypeParameterList [ TsTypeParameter { modifiers: TsTypeParameterModifierList [], name: TsTypeParameterName { - ident_token: IDENT@78..79 "A" [] [], + ident_token: IDENT@112..113 "A" [] [], }, constraint: missing (optional), default: missing (optional), }, - COMMA@79..81 "," [] [Whitespace(" ")], + COMMA@113..115 "," [] [Whitespace(" ")], TsTypeParameter { modifiers: TsTypeParameterModifierList [], name: TsTypeParameterName { - ident_token: IDENT@81..82 "B" [] [], + ident_token: IDENT@115..116 "B" [] [], }, constraint: missing (optional), default: missing (optional), }, ], - r_angle_token: R_ANGLE@82..83 ">" [] [], + r_angle_token: R_ANGLE@116..117 ">" [] [], }, parameters: JsParameters { - l_paren_token: L_PAREN@83..84 "(" [] [], + l_paren_token: L_PAREN@117..118 "(" [] [], items: JsParameterList [], - r_paren_token: R_PAREN@84..86 ")" [] [Whitespace(" ")], + r_paren_token: R_PAREN@118..120 ")" [] [Whitespace(" ")], }, return_type_annotation: missing (optional), - fat_arrow_token: FAT_ARROW@86..89 "=>" [] [Whitespace(" ")], + fat_arrow_token: FAT_ARROW@120..123 "=>" [] [Whitespace(" ")], body: JsFunctionBody { - l_curly_token: L_CURLY@89..90 "{" [] [], + l_curly_token: L_CURLY@123..124 "{" [] [], directives: JsDirectiveList [], statements: JsStatementList [], - r_curly_token: R_CURLY@90..91 "}" [] [], + r_curly_token: R_CURLY@124..125 "}" [] [], }, }, - semicolon_token: SEMICOLON@91..92 ";" [] [], + semicolon_token: SEMICOLON@125..126 ";" [] [], }, JsExpressionStatement { expression: JsArrowFunctionExpression { async_token: missing (optional), type_parameters: TsTypeParameters { - l_angle_token: L_ANGLE@92..94 "<" [Newline("\n")] [], + l_angle_token: L_ANGLE@126..128 "<" [Newline("\n")] [], items: TsTypeParameterList [ TsTypeParameter { modifiers: TsTypeParameterModifierList [], name: TsTypeParameterName { - ident_token: IDENT@94..96 "A" [] [Whitespace(" ")], + ident_token: IDENT@128..130 "A" [] [Whitespace(" ")], }, constraint: TsTypeConstraintClause { - extends_token: EXTENDS_KW@96..104 "extends" [] [Whitespace(" ")], + extends_token: EXTENDS_KW@130..138 "extends" [] [Whitespace(" ")], ty: TsReferenceType { name: JsReferenceIdentifier { - value_token: IDENT@104..105 "B" [] [], + value_token: IDENT@138..139 "B" [] [], }, type_arguments: TsTypeArguments { - l_angle_token: L_ANGLE@105..106 "<" [] [], + l_angle_token: L_ANGLE@139..140 "<" [] [], ts_type_argument_list: TsTypeArgumentList [ TsReferenceType { name: JsReferenceIdentifier { - value_token: IDENT@106..107 "C" [] [], + value_token: IDENT@140..141 "C" [] [], }, type_arguments: missing (optional), }, ], - r_angle_token: R_ANGLE@107..108 ">" [] [], + r_angle_token: R_ANGLE@141..142 ">" [] [], }, }, }, default: missing (optional), }, ], - r_angle_token: R_ANGLE@108..109 ">" [] [], + r_angle_token: R_ANGLE@142..143 ">" [] [], }, parameters: JsParameters { - l_paren_token: L_PAREN@109..110 "(" [] [], + l_paren_token: L_PAREN@143..144 "(" [] [], items: JsParameterList [], - r_paren_token: R_PAREN@110..112 ")" [] [Whitespace(" ")], + r_paren_token: R_PAREN@144..146 ")" [] [Whitespace(" ")], }, return_type_annotation: missing (optional), - fat_arrow_token: FAT_ARROW@112..115 "=>" [] [Whitespace(" ")], + fat_arrow_token: FAT_ARROW@146..149 "=>" [] [Whitespace(" ")], body: JsFunctionBody { - l_curly_token: L_CURLY@115..116 "{" [] [], + l_curly_token: L_CURLY@149..150 "{" [] [], directives: JsDirectiveList [], statements: JsStatementList [], - r_curly_token: R_CURLY@116..117 "}" [] [], + r_curly_token: R_CURLY@150..151 "}" [] [], }, }, - semicolon_token: missing (optional), + semicolon_token: SEMICOLON@151..152 ";" [] [], }, ], - eof_token: EOF@117..118 "" [Newline("\n")] [], + eof_token: EOF@152..153 "" [Newline("\n")] [], } -0: JS_MODULE@0..118 +0: JS_MODULE@0..153 0: (empty) 1: (empty) 2: JS_DIRECTIVE_LIST@0..0 - 3: JS_MODULE_ITEM_LIST@0..117 - 0: JS_EXPRESSION_STATEMENT@0..56 - 0: JS_ARROW_FUNCTION_EXPRESSION@0..55 + 3: JS_MODULE_ITEM_LIST@0..152 + 0: JS_EXPRESSION_STATEMENT@0..47 + 0: JS_ARROW_FUNCTION_EXPRESSION@0..46 0: (empty) - 1: TS_TYPE_PARAMETERS@0..47 + 1: TS_TYPE_PARAMETERS@0..38 0: L_ANGLE@0..35 "<" [Comments("// These are valid ty ..."), Newline("\n")] [] - 1: TS_TYPE_PARAMETER_LIST@35..46 - 0: TS_TYPE_PARAMETER@35..46 + 1: TS_TYPE_PARAMETER_LIST@35..37 + 0: TS_TYPE_PARAMETER@35..36 0: TS_TYPE_PARAMETER_MODIFIER_LIST@35..35 - 1: TS_TYPE_PARAMETER_NAME@35..37 - 0: IDENT@35..37 "A" [] [Whitespace(" ")] - 2: TS_TYPE_CONSTRAINT_CLAUSE@37..46 - 0: EXTENDS_KW@37..45 "extends" [] [Whitespace(" ")] - 1: TS_REFERENCE_TYPE@45..46 - 0: JS_REFERENCE_IDENTIFIER@45..46 - 0: IDENT@45..46 "B" [] [] + 1: TS_TYPE_PARAMETER_NAME@35..36 + 0: IDENT@35..36 "A" [] [] + 2: (empty) + 3: (empty) + 1: COMMA@36..37 "," [] [] + 2: R_ANGLE@37..38 ">" [] [] + 2: JS_PARAMETERS@38..41 + 0: L_PAREN@38..39 "(" [] [] + 1: JS_PARAMETER_LIST@39..39 + 2: R_PAREN@39..41 ")" [] [Whitespace(" ")] + 3: (empty) + 4: FAT_ARROW@41..44 "=>" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@44..46 + 0: L_CURLY@44..45 "{" [] [] + 1: JS_DIRECTIVE_LIST@45..45 + 2: JS_STATEMENT_LIST@45..45 + 3: R_CURLY@45..46 "}" [] [] + 1: SEMICOLON@46..47 ";" [] [] + 1: JS_EXPRESSION_STATEMENT@47..67 + 0: JS_ARROW_FUNCTION_EXPRESSION@47..66 + 0: (empty) + 1: TS_TYPE_PARAMETERS@47..58 + 0: L_ANGLE@47..49 "<" [Newline("\n")] [] + 1: TS_TYPE_PARAMETER_LIST@49..57 + 0: TS_TYPE_PARAMETER@49..56 + 0: TS_TYPE_PARAMETER_MODIFIER_LIST@49..55 + 0: TS_CONST_MODIFIER@49..55 + 0: CONST_KW@49..55 "const" [] [Whitespace(" ")] + 1: TS_TYPE_PARAMETER_NAME@55..56 + 0: IDENT@55..56 "A" [] [] + 2: (empty) + 3: (empty) + 1: COMMA@56..57 "," [] [] + 2: R_ANGLE@57..58 ">" [] [] + 2: JS_PARAMETERS@58..61 + 0: L_PAREN@58..59 "(" [] [] + 1: JS_PARAMETER_LIST@59..59 + 2: R_PAREN@59..61 ")" [] [Whitespace(" ")] + 3: (empty) + 4: FAT_ARROW@61..64 "=>" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@64..66 + 0: L_CURLY@64..65 "{" [] [] + 1: JS_DIRECTIVE_LIST@65..65 + 2: JS_STATEMENT_LIST@65..65 + 3: R_CURLY@65..66 "}" [] [] + 1: SEMICOLON@66..67 ";" [] [] + 2: JS_EXPRESSION_STATEMENT@67..90 + 0: JS_ARROW_FUNCTION_EXPRESSION@67..89 + 0: (empty) + 1: TS_TYPE_PARAMETERS@67..81 + 0: L_ANGLE@67..69 "<" [Newline("\n")] [] + 1: TS_TYPE_PARAMETER_LIST@69..80 + 0: TS_TYPE_PARAMETER@69..80 + 0: TS_TYPE_PARAMETER_MODIFIER_LIST@69..69 + 1: TS_TYPE_PARAMETER_NAME@69..71 + 0: IDENT@69..71 "A" [] [Whitespace(" ")] + 2: TS_TYPE_CONSTRAINT_CLAUSE@71..80 + 0: EXTENDS_KW@71..79 "extends" [] [Whitespace(" ")] + 1: TS_REFERENCE_TYPE@79..80 + 0: JS_REFERENCE_IDENTIFIER@79..80 + 0: IDENT@79..80 "B" [] [] 1: (empty) 3: (empty) - 2: R_ANGLE@46..47 ">" [] [] - 2: JS_PARAMETERS@47..50 - 0: L_PAREN@47..48 "(" [] [] - 1: JS_PARAMETER_LIST@48..48 - 2: R_PAREN@48..50 ")" [] [Whitespace(" ")] + 2: R_ANGLE@80..81 ">" [] [] + 2: JS_PARAMETERS@81..84 + 0: L_PAREN@81..82 "(" [] [] + 1: JS_PARAMETER_LIST@82..82 + 2: R_PAREN@82..84 ")" [] [Whitespace(" ")] 3: (empty) - 4: FAT_ARROW@50..53 "=>" [] [Whitespace(" ")] - 5: JS_FUNCTION_BODY@53..55 - 0: L_CURLY@53..54 "{" [] [] - 1: JS_DIRECTIVE_LIST@54..54 - 2: JS_STATEMENT_LIST@54..54 - 3: R_CURLY@54..55 "}" [] [] - 1: SEMICOLON@55..56 ";" [] [] - 1: JS_EXPRESSION_STATEMENT@56..76 - 0: JS_ARROW_FUNCTION_EXPRESSION@56..75 + 4: FAT_ARROW@84..87 "=>" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@87..89 + 0: L_CURLY@87..88 "{" [] [] + 1: JS_DIRECTIVE_LIST@88..88 + 2: JS_STATEMENT_LIST@88..88 + 3: R_CURLY@88..89 "}" [] [] + 1: SEMICOLON@89..90 ";" [] [] + 3: JS_EXPRESSION_STATEMENT@90..110 + 0: JS_ARROW_FUNCTION_EXPRESSION@90..109 0: (empty) - 1: TS_TYPE_PARAMETERS@56..67 - 0: L_ANGLE@56..58 "<" [Newline("\n")] [] - 1: TS_TYPE_PARAMETER_LIST@58..66 - 0: TS_TYPE_PARAMETER@58..66 - 0: TS_TYPE_PARAMETER_MODIFIER_LIST@58..58 - 1: TS_TYPE_PARAMETER_NAME@58..59 - 0: IDENT@58..59 "A" [] [] + 1: TS_TYPE_PARAMETERS@90..101 + 0: L_ANGLE@90..92 "<" [Newline("\n")] [] + 1: TS_TYPE_PARAMETER_LIST@92..100 + 0: TS_TYPE_PARAMETER@92..100 + 0: TS_TYPE_PARAMETER_MODIFIER_LIST@92..92 + 1: TS_TYPE_PARAMETER_NAME@92..93 + 0: IDENT@92..93 "A" [] [] 2: (empty) - 3: TS_DEFAULT_TYPE_CLAUSE@59..66 - 0: EQ@59..60 "=" [] [] - 1: TS_STRING_TYPE@60..66 - 0: STRING_KW@60..66 "string" [] [] - 2: R_ANGLE@66..67 ">" [] [] - 2: JS_PARAMETERS@67..70 - 0: L_PAREN@67..68 "(" [] [] - 1: JS_PARAMETER_LIST@68..68 - 2: R_PAREN@68..70 ")" [] [Whitespace(" ")] + 3: TS_DEFAULT_TYPE_CLAUSE@93..100 + 0: EQ@93..94 "=" [] [] + 1: TS_STRING_TYPE@94..100 + 0: STRING_KW@94..100 "string" [] [] + 2: R_ANGLE@100..101 ">" [] [] + 2: JS_PARAMETERS@101..104 + 0: L_PAREN@101..102 "(" [] [] + 1: JS_PARAMETER_LIST@102..102 + 2: R_PAREN@102..104 ")" [] [Whitespace(" ")] 3: (empty) - 4: FAT_ARROW@70..73 "=>" [] [Whitespace(" ")] - 5: JS_FUNCTION_BODY@73..75 - 0: L_CURLY@73..74 "{" [] [] - 1: JS_DIRECTIVE_LIST@74..74 - 2: JS_STATEMENT_LIST@74..74 - 3: R_CURLY@74..75 "}" [] [] - 1: SEMICOLON@75..76 ";" [] [] - 2: JS_EXPRESSION_STATEMENT@76..92 - 0: JS_ARROW_FUNCTION_EXPRESSION@76..91 + 4: FAT_ARROW@104..107 "=>" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@107..109 + 0: L_CURLY@107..108 "{" [] [] + 1: JS_DIRECTIVE_LIST@108..108 + 2: JS_STATEMENT_LIST@108..108 + 3: R_CURLY@108..109 "}" [] [] + 1: SEMICOLON@109..110 ";" [] [] + 4: JS_EXPRESSION_STATEMENT@110..126 + 0: JS_ARROW_FUNCTION_EXPRESSION@110..125 0: (empty) - 1: TS_TYPE_PARAMETERS@76..83 - 0: L_ANGLE@76..78 "<" [Newline("\n")] [] - 1: TS_TYPE_PARAMETER_LIST@78..82 - 0: TS_TYPE_PARAMETER@78..79 - 0: TS_TYPE_PARAMETER_MODIFIER_LIST@78..78 - 1: TS_TYPE_PARAMETER_NAME@78..79 - 0: IDENT@78..79 "A" [] [] + 1: TS_TYPE_PARAMETERS@110..117 + 0: L_ANGLE@110..112 "<" [Newline("\n")] [] + 1: TS_TYPE_PARAMETER_LIST@112..116 + 0: TS_TYPE_PARAMETER@112..113 + 0: TS_TYPE_PARAMETER_MODIFIER_LIST@112..112 + 1: TS_TYPE_PARAMETER_NAME@112..113 + 0: IDENT@112..113 "A" [] [] 2: (empty) 3: (empty) - 1: COMMA@79..81 "," [] [Whitespace(" ")] - 2: TS_TYPE_PARAMETER@81..82 - 0: TS_TYPE_PARAMETER_MODIFIER_LIST@81..81 - 1: TS_TYPE_PARAMETER_NAME@81..82 - 0: IDENT@81..82 "B" [] [] + 1: COMMA@113..115 "," [] [Whitespace(" ")] + 2: TS_TYPE_PARAMETER@115..116 + 0: TS_TYPE_PARAMETER_MODIFIER_LIST@115..115 + 1: TS_TYPE_PARAMETER_NAME@115..116 + 0: IDENT@115..116 "B" [] [] 2: (empty) 3: (empty) - 2: R_ANGLE@82..83 ">" [] [] - 2: JS_PARAMETERS@83..86 - 0: L_PAREN@83..84 "(" [] [] - 1: JS_PARAMETER_LIST@84..84 - 2: R_PAREN@84..86 ")" [] [Whitespace(" ")] + 2: R_ANGLE@116..117 ">" [] [] + 2: JS_PARAMETERS@117..120 + 0: L_PAREN@117..118 "(" [] [] + 1: JS_PARAMETER_LIST@118..118 + 2: R_PAREN@118..120 ")" [] [Whitespace(" ")] 3: (empty) - 4: FAT_ARROW@86..89 "=>" [] [Whitespace(" ")] - 5: JS_FUNCTION_BODY@89..91 - 0: L_CURLY@89..90 "{" [] [] - 1: JS_DIRECTIVE_LIST@90..90 - 2: JS_STATEMENT_LIST@90..90 - 3: R_CURLY@90..91 "}" [] [] - 1: SEMICOLON@91..92 ";" [] [] - 3: JS_EXPRESSION_STATEMENT@92..117 - 0: JS_ARROW_FUNCTION_EXPRESSION@92..117 + 4: FAT_ARROW@120..123 "=>" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@123..125 + 0: L_CURLY@123..124 "{" [] [] + 1: JS_DIRECTIVE_LIST@124..124 + 2: JS_STATEMENT_LIST@124..124 + 3: R_CURLY@124..125 "}" [] [] + 1: SEMICOLON@125..126 ";" [] [] + 5: JS_EXPRESSION_STATEMENT@126..152 + 0: JS_ARROW_FUNCTION_EXPRESSION@126..151 0: (empty) - 1: TS_TYPE_PARAMETERS@92..109 - 0: L_ANGLE@92..94 "<" [Newline("\n")] [] - 1: TS_TYPE_PARAMETER_LIST@94..108 - 0: TS_TYPE_PARAMETER@94..108 - 0: TS_TYPE_PARAMETER_MODIFIER_LIST@94..94 - 1: TS_TYPE_PARAMETER_NAME@94..96 - 0: IDENT@94..96 "A" [] [Whitespace(" ")] - 2: TS_TYPE_CONSTRAINT_CLAUSE@96..108 - 0: EXTENDS_KW@96..104 "extends" [] [Whitespace(" ")] - 1: TS_REFERENCE_TYPE@104..108 - 0: JS_REFERENCE_IDENTIFIER@104..105 - 0: IDENT@104..105 "B" [] [] - 1: TS_TYPE_ARGUMENTS@105..108 - 0: L_ANGLE@105..106 "<" [] [] - 1: TS_TYPE_ARGUMENT_LIST@106..107 - 0: TS_REFERENCE_TYPE@106..107 - 0: JS_REFERENCE_IDENTIFIER@106..107 - 0: IDENT@106..107 "C" [] [] + 1: TS_TYPE_PARAMETERS@126..143 + 0: L_ANGLE@126..128 "<" [Newline("\n")] [] + 1: TS_TYPE_PARAMETER_LIST@128..142 + 0: TS_TYPE_PARAMETER@128..142 + 0: TS_TYPE_PARAMETER_MODIFIER_LIST@128..128 + 1: TS_TYPE_PARAMETER_NAME@128..130 + 0: IDENT@128..130 "A" [] [Whitespace(" ")] + 2: TS_TYPE_CONSTRAINT_CLAUSE@130..142 + 0: EXTENDS_KW@130..138 "extends" [] [Whitespace(" ")] + 1: TS_REFERENCE_TYPE@138..142 + 0: JS_REFERENCE_IDENTIFIER@138..139 + 0: IDENT@138..139 "B" [] [] + 1: TS_TYPE_ARGUMENTS@139..142 + 0: L_ANGLE@139..140 "<" [] [] + 1: TS_TYPE_ARGUMENT_LIST@140..141 + 0: TS_REFERENCE_TYPE@140..141 + 0: JS_REFERENCE_IDENTIFIER@140..141 + 0: IDENT@140..141 "C" [] [] 1: (empty) - 2: R_ANGLE@107..108 ">" [] [] + 2: R_ANGLE@141..142 ">" [] [] 3: (empty) - 2: R_ANGLE@108..109 ">" [] [] - 2: JS_PARAMETERS@109..112 - 0: L_PAREN@109..110 "(" [] [] - 1: JS_PARAMETER_LIST@110..110 - 2: R_PAREN@110..112 ")" [] [Whitespace(" ")] + 2: R_ANGLE@142..143 ">" [] [] + 2: JS_PARAMETERS@143..146 + 0: L_PAREN@143..144 "(" [] [] + 1: JS_PARAMETER_LIST@144..144 + 2: R_PAREN@144..146 ")" [] [Whitespace(" ")] 3: (empty) - 4: FAT_ARROW@112..115 "=>" [] [Whitespace(" ")] - 5: JS_FUNCTION_BODY@115..117 - 0: L_CURLY@115..116 "{" [] [] - 1: JS_DIRECTIVE_LIST@116..116 - 2: JS_STATEMENT_LIST@116..116 - 3: R_CURLY@116..117 "}" [] [] - 1: (empty) - 4: EOF@117..118 "" [Newline("\n")] [] + 4: FAT_ARROW@146..149 "=>" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@149..151 + 0: L_CURLY@149..150 "{" [] [] + 1: JS_DIRECTIVE_LIST@150..150 + 2: JS_STATEMENT_LIST@150..150 + 3: R_CURLY@150..151 "}" [] [] + 1: SEMICOLON@151..152 ";" [] [] + 4: EOF@152..153 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.tsx b/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.tsx index 26d28966793a..0128c0f8303a 100644 --- a/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.tsx +++ b/crates/biome_js_parser/test_data/inline/ok/tsx_type_arguments.tsx @@ -1,5 +1,7 @@ // These are valid type arguments +() => {}; +() => {}; () => {}; () => {}; () => {}; ->() => {} +>() => {}; diff --git a/website/src/content/docs/internals/changelog.mdx b/website/src/content/docs/internals/changelog.mdx index fa863d472b44..940961a8d863 100644 --- a/website/src/content/docs/internals/changelog.mdx +++ b/website/src/content/docs/internals/changelog.mdx @@ -69,6 +69,10 @@ Read our [guidelines for writing a good changelog entry](https://github.com/biom ### Parser +#### Bug fixes + +- Fix [#846](https://github.com/biomejs/biome/issues/846) that erroneously parsed `() => {}` as a JSX tag instead of an arrow function when both TypeScript and JSX are enabled. + ### VSCode ## 1.3.3 (2023-10-31)