diff --git a/CHANGELOG.md b/CHANGELOG.md index e5903d8a6b8f..a64de7543ae4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -192,6 +192,12 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b Contributed by @fireairforce +- Add support for parsing typescript's `resolution-mode` in Import Types([#2115](https://github.com/biomejs/biome/issues/2115)) + + ```ts + export type Fs = typeof import('fs', { with: { 'resolution-mode': 'import' } }); + ``` + #### Bug Fixes - The CSS parser now accepts more emoji in identifiers ([#3627](https://github.com/biomejs/biome/issues/3627#issuecomment-2392388022)). diff --git a/crates/biome_js_factory/src/generated/node_factory.rs b/crates/biome_js_factory/src/generated/node_factory.rs index f2afe8feb2a9..99ae9e84c5be 100644 --- a/crates/biome_js_factory/src/generated/node_factory.rs +++ b/crates/biome_js_factory/src/generated/node_factory.rs @@ -4971,15 +4971,11 @@ impl TsImportEqualsDeclarationBuilder { } pub fn ts_import_type( import_token: SyntaxToken, - l_paren_token: SyntaxToken, - argument_token: SyntaxToken, - r_paren_token: SyntaxToken, + arguments: JsCallArguments, ) -> TsImportTypeBuilder { TsImportTypeBuilder { import_token, - l_paren_token, - argument_token, - r_paren_token, + arguments, typeof_token: None, qualifier_clause: None, type_arguments: None, @@ -4987,9 +4983,7 @@ pub fn ts_import_type( } pub struct TsImportTypeBuilder { import_token: SyntaxToken, - l_paren_token: SyntaxToken, - argument_token: SyntaxToken, - r_paren_token: SyntaxToken, + arguments: JsCallArguments, typeof_token: Option, qualifier_clause: Option, type_arguments: Option, @@ -5013,9 +5007,7 @@ impl TsImportTypeBuilder { [ self.typeof_token.map(|token| SyntaxElement::Token(token)), Some(SyntaxElement::Token(self.import_token)), - Some(SyntaxElement::Token(self.l_paren_token)), - Some(SyntaxElement::Token(self.argument_token)), - Some(SyntaxElement::Token(self.r_paren_token)), + Some(SyntaxElement::Node(self.arguments.into_syntax())), self.qualifier_clause .map(|token| SyntaxElement::Node(token.into_syntax())), self.type_arguments diff --git a/crates/biome_js_factory/src/generated/syntax_factory.rs b/crates/biome_js_factory/src/generated/syntax_factory.rs index f4927dc760de..5fb242724f30 100644 --- a/crates/biome_js_factory/src/generated/syntax_factory.rs +++ b/crates/biome_js_factory/src/generated/syntax_factory.rs @@ -7514,7 +7514,7 @@ impl SyntaxFactory for JsSyntaxFactory { } TS_IMPORT_TYPE => { let mut elements = (&children).into_iter(); - let mut slots: RawNodeSlots<7usize> = RawNodeSlots::default(); + let mut slots: RawNodeSlots<5usize> = RawNodeSlots::default(); let mut current_element = elements.next(); if let Some(element) = ¤t_element { if element.kind() == T![typeof] { @@ -7531,21 +7531,7 @@ impl SyntaxFactory for JsSyntaxFactory { } slots.next_slot(); if let Some(element) = ¤t_element { - if element.kind() == T!['('] { - slots.mark_present(); - current_element = elements.next(); - } - } - slots.next_slot(); - if let Some(element) = ¤t_element { - if element.kind() == JS_STRING_LITERAL { - slots.mark_present(); - current_element = elements.next(); - } - } - slots.next_slot(); - if let Some(element) = ¤t_element { - if element.kind() == T![')'] { + if JsCallArguments::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } diff --git a/crates/biome_js_formatter/src/ts/module/import_type.rs b/crates/biome_js_formatter/src/ts/module/import_type.rs index 1dc76fa67f70..651f66d04f17 100644 --- a/crates/biome_js_formatter/src/ts/module/import_type.rs +++ b/crates/biome_js_formatter/src/ts/module/import_type.rs @@ -1,6 +1,4 @@ use crate::prelude::*; -use crate::utils::{FormatLiteralStringToken, StringLiteralParentKind}; - use biome_formatter::write; use biome_js_syntax::TsImportType; use biome_js_syntax::TsImportTypeFields; @@ -13,9 +11,7 @@ impl FormatNodeRule for FormatTsImportType { let TsImportTypeFields { typeof_token, import_token, - l_paren_token, - argument_token, - r_paren_token, + arguments, qualifier_clause, type_arguments, } = node.as_fields(); @@ -28,12 +24,7 @@ impl FormatNodeRule for FormatTsImportType { f, [ import_token.format(), - l_paren_token.format(), - FormatLiteralStringToken::new( - &argument_token?, - StringLiteralParentKind::Expression - ), - r_paren_token.format(), + arguments.format(), qualifier_clause.format(), type_arguments.format(), ] diff --git a/crates/biome_js_formatter/tests/specs/ts/type/import_type_with_resolution_mode.ts b/crates/biome_js_formatter/tests/specs/ts/type/import_type_with_resolution_mode.ts new file mode 100644 index 000000000000..685d1ca54c2e --- /dev/null +++ b/crates/biome_js_formatter/tests/specs/ts/type/import_type_with_resolution_mode.ts @@ -0,0 +1,5 @@ +export type Fs = typeof import('fs', { with: { 'resolution-mode': 'import' } }); +export type TypeFromRequire = + import("pkg", { with: { "resolution-mode": "require" } }).TypeFromRequire; +export type TypeFromImport = + import("pkg", { with: { "resolution-mode": "import" } }).TypeFromImport; \ No newline at end of file diff --git a/crates/biome_js_formatter/tests/specs/ts/type/import_type_with_resolution_mode.ts.snap b/crates/biome_js_formatter/tests/specs/ts/type/import_type_with_resolution_mode.ts.snap new file mode 100644 index 000000000000..ecbe830f4d76 --- /dev/null +++ b/crates/biome_js_formatter/tests/specs/ts/type/import_type_with_resolution_mode.ts.snap @@ -0,0 +1,46 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: ts/type/import_type_with_resolution_mode.ts +--- +# Input + +```ts +export type Fs = typeof import('fs', { with: { 'resolution-mode': 'import' } }); +export type TypeFromRequire = + import("pkg", { with: { "resolution-mode": "require" } }).TypeFromRequire; +export type TypeFromImport = + import("pkg", { with: { "resolution-mode": "import" } }).TypeFromImport; +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Quote style: Double Quotes +JSX quote style: Double Quotes +Quote properties: As needed +Trailing commas: All +Semicolons: Always +Arrow parentheses: Always +Bracket spacing: true +Bracket same line: false +Attribute Position: Auto +----- + +```ts +export type Fs = typeof import("fs", { with: { "resolution-mode": "import" } }); +export type TypeFromRequire = import("pkg", { + with: { "resolution-mode": "require" }, +}).TypeFromRequire; +export type TypeFromImport = import("pkg", { + with: { "resolution-mode": "import" }, +}).TypeFromImport; +``` diff --git a/crates/biome_js_parser/src/syntax/expr.rs b/crates/biome_js_parser/src/syntax/expr.rs index cb4c31498f8d..0c534153f50b 100644 --- a/crates/biome_js_parser/src/syntax/expr.rs +++ b/crates/biome_js_parser/src/syntax/expr.rs @@ -1450,12 +1450,13 @@ fn parse_primary_expression(p: &mut JsParser, context: ExpressionContext) -> Par // test js import_call // import("foo") // import("foo", { assert: { type: 'json' } }) + // import("foo", { with: { 'resolution-mode': 'import' } }) // test_err js import_invalid_args // import() // import(...["foo"]) // import("foo", { assert: { type: 'json' } }, "bar") - + // import("foo", { with: { type: 'json' } }, "bar") let args = p.start(); p.bump(T!['(']); let args_list = p.start(); @@ -1834,7 +1835,7 @@ fn parse_array_expr(p: &mut JsParser) -> ParsedSyntax { // test_err js spread // [...] /// A spread element consisting of three dots and an assignment expression such as `...foo` -fn parse_spread_element(p: &mut JsParser, context: ExpressionContext) -> ParsedSyntax { +pub(crate) fn parse_spread_element(p: &mut JsParser, context: ExpressionContext) -> ParsedSyntax { if !p.at(T![...]) { return Absent; } diff --git a/crates/biome_js_parser/src/syntax/typescript/types.rs b/crates/biome_js_parser/src/syntax/typescript/types.rs index b5b6d8f29d4b..5474bc84d918 100644 --- a/crates/biome_js_parser/src/syntax/typescript/types.rs +++ b/crates/biome_js_parser/src/syntax/typescript/types.rs @@ -5,13 +5,15 @@ use crate::prelude::*; use crate::state::{EnterType, SignatureFlags}; use crate::syntax::expr::{ is_at_binary_operator, is_at_expression, is_at_identifier, is_nth_at_identifier, - is_nth_at_identifier_or_keyword, parse_big_int_literal_expression, parse_identifier, - parse_literal_expression, parse_name, parse_number_literal_expression, - parse_reference_identifier, parse_template_elements, ExpressionContext, + is_nth_at_identifier_or_keyword, parse_assignment_expression_or_higher, + parse_big_int_literal_expression, parse_identifier, parse_literal_expression, parse_name, + parse_number_literal_expression, parse_reference_identifier, parse_template_elements, + ExpressionContext, }; use crate::syntax::function::{ parse_formal_parameter, parse_parameter_list, skip_parameter_start, ParameterContext, }; +use crate::syntax::js_parse_error; use crate::syntax::js_parse_error::{ decorators_not_allowed, expected_identifier, expected_object_member_name, expected_parameter, expected_parameters, expected_property_or_signature, modifier_already_seen, @@ -29,6 +31,7 @@ use crate::syntax::typescript::ts_parse_error::{ ts_in_out_modifier_cannot_appear_on_a_type_parameter, }; use biome_parser::parse_lists::{ParseNodeList, ParseSeparatedList}; +use biome_parser::ParserProgress; use enumflags2::{bitflags, make_bitflags, BitFlags}; use smallvec::SmallVec; @@ -1150,6 +1153,11 @@ fn parse_ts_mapped_type_optional_modifier_clause(p: &mut JsParser) -> ParsedSynt // type C = typeof import("test").a.b.c.d.e.f; // type D = import("test"); // type E = import("test").C; +// type F = typeof import("test", { with: { "resolution-mode": "import" } }); +// type G = import("test", { with: { "resolution-mode": "import" } }).TypeFromImport; +// type H = import("test", { with: { "resolution-mode": "import" } }); +// type I = import("test", { with: { "resolution-mode": "require" } }).C; +// type J = typeof import("test", { with: { "resolution-mode": "require" } }).a.b.c.d.e.f; fn parse_ts_import_type(p: &mut JsParser, context: TypeContext) -> ParsedSyntax { if !p.at(T![typeof]) && !p.at(T![import]) { return Absent; @@ -1158,9 +1166,44 @@ fn parse_ts_import_type(p: &mut JsParser, context: TypeContext) -> ParsedSyntax let m = p.start(); p.eat(T![typeof]); p.expect(T![import]); + let args = p.start(); p.expect(T!['(']); - p.expect(JS_STRING_LITERAL); + let args_list = p.start(); + + let mut progress = ParserProgress::default(); + let mut error_range_start = p.cur_range().start(); + let mut args_count = 0; + + println!("currr: {:?}", p.cur_text()); + + while !p.at(EOF) && !p.at(T![')']) { + progress.assert_progressing(p); + args_count += 1; + + if args_count == 3 { + error_range_start = p.cur_range().start(); + } + + parse_assignment_expression_or_higher(p, ExpressionContext::default()) + .or_add_diagnostic(p, js_parse_error::expected_expression_assignment); + + if p.at(T![,]) { + p.bump_any(); + } else { + break; + } + } + args_list.complete(p, JS_CALL_ARGUMENT_LIST); + + if args_count == 0 || args_count > 2 { + let err = p.err_builder( + "`typeof import()` requires exactly one or two arguments. ", + error_range_start..p.cur_range().end(), + ); + p.error(err); + } p.expect(T![')']); + args.complete(p, JS_CALL_ARGUMENTS); if p.at(T![.]) { let qualifier = p.start(); diff --git a/crates/biome_js_parser/src/tests.rs b/crates/biome_js_parser/src/tests.rs index 8bb58ede06df..d01317e65b08 100644 --- a/crates/biome_js_parser/src/tests.rs +++ b/crates/biome_js_parser/src/tests.rs @@ -408,7 +408,7 @@ fn diagnostics_print_correctly() { #[test] pub fn quick_test() { let code = r#" - import defer * as yNamespace from "y"; + type A = typeof import("test"); "#; let root = parse( code, diff --git a/crates/biome_js_parser/test_data/inline/err/import_invalid_args.js b/crates/biome_js_parser/test_data/inline/err/import_invalid_args.js index 032b373263ea..8e214ed526f6 100644 --- a/crates/biome_js_parser/test_data/inline/err/import_invalid_args.js +++ b/crates/biome_js_parser/test_data/inline/err/import_invalid_args.js @@ -1,3 +1,4 @@ import() import(...["foo"]) import("foo", { assert: { type: 'json' } }, "bar") +import("foo", { with: { type: 'json' } }, "bar") diff --git a/crates/biome_js_parser/test_data/inline/err/import_invalid_args.rast b/crates/biome_js_parser/test_data/inline/err/import_invalid_args.rast index 2ff276e9fd86..f875058a6c77 100644 --- a/crates/biome_js_parser/test_data/inline/err/import_invalid_args.rast +++ b/crates/biome_js_parser/test_data/inline/err/import_invalid_args.rast @@ -93,15 +93,62 @@ JsModule { }, semicolon_token: missing (optional), }, + JsExpressionStatement { + expression: JsImportCallExpression { + import_token: IMPORT_KW@78..85 "import" [Newline("\n")] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@85..86 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@86..91 "\"foo\"" [] [], + }, + COMMA@91..93 "," [] [Whitespace(" ")], + JsObjectExpression { + l_curly_token: L_CURLY@93..95 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@95..99 "with" [] [], + }, + colon_token: COLON@99..101 ":" [] [Whitespace(" ")], + value: JsObjectExpression { + l_curly_token: L_CURLY@101..103 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@103..107 "type" [] [], + }, + colon_token: COLON@107..109 ":" [] [Whitespace(" ")], + value: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@109..116 "'json'" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@116..118 "}" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@118..119 "}" [] [], + }, + COMMA@119..121 "," [] [Whitespace(" ")], + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@121..126 "\"bar\"" [] [], + }, + ], + r_paren_token: R_PAREN@126..127 ")" [] [], + }, + }, + semicolon_token: missing (optional), + }, ], - eof_token: EOF@78..79 "" [Newline("\n")] [], + eof_token: EOF@127..128 "" [Newline("\n")] [], } -0: JS_MODULE@0..79 +0: JS_MODULE@0..128 0: (empty) 1: (empty) 2: JS_DIRECTIVE_LIST@0..0 - 3: JS_MODULE_ITEM_LIST@0..78 + 3: JS_MODULE_ITEM_LIST@0..127 0: JS_EXPRESSION_STATEMENT@0..8 0: JS_IMPORT_CALL_EXPRESSION@0..8 0: IMPORT_KW@0..6 "import" [] [] @@ -158,7 +205,39 @@ JsModule { 0: JS_STRING_LITERAL@72..77 "\"bar\"" [] [] 2: R_PAREN@77..78 ")" [] [] 1: (empty) - 4: EOF@78..79 "" [Newline("\n")] [] + 3: JS_EXPRESSION_STATEMENT@78..127 + 0: JS_IMPORT_CALL_EXPRESSION@78..127 + 0: IMPORT_KW@78..85 "import" [Newline("\n")] [] + 1: JS_CALL_ARGUMENTS@85..127 + 0: L_PAREN@85..86 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@86..126 + 0: JS_STRING_LITERAL_EXPRESSION@86..91 + 0: JS_STRING_LITERAL@86..91 "\"foo\"" [] [] + 1: COMMA@91..93 "," [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@93..119 + 0: L_CURLY@93..95 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@95..118 + 0: JS_PROPERTY_OBJECT_MEMBER@95..118 + 0: JS_LITERAL_MEMBER_NAME@95..99 + 0: IDENT@95..99 "with" [] [] + 1: COLON@99..101 ":" [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@101..118 + 0: L_CURLY@101..103 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@103..116 + 0: JS_PROPERTY_OBJECT_MEMBER@103..116 + 0: JS_LITERAL_MEMBER_NAME@103..107 + 0: IDENT@103..107 "type" [] [] + 1: COLON@107..109 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@109..116 + 0: JS_STRING_LITERAL@109..116 "'json'" [] [Whitespace(" ")] + 2: R_CURLY@116..118 "}" [] [Whitespace(" ")] + 2: R_CURLY@118..119 "}" [] [] + 3: COMMA@119..121 "," [] [Whitespace(" ")] + 4: JS_STRING_LITERAL_EXPRESSION@121..126 + 0: JS_STRING_LITERAL@121..126 "\"bar\"" [] [] + 2: R_PAREN@126..127 ")" [] [] + 1: (empty) + 4: EOF@127..128 "" [Newline("\n")] [] -- import_invalid_args.js:1:8 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -178,7 +257,7 @@ import_invalid_args.js:2:8 parse ━━━━━━━━━━━━━━━ > 2 │ import(...["foo"]) │ ^^^^^^^^^^ 3 │ import("foo", { assert: { type: 'json' } }, "bar") - 4 │ + 4 │ import("foo", { with: { type: 'json' } }, "bar") -- import_invalid_args.js:3:45 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -189,9 +268,22 @@ import_invalid_args.js:3:45 parse ━━━━━━━━━━━━━━━ 2 │ import(...["foo"]) > 3 │ import("foo", { assert: { type: 'json' } }, "bar") │ ^^^^^^ - 4 │ + 4 │ import("foo", { with: { type: 'json' } }, "bar") + 5 │ + +-- +import_invalid_args.js:4:43 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × `import()` requires exactly one or two arguments. + + 2 │ import(...["foo"]) + 3 │ import("foo", { assert: { type: 'json' } }, "bar") + > 4 │ import("foo", { with: { type: 'json' } }, "bar") + │ ^^^^^^ + 5 │ -- import() import(...["foo"]) import("foo", { assert: { type: 'json' } }, "bar") +import("foo", { with: { type: 'json' } }, "bar") diff --git a/crates/biome_js_parser/test_data/inline/ok/import_call.js b/crates/biome_js_parser/test_data/inline/ok/import_call.js index ab9eb6f2e9f5..53c9edfc642b 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_call.js +++ b/crates/biome_js_parser/test_data/inline/ok/import_call.js @@ -1,2 +1,3 @@ import("foo") import("foo", { assert: { type: 'json' } }) +import("foo", { with: { 'resolution-mode': 'import' } }) diff --git a/crates/biome_js_parser/test_data/inline/ok/import_call.rast b/crates/biome_js_parser/test_data/inline/ok/import_call.rast index 78b50882738d..34a97d619a80 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_call.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_call.rast @@ -61,15 +61,58 @@ JsModule { }, semicolon_token: missing (optional), }, + JsExpressionStatement { + expression: JsImportCallExpression { + import_token: IMPORT_KW@57..64 "import" [Newline("\n")] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@64..65 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@65..70 "\"foo\"" [] [], + }, + COMMA@70..72 "," [] [Whitespace(" ")], + JsObjectExpression { + l_curly_token: L_CURLY@72..74 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@74..78 "with" [] [], + }, + colon_token: COLON@78..80 ":" [] [Whitespace(" ")], + value: JsObjectExpression { + l_curly_token: L_CURLY@80..82 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: JS_STRING_LITERAL@82..99 "'resolution-mode'" [] [], + }, + colon_token: COLON@99..101 ":" [] [Whitespace(" ")], + value: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@101..110 "'import'" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@110..112 "}" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@112..113 "}" [] [], + }, + ], + r_paren_token: R_PAREN@113..114 ")" [] [], + }, + }, + semicolon_token: missing (optional), + }, ], - eof_token: EOF@57..58 "" [Newline("\n")] [], + eof_token: EOF@114..115 "" [Newline("\n")] [], } -0: JS_MODULE@0..58 +0: JS_MODULE@0..115 0: (empty) 1: (empty) 2: JS_DIRECTIVE_LIST@0..0 - 3: JS_MODULE_ITEM_LIST@0..57 + 3: JS_MODULE_ITEM_LIST@0..114 0: JS_EXPRESSION_STATEMENT@0..13 0: JS_IMPORT_CALL_EXPRESSION@0..13 0: IMPORT_KW@0..6 "import" [] [] @@ -109,4 +152,33 @@ JsModule { 2: R_CURLY@55..56 "}" [] [] 2: R_PAREN@56..57 ")" [] [] 1: (empty) - 4: EOF@57..58 "" [Newline("\n")] [] + 2: JS_EXPRESSION_STATEMENT@57..114 + 0: JS_IMPORT_CALL_EXPRESSION@57..114 + 0: IMPORT_KW@57..64 "import" [Newline("\n")] [] + 1: JS_CALL_ARGUMENTS@64..114 + 0: L_PAREN@64..65 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@65..113 + 0: JS_STRING_LITERAL_EXPRESSION@65..70 + 0: JS_STRING_LITERAL@65..70 "\"foo\"" [] [] + 1: COMMA@70..72 "," [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@72..113 + 0: L_CURLY@72..74 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@74..112 + 0: JS_PROPERTY_OBJECT_MEMBER@74..112 + 0: JS_LITERAL_MEMBER_NAME@74..78 + 0: IDENT@74..78 "with" [] [] + 1: COLON@78..80 ":" [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@80..112 + 0: L_CURLY@80..82 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@82..110 + 0: JS_PROPERTY_OBJECT_MEMBER@82..110 + 0: JS_LITERAL_MEMBER_NAME@82..99 + 0: JS_STRING_LITERAL@82..99 "'resolution-mode'" [] [] + 1: COLON@99..101 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@101..110 + 0: JS_STRING_LITERAL@101..110 "'import'" [] [Whitespace(" ")] + 2: R_CURLY@110..112 "}" [] [Whitespace(" ")] + 2: R_CURLY@112..113 "}" [] [] + 2: R_PAREN@113..114 ")" [] [] + 1: (empty) + 4: EOF@114..115 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/ts_import_type.rast b/crates/biome_js_parser/test_data/inline/ok/ts_import_type.rast index cfe35dbd8440..60845a8cf015 100644 --- a/crates/biome_js_parser/test_data/inline/ok/ts_import_type.rast +++ b/crates/biome_js_parser/test_data/inline/ok/ts_import_type.rast @@ -13,9 +13,15 @@ JsModule { ty: TsImportType { typeof_token: TYPEOF_KW@9..16 "typeof" [] [Whitespace(" ")], import_token: IMPORT_KW@16..22 "import" [] [], - l_paren_token: L_PAREN@22..23 "(" [] [], - argument_token: JS_STRING_LITERAL@23..29 "\"test\"" [] [], - r_paren_token: R_PAREN@29..30 ")" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@22..23 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@23..29 "\"test\"" [] [], + }, + ], + r_paren_token: R_PAREN@29..30 ")" [] [], + }, qualifier_clause: missing (optional), type_arguments: missing (optional), }, @@ -31,9 +37,15 @@ JsModule { ty: TsImportType { typeof_token: missing (optional), import_token: IMPORT_KW@41..47 "import" [] [], - l_paren_token: L_PAREN@47..48 "(" [] [], - argument_token: JS_STRING_LITERAL@48..54 "\"test\"" [] [], - r_paren_token: R_PAREN@54..55 ")" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@47..48 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@48..54 "\"test\"" [] [], + }, + ], + r_paren_token: R_PAREN@54..55 ")" [] [], + }, qualifier_clause: missing (optional), type_arguments: missing (optional), }, @@ -49,9 +61,15 @@ JsModule { ty: TsImportType { typeof_token: TYPEOF_KW@66..73 "typeof" [] [Whitespace(" ")], import_token: IMPORT_KW@73..79 "import" [] [], - l_paren_token: L_PAREN@79..80 "(" [] [], - argument_token: JS_STRING_LITERAL@80..86 "\"test\"" [] [], - r_paren_token: R_PAREN@86..87 ")" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@79..80 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@80..86 "\"test\"" [] [], + }, + ], + r_paren_token: R_PAREN@86..87 ")" [] [], + }, qualifier_clause: TsImportTypeQualifier { dot_token: DOT@87..88 "." [] [], right: TsQualifiedName { @@ -102,9 +120,15 @@ JsModule { ty: TsImportType { typeof_token: missing (optional), import_token: IMPORT_KW@110..116 "import" [] [], - l_paren_token: L_PAREN@116..117 "(" [] [], - argument_token: JS_STRING_LITERAL@117..123 "\"test\"" [] [], - r_paren_token: R_PAREN@123..124 ")" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@116..117 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@117..123 "\"test\"" [] [], + }, + ], + r_paren_token: R_PAREN@123..124 ")" [] [], + }, qualifier_clause: missing (optional), type_arguments: TsTypeArguments { l_angle_token: L_ANGLE@124..125 "<" [] [], @@ -128,9 +152,15 @@ JsModule { ty: TsImportType { typeof_token: missing (optional), import_token: IMPORT_KW@143..149 "import" [] [], - l_paren_token: L_PAREN@149..150 "(" [] [], - argument_token: JS_STRING_LITERAL@150..156 "\"test\"" [] [], - r_paren_token: R_PAREN@156..157 ")" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@149..150 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@150..156 "\"test\"" [] [], + }, + ], + r_paren_token: R_PAREN@156..157 ")" [] [], + }, qualifier_clause: TsImportTypeQualifier { dot_token: DOT@157..158 "." [] [], right: JsReferenceIdentifier { @@ -149,15 +179,336 @@ JsModule { }, semicolon_token: SEMICOLON@167..168 ";" [] [], }, + TsTypeAliasDeclaration { + type_token: TYPE_KW@168..174 "type" [Newline("\n")] [Whitespace(" ")], + binding_identifier: TsIdentifierBinding { + name_token: IDENT@174..176 "F" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + eq_token: EQ@176..178 "=" [] [Whitespace(" ")], + ty: TsImportType { + typeof_token: TYPEOF_KW@178..185 "typeof" [] [Whitespace(" ")], + import_token: IMPORT_KW@185..191 "import" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@191..192 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@192..198 "\"test\"" [] [], + }, + COMMA@198..200 "," [] [Whitespace(" ")], + JsObjectExpression { + l_curly_token: L_CURLY@200..202 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@202..206 "with" [] [], + }, + colon_token: COLON@206..208 ":" [] [Whitespace(" ")], + value: JsObjectExpression { + l_curly_token: L_CURLY@208..210 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: JS_STRING_LITERAL@210..227 "\"resolution-mode\"" [] [], + }, + colon_token: COLON@227..229 ":" [] [Whitespace(" ")], + value: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@229..238 "\"import\"" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@238..240 "}" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@240..241 "}" [] [], + }, + ], + r_paren_token: R_PAREN@241..242 ")" [] [], + }, + qualifier_clause: missing (optional), + type_arguments: missing (optional), + }, + semicolon_token: SEMICOLON@242..243 ";" [] [], + }, + TsTypeAliasDeclaration { + type_token: TYPE_KW@243..249 "type" [Newline("\n")] [Whitespace(" ")], + binding_identifier: TsIdentifierBinding { + name_token: IDENT@249..251 "G" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + eq_token: EQ@251..253 "=" [] [Whitespace(" ")], + ty: TsImportType { + typeof_token: missing (optional), + import_token: IMPORT_KW@253..259 "import" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@259..260 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@260..266 "\"test\"" [] [], + }, + COMMA@266..268 "," [] [Whitespace(" ")], + JsObjectExpression { + l_curly_token: L_CURLY@268..270 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@270..274 "with" [] [], + }, + colon_token: COLON@274..276 ":" [] [Whitespace(" ")], + value: JsObjectExpression { + l_curly_token: L_CURLY@276..278 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: JS_STRING_LITERAL@278..295 "\"resolution-mode\"" [] [], + }, + colon_token: COLON@295..297 ":" [] [Whitespace(" ")], + value: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@297..306 "\"import\"" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@306..308 "}" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@308..309 "}" [] [], + }, + ], + r_paren_token: R_PAREN@309..310 ")" [] [], + }, + qualifier_clause: TsImportTypeQualifier { + dot_token: DOT@310..311 "." [] [], + right: JsReferenceIdentifier { + value_token: IDENT@311..325 "TypeFromImport" [] [], + }, + }, + type_arguments: missing (optional), + }, + semicolon_token: SEMICOLON@325..326 ";" [] [], + }, + TsTypeAliasDeclaration { + type_token: TYPE_KW@326..332 "type" [Newline("\n")] [Whitespace(" ")], + binding_identifier: TsIdentifierBinding { + name_token: IDENT@332..334 "H" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + eq_token: EQ@334..336 "=" [] [Whitespace(" ")], + ty: TsImportType { + typeof_token: missing (optional), + import_token: IMPORT_KW@336..342 "import" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@342..343 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@343..349 "\"test\"" [] [], + }, + COMMA@349..351 "," [] [Whitespace(" ")], + JsObjectExpression { + l_curly_token: L_CURLY@351..353 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@353..357 "with" [] [], + }, + colon_token: COLON@357..359 ":" [] [Whitespace(" ")], + value: JsObjectExpression { + l_curly_token: L_CURLY@359..361 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: JS_STRING_LITERAL@361..378 "\"resolution-mode\"" [] [], + }, + colon_token: COLON@378..380 ":" [] [Whitespace(" ")], + value: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@380..389 "\"import\"" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@389..391 "}" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@391..392 "}" [] [], + }, + ], + r_paren_token: R_PAREN@392..393 ")" [] [], + }, + qualifier_clause: missing (optional), + type_arguments: TsTypeArguments { + l_angle_token: L_ANGLE@393..394 "<" [] [], + ts_type_argument_list: TsTypeArgumentList [ + TsStringType { + string_token: STRING_KW@394..400 "string" [] [], + }, + ], + r_angle_token: R_ANGLE@400..401 ">" [] [], + }, + }, + semicolon_token: SEMICOLON@401..402 ";" [] [], + }, + TsTypeAliasDeclaration { + type_token: TYPE_KW@402..408 "type" [Newline("\n")] [Whitespace(" ")], + binding_identifier: TsIdentifierBinding { + name_token: IDENT@408..410 "I" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + eq_token: EQ@410..412 "=" [] [Whitespace(" ")], + ty: TsImportType { + typeof_token: missing (optional), + import_token: IMPORT_KW@412..418 "import" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@418..419 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@419..425 "\"test\"" [] [], + }, + COMMA@425..427 "," [] [Whitespace(" ")], + JsObjectExpression { + l_curly_token: L_CURLY@427..429 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@429..433 "with" [] [], + }, + colon_token: COLON@433..435 ":" [] [Whitespace(" ")], + value: JsObjectExpression { + l_curly_token: L_CURLY@435..437 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: JS_STRING_LITERAL@437..454 "\"resolution-mode\"" [] [], + }, + colon_token: COLON@454..456 ":" [] [Whitespace(" ")], + value: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@456..466 "\"require\"" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@466..468 "}" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@468..469 "}" [] [], + }, + ], + r_paren_token: R_PAREN@469..470 ")" [] [], + }, + qualifier_clause: TsImportTypeQualifier { + dot_token: DOT@470..471 "." [] [], + right: JsReferenceIdentifier { + value_token: IDENT@471..472 "C" [] [], + }, + }, + type_arguments: TsTypeArguments { + l_angle_token: L_ANGLE@472..473 "<" [] [], + ts_type_argument_list: TsTypeArgumentList [ + TsStringType { + string_token: STRING_KW@473..479 "string" [] [], + }, + ], + r_angle_token: R_ANGLE@479..480 ">" [] [], + }, + }, + semicolon_token: SEMICOLON@480..481 ";" [] [], + }, + TsTypeAliasDeclaration { + type_token: TYPE_KW@481..487 "type" [Newline("\n")] [Whitespace(" ")], + binding_identifier: TsIdentifierBinding { + name_token: IDENT@487..489 "J" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + eq_token: EQ@489..491 "=" [] [Whitespace(" ")], + ty: TsImportType { + typeof_token: TYPEOF_KW@491..498 "typeof" [] [Whitespace(" ")], + import_token: IMPORT_KW@498..504 "import" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@504..505 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@505..511 "\"test\"" [] [], + }, + COMMA@511..513 "," [] [Whitespace(" ")], + JsObjectExpression { + l_curly_token: L_CURLY@513..515 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: IDENT@515..519 "with" [] [], + }, + colon_token: COLON@519..521 ":" [] [Whitespace(" ")], + value: JsObjectExpression { + l_curly_token: L_CURLY@521..523 "{" [] [Whitespace(" ")], + members: JsObjectMemberList [ + JsPropertyObjectMember { + name: JsLiteralMemberName { + value: JS_STRING_LITERAL@523..540 "\"resolution-mode\"" [] [], + }, + colon_token: COLON@540..542 ":" [] [Whitespace(" ")], + value: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@542..552 "\"require\"" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@552..554 "}" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@554..555 "}" [] [], + }, + ], + r_paren_token: R_PAREN@555..556 ")" [] [], + }, + qualifier_clause: TsImportTypeQualifier { + dot_token: DOT@556..557 "." [] [], + right: TsQualifiedName { + left: TsQualifiedName { + left: TsQualifiedName { + left: TsQualifiedName { + left: TsQualifiedName { + left: JsReferenceIdentifier { + value_token: IDENT@557..558 "a" [] [], + }, + dot_token: DOT@558..559 "." [] [], + right: JsName { + value_token: IDENT@559..560 "b" [] [], + }, + }, + dot_token: DOT@560..561 "." [] [], + right: JsName { + value_token: IDENT@561..562 "c" [] [], + }, + }, + dot_token: DOT@562..563 "." [] [], + right: JsName { + value_token: IDENT@563..564 "d" [] [], + }, + }, + dot_token: DOT@564..565 "." [] [], + right: JsName { + value_token: IDENT@565..566 "e" [] [], + }, + }, + dot_token: DOT@566..567 "." [] [], + right: JsName { + value_token: IDENT@567..568 "f" [] [], + }, + }, + }, + type_arguments: missing (optional), + }, + semicolon_token: SEMICOLON@568..569 ";" [] [], + }, ], - eof_token: EOF@168..169 "" [Newline("\n")] [], + eof_token: EOF@569..570 "" [Newline("\n")] [], } -0: JS_MODULE@0..169 +0: JS_MODULE@0..570 0: (empty) 1: (empty) 2: JS_DIRECTIVE_LIST@0..0 - 3: JS_MODULE_ITEM_LIST@0..168 + 3: JS_MODULE_ITEM_LIST@0..569 0: TS_TYPE_ALIAS_DECLARATION@0..31 0: TYPE_KW@0..5 "type" [] [Whitespace(" ")] 1: TS_IDENTIFIER_BINDING@5..7 @@ -167,11 +518,14 @@ JsModule { 4: TS_IMPORT_TYPE@9..30 0: TYPEOF_KW@9..16 "typeof" [] [Whitespace(" ")] 1: IMPORT_KW@16..22 "import" [] [] - 2: L_PAREN@22..23 "(" [] [] - 3: JS_STRING_LITERAL@23..29 "\"test\"" [] [] - 4: R_PAREN@29..30 ")" [] [] - 5: (empty) - 6: (empty) + 2: JS_CALL_ARGUMENTS@22..30 + 0: L_PAREN@22..23 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@23..29 + 0: JS_STRING_LITERAL_EXPRESSION@23..29 + 0: JS_STRING_LITERAL@23..29 "\"test\"" [] [] + 2: R_PAREN@29..30 ")" [] [] + 3: (empty) + 4: (empty) 5: SEMICOLON@30..31 ";" [] [] 1: TS_TYPE_ALIAS_DECLARATION@31..56 0: TYPE_KW@31..37 "type" [Newline("\n")] [Whitespace(" ")] @@ -182,11 +536,14 @@ JsModule { 4: TS_IMPORT_TYPE@41..55 0: (empty) 1: IMPORT_KW@41..47 "import" [] [] - 2: L_PAREN@47..48 "(" [] [] - 3: JS_STRING_LITERAL@48..54 "\"test\"" [] [] - 4: R_PAREN@54..55 ")" [] [] - 5: (empty) - 6: (empty) + 2: JS_CALL_ARGUMENTS@47..55 + 0: L_PAREN@47..48 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@48..54 + 0: JS_STRING_LITERAL_EXPRESSION@48..54 + 0: JS_STRING_LITERAL@48..54 "\"test\"" [] [] + 2: R_PAREN@54..55 ")" [] [] + 3: (empty) + 4: (empty) 5: SEMICOLON@55..56 ";" [] [] 2: TS_TYPE_ALIAS_DECLARATION@56..100 0: TYPE_KW@56..62 "type" [Newline("\n")] [Whitespace(" ")] @@ -197,10 +554,13 @@ JsModule { 4: TS_IMPORT_TYPE@66..99 0: TYPEOF_KW@66..73 "typeof" [] [Whitespace(" ")] 1: IMPORT_KW@73..79 "import" [] [] - 2: L_PAREN@79..80 "(" [] [] - 3: JS_STRING_LITERAL@80..86 "\"test\"" [] [] - 4: R_PAREN@86..87 ")" [] [] - 5: TS_IMPORT_TYPE_QUALIFIER@87..99 + 2: JS_CALL_ARGUMENTS@79..87 + 0: L_PAREN@79..80 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@80..86 + 0: JS_STRING_LITERAL_EXPRESSION@80..86 + 0: JS_STRING_LITERAL@80..86 "\"test\"" [] [] + 2: R_PAREN@86..87 ")" [] [] + 3: TS_IMPORT_TYPE_QUALIFIER@87..99 0: DOT@87..88 "." [] [] 1: TS_QUALIFIED_NAME@88..99 0: TS_QUALIFIED_NAME@88..97 @@ -224,7 +584,7 @@ JsModule { 1: DOT@97..98 "." [] [] 2: JS_NAME@98..99 0: IDENT@98..99 "f" [] [] - 6: (empty) + 4: (empty) 5: SEMICOLON@99..100 ";" [] [] 3: TS_TYPE_ALIAS_DECLARATION@100..133 0: TYPE_KW@100..106 "type" [Newline("\n")] [Whitespace(" ")] @@ -235,11 +595,14 @@ JsModule { 4: TS_IMPORT_TYPE@110..132 0: (empty) 1: IMPORT_KW@110..116 "import" [] [] - 2: L_PAREN@116..117 "(" [] [] - 3: JS_STRING_LITERAL@117..123 "\"test\"" [] [] - 4: R_PAREN@123..124 ")" [] [] - 5: (empty) - 6: TS_TYPE_ARGUMENTS@124..132 + 2: JS_CALL_ARGUMENTS@116..124 + 0: L_PAREN@116..117 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@117..123 + 0: JS_STRING_LITERAL_EXPRESSION@117..123 + 0: JS_STRING_LITERAL@117..123 "\"test\"" [] [] + 2: R_PAREN@123..124 ")" [] [] + 3: (empty) + 4: TS_TYPE_ARGUMENTS@124..132 0: L_ANGLE@124..125 "<" [] [] 1: TS_TYPE_ARGUMENT_LIST@125..131 0: TS_STRING_TYPE@125..131 @@ -255,18 +618,245 @@ JsModule { 4: TS_IMPORT_TYPE@143..167 0: (empty) 1: IMPORT_KW@143..149 "import" [] [] - 2: L_PAREN@149..150 "(" [] [] - 3: JS_STRING_LITERAL@150..156 "\"test\"" [] [] - 4: R_PAREN@156..157 ")" [] [] - 5: TS_IMPORT_TYPE_QUALIFIER@157..159 + 2: JS_CALL_ARGUMENTS@149..157 + 0: L_PAREN@149..150 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@150..156 + 0: JS_STRING_LITERAL_EXPRESSION@150..156 + 0: JS_STRING_LITERAL@150..156 "\"test\"" [] [] + 2: R_PAREN@156..157 ")" [] [] + 3: TS_IMPORT_TYPE_QUALIFIER@157..159 0: DOT@157..158 "." [] [] 1: JS_REFERENCE_IDENTIFIER@158..159 0: IDENT@158..159 "C" [] [] - 6: TS_TYPE_ARGUMENTS@159..167 + 4: TS_TYPE_ARGUMENTS@159..167 0: L_ANGLE@159..160 "<" [] [] 1: TS_TYPE_ARGUMENT_LIST@160..166 0: TS_STRING_TYPE@160..166 0: STRING_KW@160..166 "string" [] [] 2: R_ANGLE@166..167 ">" [] [] 5: SEMICOLON@167..168 ";" [] [] - 4: EOF@168..169 "" [Newline("\n")] [] + 5: TS_TYPE_ALIAS_DECLARATION@168..243 + 0: TYPE_KW@168..174 "type" [Newline("\n")] [Whitespace(" ")] + 1: TS_IDENTIFIER_BINDING@174..176 + 0: IDENT@174..176 "F" [] [Whitespace(" ")] + 2: (empty) + 3: EQ@176..178 "=" [] [Whitespace(" ")] + 4: TS_IMPORT_TYPE@178..242 + 0: TYPEOF_KW@178..185 "typeof" [] [Whitespace(" ")] + 1: IMPORT_KW@185..191 "import" [] [] + 2: JS_CALL_ARGUMENTS@191..242 + 0: L_PAREN@191..192 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@192..241 + 0: JS_STRING_LITERAL_EXPRESSION@192..198 + 0: JS_STRING_LITERAL@192..198 "\"test\"" [] [] + 1: COMMA@198..200 "," [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@200..241 + 0: L_CURLY@200..202 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@202..240 + 0: JS_PROPERTY_OBJECT_MEMBER@202..240 + 0: JS_LITERAL_MEMBER_NAME@202..206 + 0: IDENT@202..206 "with" [] [] + 1: COLON@206..208 ":" [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@208..240 + 0: L_CURLY@208..210 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@210..238 + 0: JS_PROPERTY_OBJECT_MEMBER@210..238 + 0: JS_LITERAL_MEMBER_NAME@210..227 + 0: JS_STRING_LITERAL@210..227 "\"resolution-mode\"" [] [] + 1: COLON@227..229 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@229..238 + 0: JS_STRING_LITERAL@229..238 "\"import\"" [] [Whitespace(" ")] + 2: R_CURLY@238..240 "}" [] [Whitespace(" ")] + 2: R_CURLY@240..241 "}" [] [] + 2: R_PAREN@241..242 ")" [] [] + 3: (empty) + 4: (empty) + 5: SEMICOLON@242..243 ";" [] [] + 6: TS_TYPE_ALIAS_DECLARATION@243..326 + 0: TYPE_KW@243..249 "type" [Newline("\n")] [Whitespace(" ")] + 1: TS_IDENTIFIER_BINDING@249..251 + 0: IDENT@249..251 "G" [] [Whitespace(" ")] + 2: (empty) + 3: EQ@251..253 "=" [] [Whitespace(" ")] + 4: TS_IMPORT_TYPE@253..325 + 0: (empty) + 1: IMPORT_KW@253..259 "import" [] [] + 2: JS_CALL_ARGUMENTS@259..310 + 0: L_PAREN@259..260 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@260..309 + 0: JS_STRING_LITERAL_EXPRESSION@260..266 + 0: JS_STRING_LITERAL@260..266 "\"test\"" [] [] + 1: COMMA@266..268 "," [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@268..309 + 0: L_CURLY@268..270 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@270..308 + 0: JS_PROPERTY_OBJECT_MEMBER@270..308 + 0: JS_LITERAL_MEMBER_NAME@270..274 + 0: IDENT@270..274 "with" [] [] + 1: COLON@274..276 ":" [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@276..308 + 0: L_CURLY@276..278 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@278..306 + 0: JS_PROPERTY_OBJECT_MEMBER@278..306 + 0: JS_LITERAL_MEMBER_NAME@278..295 + 0: JS_STRING_LITERAL@278..295 "\"resolution-mode\"" [] [] + 1: COLON@295..297 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@297..306 + 0: JS_STRING_LITERAL@297..306 "\"import\"" [] [Whitespace(" ")] + 2: R_CURLY@306..308 "}" [] [Whitespace(" ")] + 2: R_CURLY@308..309 "}" [] [] + 2: R_PAREN@309..310 ")" [] [] + 3: TS_IMPORT_TYPE_QUALIFIER@310..325 + 0: DOT@310..311 "." [] [] + 1: JS_REFERENCE_IDENTIFIER@311..325 + 0: IDENT@311..325 "TypeFromImport" [] [] + 4: (empty) + 5: SEMICOLON@325..326 ";" [] [] + 7: TS_TYPE_ALIAS_DECLARATION@326..402 + 0: TYPE_KW@326..332 "type" [Newline("\n")] [Whitespace(" ")] + 1: TS_IDENTIFIER_BINDING@332..334 + 0: IDENT@332..334 "H" [] [Whitespace(" ")] + 2: (empty) + 3: EQ@334..336 "=" [] [Whitespace(" ")] + 4: TS_IMPORT_TYPE@336..401 + 0: (empty) + 1: IMPORT_KW@336..342 "import" [] [] + 2: JS_CALL_ARGUMENTS@342..393 + 0: L_PAREN@342..343 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@343..392 + 0: JS_STRING_LITERAL_EXPRESSION@343..349 + 0: JS_STRING_LITERAL@343..349 "\"test\"" [] [] + 1: COMMA@349..351 "," [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@351..392 + 0: L_CURLY@351..353 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@353..391 + 0: JS_PROPERTY_OBJECT_MEMBER@353..391 + 0: JS_LITERAL_MEMBER_NAME@353..357 + 0: IDENT@353..357 "with" [] [] + 1: COLON@357..359 ":" [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@359..391 + 0: L_CURLY@359..361 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@361..389 + 0: JS_PROPERTY_OBJECT_MEMBER@361..389 + 0: JS_LITERAL_MEMBER_NAME@361..378 + 0: JS_STRING_LITERAL@361..378 "\"resolution-mode\"" [] [] + 1: COLON@378..380 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@380..389 + 0: JS_STRING_LITERAL@380..389 "\"import\"" [] [Whitespace(" ")] + 2: R_CURLY@389..391 "}" [] [Whitespace(" ")] + 2: R_CURLY@391..392 "}" [] [] + 2: R_PAREN@392..393 ")" [] [] + 3: (empty) + 4: TS_TYPE_ARGUMENTS@393..401 + 0: L_ANGLE@393..394 "<" [] [] + 1: TS_TYPE_ARGUMENT_LIST@394..400 + 0: TS_STRING_TYPE@394..400 + 0: STRING_KW@394..400 "string" [] [] + 2: R_ANGLE@400..401 ">" [] [] + 5: SEMICOLON@401..402 ";" [] [] + 8: TS_TYPE_ALIAS_DECLARATION@402..481 + 0: TYPE_KW@402..408 "type" [Newline("\n")] [Whitespace(" ")] + 1: TS_IDENTIFIER_BINDING@408..410 + 0: IDENT@408..410 "I" [] [Whitespace(" ")] + 2: (empty) + 3: EQ@410..412 "=" [] [Whitespace(" ")] + 4: TS_IMPORT_TYPE@412..480 + 0: (empty) + 1: IMPORT_KW@412..418 "import" [] [] + 2: JS_CALL_ARGUMENTS@418..470 + 0: L_PAREN@418..419 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@419..469 + 0: JS_STRING_LITERAL_EXPRESSION@419..425 + 0: JS_STRING_LITERAL@419..425 "\"test\"" [] [] + 1: COMMA@425..427 "," [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@427..469 + 0: L_CURLY@427..429 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@429..468 + 0: JS_PROPERTY_OBJECT_MEMBER@429..468 + 0: JS_LITERAL_MEMBER_NAME@429..433 + 0: IDENT@429..433 "with" [] [] + 1: COLON@433..435 ":" [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@435..468 + 0: L_CURLY@435..437 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@437..466 + 0: JS_PROPERTY_OBJECT_MEMBER@437..466 + 0: JS_LITERAL_MEMBER_NAME@437..454 + 0: JS_STRING_LITERAL@437..454 "\"resolution-mode\"" [] [] + 1: COLON@454..456 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@456..466 + 0: JS_STRING_LITERAL@456..466 "\"require\"" [] [Whitespace(" ")] + 2: R_CURLY@466..468 "}" [] [Whitespace(" ")] + 2: R_CURLY@468..469 "}" [] [] + 2: R_PAREN@469..470 ")" [] [] + 3: TS_IMPORT_TYPE_QUALIFIER@470..472 + 0: DOT@470..471 "." [] [] + 1: JS_REFERENCE_IDENTIFIER@471..472 + 0: IDENT@471..472 "C" [] [] + 4: TS_TYPE_ARGUMENTS@472..480 + 0: L_ANGLE@472..473 "<" [] [] + 1: TS_TYPE_ARGUMENT_LIST@473..479 + 0: TS_STRING_TYPE@473..479 + 0: STRING_KW@473..479 "string" [] [] + 2: R_ANGLE@479..480 ">" [] [] + 5: SEMICOLON@480..481 ";" [] [] + 9: TS_TYPE_ALIAS_DECLARATION@481..569 + 0: TYPE_KW@481..487 "type" [Newline("\n")] [Whitespace(" ")] + 1: TS_IDENTIFIER_BINDING@487..489 + 0: IDENT@487..489 "J" [] [Whitespace(" ")] + 2: (empty) + 3: EQ@489..491 "=" [] [Whitespace(" ")] + 4: TS_IMPORT_TYPE@491..568 + 0: TYPEOF_KW@491..498 "typeof" [] [Whitespace(" ")] + 1: IMPORT_KW@498..504 "import" [] [] + 2: JS_CALL_ARGUMENTS@504..556 + 0: L_PAREN@504..505 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@505..555 + 0: JS_STRING_LITERAL_EXPRESSION@505..511 + 0: JS_STRING_LITERAL@505..511 "\"test\"" [] [] + 1: COMMA@511..513 "," [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@513..555 + 0: L_CURLY@513..515 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@515..554 + 0: JS_PROPERTY_OBJECT_MEMBER@515..554 + 0: JS_LITERAL_MEMBER_NAME@515..519 + 0: IDENT@515..519 "with" [] [] + 1: COLON@519..521 ":" [] [Whitespace(" ")] + 2: JS_OBJECT_EXPRESSION@521..554 + 0: L_CURLY@521..523 "{" [] [Whitespace(" ")] + 1: JS_OBJECT_MEMBER_LIST@523..552 + 0: JS_PROPERTY_OBJECT_MEMBER@523..552 + 0: JS_LITERAL_MEMBER_NAME@523..540 + 0: JS_STRING_LITERAL@523..540 "\"resolution-mode\"" [] [] + 1: COLON@540..542 ":" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@542..552 + 0: JS_STRING_LITERAL@542..552 "\"require\"" [] [Whitespace(" ")] + 2: R_CURLY@552..554 "}" [] [Whitespace(" ")] + 2: R_CURLY@554..555 "}" [] [] + 2: R_PAREN@555..556 ")" [] [] + 3: TS_IMPORT_TYPE_QUALIFIER@556..568 + 0: DOT@556..557 "." [] [] + 1: TS_QUALIFIED_NAME@557..568 + 0: TS_QUALIFIED_NAME@557..566 + 0: TS_QUALIFIED_NAME@557..564 + 0: TS_QUALIFIED_NAME@557..562 + 0: TS_QUALIFIED_NAME@557..560 + 0: JS_REFERENCE_IDENTIFIER@557..558 + 0: IDENT@557..558 "a" [] [] + 1: DOT@558..559 "." [] [] + 2: JS_NAME@559..560 + 0: IDENT@559..560 "b" [] [] + 1: DOT@560..561 "." [] [] + 2: JS_NAME@561..562 + 0: IDENT@561..562 "c" [] [] + 1: DOT@562..563 "." [] [] + 2: JS_NAME@563..564 + 0: IDENT@563..564 "d" [] [] + 1: DOT@564..565 "." [] [] + 2: JS_NAME@565..566 + 0: IDENT@565..566 "e" [] [] + 1: DOT@566..567 "." [] [] + 2: JS_NAME@567..568 + 0: IDENT@567..568 "f" [] [] + 4: (empty) + 5: SEMICOLON@568..569 ";" [] [] + 4: EOF@569..570 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/ts_import_type.ts b/crates/biome_js_parser/test_data/inline/ok/ts_import_type.ts index 30b2fd7e790d..315dab874217 100644 --- a/crates/biome_js_parser/test_data/inline/ok/ts_import_type.ts +++ b/crates/biome_js_parser/test_data/inline/ok/ts_import_type.ts @@ -3,3 +3,8 @@ type B = import("test"); type C = typeof import("test").a.b.c.d.e.f; type D = import("test"); type E = import("test").C; +type F = typeof import("test", { with: { "resolution-mode": "import" } }); +type G = import("test", { with: { "resolution-mode": "import" } }).TypeFromImport; +type H = import("test", { with: { "resolution-mode": "import" } }); +type I = import("test", { with: { "resolution-mode": "require" } }).C; +type J = typeof import("test", { with: { "resolution-mode": "require" } }).a.b.c.d.e.f; diff --git a/crates/biome_js_parser/test_data/inline/ok/ts_infer_type_allowed.rast b/crates/biome_js_parser/test_data/inline/ok/ts_infer_type_allowed.rast index 018542ccc553..5511ba943583 100644 --- a/crates/biome_js_parser/test_data/inline/ok/ts_infer_type_allowed.rast +++ b/crates/biome_js_parser/test_data/inline/ok/ts_infer_type_allowed.rast @@ -93,9 +93,15 @@ JsModule { extends_type: TsImportType { typeof_token: missing (optional), import_token: IMPORT_KW@84..90 "import" [] [], - l_paren_token: L_PAREN@90..91 "(" [] [], - argument_token: JS_STRING_LITERAL@91..97 "\"test\"" [] [], - r_paren_token: R_PAREN@97..98 ")" [] [], + arguments: JsCallArguments { + l_paren_token: L_PAREN@90..91 "(" [] [], + args: JsCallArgumentList [ + JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@91..97 "\"test\"" [] [], + }, + ], + r_paren_token: R_PAREN@97..98 ")" [] [], + }, qualifier_clause: TsImportTypeQualifier { dot_token: DOT@98..99 "." [] [], right: JsReferenceIdentifier { @@ -3122,14 +3128,17 @@ JsModule { 2: TS_IMPORT_TYPE@84..110 0: (empty) 1: IMPORT_KW@84..90 "import" [] [] - 2: L_PAREN@90..91 "(" [] [] - 3: JS_STRING_LITERAL@91..97 "\"test\"" [] [] - 4: R_PAREN@97..98 ")" [] [] - 5: TS_IMPORT_TYPE_QUALIFIER@98..100 + 2: JS_CALL_ARGUMENTS@90..98 + 0: L_PAREN@90..91 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@91..97 + 0: JS_STRING_LITERAL_EXPRESSION@91..97 + 0: JS_STRING_LITERAL@91..97 "\"test\"" [] [] + 2: R_PAREN@97..98 ")" [] [] + 3: TS_IMPORT_TYPE_QUALIFIER@98..100 0: DOT@98..99 "." [] [] 1: JS_REFERENCE_IDENTIFIER@99..100 0: IDENT@99..100 "C" [] [] - 6: TS_TYPE_ARGUMENTS@100..110 + 4: TS_TYPE_ARGUMENTS@100..110 0: L_ANGLE@100..101 "<" [] [] 1: TS_TYPE_ARGUMENT_LIST@101..108 0: TS_INFER_TYPE@101..108 diff --git a/crates/biome_js_syntax/src/generated/nodes.rs b/crates/biome_js_syntax/src/generated/nodes.rs index 1472a013c63b..4851f0c32239 100644 --- a/crates/biome_js_syntax/src/generated/nodes.rs +++ b/crates/biome_js_syntax/src/generated/nodes.rs @@ -9942,9 +9942,7 @@ impl TsImportType { TsImportTypeFields { typeof_token: self.typeof_token(), import_token: self.import_token(), - l_paren_token: self.l_paren_token(), - argument_token: self.argument_token(), - r_paren_token: self.r_paren_token(), + arguments: self.arguments(), qualifier_clause: self.qualifier_clause(), type_arguments: self.type_arguments(), } @@ -9955,20 +9953,14 @@ impl TsImportType { pub fn import_token(&self) -> SyntaxResult { support::required_token(&self.syntax, 1usize) } - pub fn l_paren_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 2usize) - } - pub fn argument_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 3usize) - } - pub fn r_paren_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 4usize) + pub fn arguments(&self) -> SyntaxResult { + support::required_node(&self.syntax, 2usize) } pub fn qualifier_clause(&self) -> Option { - support::node(&self.syntax, 5usize) + support::node(&self.syntax, 3usize) } pub fn type_arguments(&self) -> Option { - support::node(&self.syntax, 6usize) + support::node(&self.syntax, 4usize) } } impl Serialize for TsImportType { @@ -9983,9 +9975,7 @@ impl Serialize for TsImportType { pub struct TsImportTypeFields { pub typeof_token: Option, pub import_token: SyntaxResult, - pub l_paren_token: SyntaxResult, - pub argument_token: SyntaxResult, - pub r_paren_token: SyntaxResult, + pub arguments: SyntaxResult, pub qualifier_clause: Option, pub type_arguments: Option, } @@ -26013,18 +26003,7 @@ impl std::fmt::Debug for TsImportType { "import_token", &support::DebugSyntaxResult(self.import_token()), ) - .field( - "l_paren_token", - &support::DebugSyntaxResult(self.l_paren_token()), - ) - .field( - "argument_token", - &support::DebugSyntaxResult(self.argument_token()), - ) - .field( - "r_paren_token", - &support::DebugSyntaxResult(self.r_paren_token()), - ) + .field("arguments", &support::DebugSyntaxResult(self.arguments())) .field( "qualifier_clause", &support::DebugOptionalElement(self.qualifier_clause()), diff --git a/crates/biome_js_syntax/src/generated/nodes_mut.rs b/crates/biome_js_syntax/src/generated/nodes_mut.rs index 434826ab35ae..42e90d00fa41 100644 --- a/crates/biome_js_syntax/src/generated/nodes_mut.rs +++ b/crates/biome_js_syntax/src/generated/nodes_mut.rs @@ -4631,33 +4631,21 @@ impl TsImportType { .splice_slots(1usize..=1usize, once(Some(element.into()))), ) } - pub fn with_l_paren_token(self, element: SyntaxToken) -> Self { - Self::unwrap_cast( - self.syntax - .splice_slots(2usize..=2usize, once(Some(element.into()))), - ) - } - pub fn with_argument_token(self, element: SyntaxToken) -> Self { - Self::unwrap_cast( - self.syntax - .splice_slots(3usize..=3usize, once(Some(element.into()))), - ) - } - pub fn with_r_paren_token(self, element: SyntaxToken) -> Self { + pub fn with_arguments(self, element: JsCallArguments) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(4usize..=4usize, once(Some(element.into()))), + .splice_slots(2usize..=2usize, once(Some(element.into_syntax().into()))), ) } pub fn with_qualifier_clause(self, element: Option) -> Self { Self::unwrap_cast(self.syntax.splice_slots( - 5usize..=5usize, + 3usize..=3usize, once(element.map(|element| element.into_syntax().into())), )) } pub fn with_type_arguments(self, element: Option) -> Self { Self::unwrap_cast(self.syntax.splice_slots( - 6usize..=6usize, + 4usize..=4usize, once(element.map(|element| element.into_syntax().into())), )) } diff --git a/xtask/codegen/js.ungram b/xtask/codegen/js.ungram index 219e6bddb010..a9ca2339abe4 100644 --- a/xtask/codegen/js.ungram +++ b/xtask/codegen/js.ungram @@ -2133,9 +2133,7 @@ TsMappedTypeReadonlyModifierClause = TsImportType = 'typeof'? 'import' - '(' - argument: 'js_string_literal' - ')' + arguments: JsCallArguments qualifier_clause: TsImportTypeQualifier? type_arguments: TsTypeArguments?