From d9c8c8f32a906c5b71b4c34f40232e88e6807a73 Mon Sep 17 00:00:00 2001 From: Victorien Elvinger Date: Tue, 12 Dec 2023 21:39:45 +0100 Subject: [PATCH 1/2] refactor(js_grammar): improve imports representation --- .../nursery/use_grouped_type_import.rs | 41 +- .../assists/correctness/organize_imports.rs | 16 +- crates/biome_js_analyze/src/react.rs | 9 +- .../correctness/no_unused_variables.rs | 2 - .../use_exhaustive_dependencies.rs | 4 +- .../nursery/no_unused_imports.rs | 109 +++-- .../style/use_naming_convention.rs | 6 +- .../suspicious/no_import_assign.rs | 15 +- .../src/generated/node_factory.rs | 94 ++-- .../src/generated/syntax_factory.rs | 94 ++-- crates/biome_js_formatter/src/generated.rs | 110 +++-- .../src/js/any/extra_import_specifier.rs | 15 + .../src/js/any/import_clause.rs | 1 + crates/biome_js_formatter/src/js/any/mod.rs | 2 +- .../src/js/any/named_import.rs | 15 - .../src/js/module/default_import_specifier.rs | 8 +- .../src/js/module/import_default_clause.rs | 4 +- .../js/module/import_default_extra_clause.rs | 44 ++ .../src/js/module/import_named_clause.rs | 149 ++----- .../src/js/module/import_namespace_clause.rs | 10 +- .../biome_js_formatter/src/js/module/mod.rs | 1 + .../deferred-import-evaluation.js.snap | 47 -- ...mport-defer-attributes-declaration.js.snap | 67 --- .../import-defer.js.snap | 47 -- .../src/syntax/js_parse_error.rs | 11 + crates/biome_js_parser/src/syntax/module.rs | 81 ++-- .../inline/err/import_as_identifier_err.rast | 12 +- .../inline/err/import_assertion_err.rast | 44 +- .../inline/err/import_attribute_err.rast | 44 +- .../inline/err/import_decl_not_top_level.rast | 11 +- .../test_data/inline/err/import_err.rast | 109 +++-- .../err/ts_named_import_specifier_error.rast | 56 +-- .../ts_typed_default_import_with_named.rast | 28 +- .../inline/ok/import_as_as_as_identifier.rast | 12 +- .../inline/ok/import_as_identifier.rast | 12 +- .../test_data/inline/ok/import_assertion.rast | 34 +- .../test_data/inline/ok/import_attribute.rast | 34 +- .../test_data/inline/ok/import_decl.rast | 25 +- .../inline/ok/import_default_clause.rast | 11 +- .../inline/ok/import_default_clauses.js | 1 + .../inline/ok/import_default_clauses.rast | 64 +++ .../inline/ok/import_named_clause.js | 2 - .../inline/ok/import_named_clause.rast | 224 +++------- .../test_data/inline/ok/module.rast | 23 +- .../inline/ok/ts_import_clause_types.rast | 70 +-- .../ts_named_import_specifier_with_type.rast | 60 ++- crates/biome_js_semantic/src/events.rs | 25 +- crates/biome_js_syntax/src/binding_ext.rs | 23 +- crates/biome_js_syntax/src/generated/kind.rs | 1 + .../biome_js_syntax/src/generated/macros.rs | 5 + crates/biome_js_syntax/src/generated/nodes.rs | 410 ++++++++++++------ .../src/generated/nodes_mut.rs | 84 ++-- crates/biome_js_syntax/src/import_ext.rs | 28 +- xtask/codegen/js.ungram | 50 ++- xtask/codegen/src/generate_bindings.rs | 11 +- xtask/codegen/src/kinds_src.rs | 1 + 56 files changed, 1252 insertions(+), 1264 deletions(-) create mode 100644 crates/biome_js_formatter/src/js/any/extra_import_specifier.rs delete mode 100644 crates/biome_js_formatter/src/js/any/named_import.rs create mode 100644 crates/biome_js_formatter/src/js/module/import_default_extra_clause.rs delete mode 100644 crates/biome_js_formatter/tests/specs/prettier/js/babel-plugins/deferred-import-evaluation.js.snap delete mode 100644 crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer-attributes-declaration.js.snap delete mode 100644 crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer.js.snap create mode 100644 crates/biome_js_parser/test_data/inline/ok/import_default_clauses.js create mode 100644 crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast diff --git a/crates/biome_js_analyze/src/analyzers/nursery/use_grouped_type_import.rs b/crates/biome_js_analyze/src/analyzers/nursery/use_grouped_type_import.rs index db687289fede..8f817165b1cd 100644 --- a/crates/biome_js_analyze/src/analyzers/nursery/use_grouped_type_import.rs +++ b/crates/biome_js_analyze/src/analyzers/nursery/use_grouped_type_import.rs @@ -5,9 +5,7 @@ use biome_analyze::{ use biome_console::markup; use biome_diagnostics::Applicability; use biome_js_factory::make; -use biome_js_syntax::{ - AnyJsNamedImport, AnyJsNamedImportSpecifier, JsImportNamedClause, TriviaPieceKind, T, -}; +use biome_js_syntax::{AnyJsNamedImportSpecifier, JsImportNamedClause, TriviaPieceKind, T}; use biome_rowan::{AstNode, AstSeparatedList, BatchMutationExt}; declare_rule! { @@ -75,24 +73,16 @@ impl Rule for UseGroupedTypeImport { type Options = (); fn run(ctx: &RuleContext) -> Self::Signals { - let node = ctx.query(); - if node.type_token().is_some() || node.default_specifier().is_some() { + let import_clause = ctx.query(); + if import_clause.type_token().is_some() { return None; } - if node - .named_import() - .ok()? - .as_js_named_import_specifiers()? - .specifiers() - .is_empty() - { + let specifiers = import_clause.named_specifiers().ok()?.specifiers(); + if specifiers.is_empty() { // import {} from ... return None; } - node.named_import() - .ok()? - .as_js_named_import_specifiers()? - .specifiers() + specifiers .iter() .all(|specifier| { let Ok(specifier) = specifier else { @@ -112,11 +102,11 @@ impl Rule for UseGroupedTypeImport { } fn diagnostic(ctx: &RuleContext, _: &Self::State) -> Option { - let node = ctx.query(); + let import_clause = ctx.query(); Some( RuleDiagnostic::new( rule_category!(), - node.named_import().ok()?.range(), + import_clause.named_specifiers().ok()?.range(), markup! { "The ""type"" qualifier can be moved just after ""import"" to completely remove the ""import"" at compile time." }, @@ -128,10 +118,8 @@ impl Rule for UseGroupedTypeImport { } fn action(ctx: &RuleContext, _: &Self::State) -> Option { - let node = ctx.query(); - let mut mutation = ctx.root().begin(); - let named_import = node.named_import().ok()?; - let named_import_specifiers = named_import.as_js_named_import_specifiers()?; + let import_clause = ctx.query(); + let named_import_specifiers = import_clause.named_specifiers().ok()?; let named_import_specifiers_list = named_import_specifiers.specifiers(); let new_named_import_specifiers_list = make::js_named_import_specifier_list( named_import_specifiers_list @@ -156,17 +144,18 @@ impl Rule for UseGroupedTypeImport { .filter_map(|separator| separator.ok()) .collect::>(), ); - let new_node = node + let new_node = import_clause .clone() .with_type_token(Some( make::token(T![type]).with_trailing_trivia([(TriviaPieceKind::Whitespace, " ")]), )) - .with_named_import(AnyJsNamedImport::JsNamedImportSpecifiers( + .with_named_specifiers( named_import_specifiers .clone() .with_specifiers(new_named_import_specifiers_list), - )); - mutation.replace_node(node.clone(), new_node); + ); + let mut mutation = ctx.root().begin(); + mutation.replace_node(import_clause.clone(), new_node); Some(JsRuleAction { category: ActionCategory::QuickFix, applicability: Applicability::MaybeIncorrect, diff --git a/crates/biome_js_analyze/src/assists/correctness/organize_imports.rs b/crates/biome_js_analyze/src/assists/correctness/organize_imports.rs index 7e79bfce362b..f7fa87534deb 100644 --- a/crates/biome_js_analyze/src/assists/correctness/organize_imports.rs +++ b/crates/biome_js_analyze/src/assists/correctness/organize_imports.rs @@ -7,8 +7,8 @@ use biome_console::markup; use biome_diagnostics::Applicability; use biome_js_factory::make; use biome_js_syntax::{ - AnyJsImportClause, AnyJsModuleItem, AnyJsNamedImport, AnyJsNamedImportSpecifier, JsImport, - JsLanguage, JsModule, JsSyntaxToken, TextRange, TriviaPieceKind, T, + AnyJsImportClause, AnyJsModuleItem, AnyJsNamedImportSpecifier, JsImport, JsLanguage, JsModule, + JsSyntaxToken, TextRange, TriviaPieceKind, T, }; use biome_rowan::{ chain_trivia_pieces, syntax::SyntaxTrivia, AstNode, AstNodeExt, AstNodeList, AstSeparatedList, @@ -300,13 +300,7 @@ impl From for ImportNode { let AnyJsImportClause::JsImportNamedClause(import_named_clause) = import_clause else { return None; }; - - let named_import = import_named_clause.named_import().ok()?; - let AnyJsNamedImport::JsNamedImportSpecifiers(named_import_specifiers) = named_import - else { - return None; - }; - + let named_import_specifiers = import_named_clause.named_specifiers().ok()?; let mut result = BTreeMap::new(); for element in named_import_specifiers.specifiers().elements() { @@ -353,9 +347,7 @@ impl ImportNode { let Ok(AnyJsImportClause::JsImportNamedClause(import_named_clause)) = import_clause else { return import; }; - - let named_import = import_named_clause.named_import(); - let Ok(AnyJsNamedImport::JsNamedImportSpecifiers(old_specifiers)) = named_import else { + let Ok(old_specifiers) = import_named_clause.named_specifiers() else { return import; }; diff --git a/crates/biome_js_analyze/src/react.rs b/crates/biome_js_analyze/src/react.rs index d0e3a232afac..23c12ce75f3d 100644 --- a/crates/biome_js_analyze/src/react.rs +++ b/crates/biome_js_analyze/src/react.rs @@ -5,8 +5,7 @@ pub mod hooks; use biome_js_semantic::{Binding, SemanticModel}; use biome_js_syntax::{ AnyJsCallArgument, AnyJsExpression, AnyJsMemberExpression, AnyJsNamedImportSpecifier, - AnyJsObjectMember, JsCallExpression, JsIdentifierBinding, JsImport, JsImportNamedClause, - JsNamedImportSpecifierList, JsNamedImportSpecifiers, JsObjectExpression, + AnyJsObjectMember, JsCallExpression, JsIdentifierBinding, JsImport, JsObjectExpression, JsPropertyObjectMember, JsxMemberName, JsxReferenceIdentifier, }; use biome_rowan::{AstNode, AstSeparatedList}; @@ -290,10 +289,6 @@ fn is_named_react_export(binding: &Binding, lib: ReactLibrary, name: &str) -> Op return Some(false); } - let import_specifier_list = import_specifier.parent::()?; - let import_specifiers = import_specifier_list.parent::()?; - let import_clause = import_specifiers.parent::()?; - let import = import_clause.parent::()?; - + let import = import_specifier.import_clause()?.parent::()?; Some(import.source_text().ok()?.text() == lib.import_name()) } diff --git a/crates/biome_js_analyze/src/semantic_analyzers/correctness/no_unused_variables.rs b/crates/biome_js_analyze/src/semantic_analyzers/correctness/no_unused_variables.rs index 6713ea9dbdbd..9829d107b001 100644 --- a/crates/biome_js_analyze/src/semantic_analyzers/correctness/no_unused_variables.rs +++ b/crates/biome_js_analyze/src/semantic_analyzers/correctness/no_unused_variables.rs @@ -223,8 +223,6 @@ fn suggested_fix_if_unused(binding: &AnyJsIdentifierBinding) -> Option Some(capture), // This should be unreachable because of the test if the capture is imported - AnyJsBindingDeclaration::JsImportDefaultClause(_) - | AnyJsBindingDeclaration::JsImportNamespaceClause(_) - | AnyJsBindingDeclaration::JsShorthandNamedImportSpecifier(_) + AnyJsBindingDeclaration::JsShorthandNamedImportSpecifier(_) | AnyJsBindingDeclaration::JsNamedImportSpecifier(_) | AnyJsBindingDeclaration::JsBogusNamedImportSpecifier(_) | AnyJsBindingDeclaration::JsDefaultImportSpecifier(_) diff --git a/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs b/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs index 2fd4be363a8b..85a81b0126c0 100644 --- a/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs +++ b/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs @@ -7,12 +7,10 @@ use biome_diagnostics::Applicability; use biome_js_factory::make; use biome_js_semantic::ReferencesExtensions; use biome_js_syntax::{ - binding_ext::AnyJsBindingDeclaration, AnyJsImportClause, JsIdentifierBinding, JsImport, - JsImportNamedClause, JsLanguage, JsNamedImportSpecifierList, T, -}; -use biome_rowan::{ - AstNode, AstSeparatedList, BatchMutation, BatchMutationExt, NodeOrToken, SyntaxResult, + binding_ext::AnyJsBindingDeclaration, AnyJsExtraImportSpecifier, AnyJsImportClause, + JsIdentifierBinding, JsImport, JsLanguage, JsNamedImportSpecifierList, JsSyntaxNode, T, }; +use biome_rowan::{AstNode, AstSeparatedList, BatchMutation, BatchMutationExt}; declare_rule! { /// Disallow unused imports. @@ -108,20 +106,12 @@ impl Rule for NoUnusedImports { let declaration = ctx.query().declaration()?; let mut mutation = ctx.root().begin(); match declaration { - AnyJsBindingDeclaration::JsImportDefaultClause(_) - | AnyJsBindingDeclaration::JsImportNamespaceClause(_) => { - let import = declaration.parent::()?; - mutation.transfer_leading_trivia_to_sibling(import.syntax()); - mutation.remove_node(import); - } AnyJsBindingDeclaration::JsShorthandNamedImportSpecifier(_) | AnyJsBindingDeclaration::JsNamedImportSpecifier(_) | AnyJsBindingDeclaration::JsBogusNamedImportSpecifier(_) => { let specifier_list = declaration.parent::()?; - if specifier_list.iter().count() == 1 { - let import_clause = - JsImportNamedClause::cast(specifier_list.syntax().parent()?.parent()?)?; - remove_named_import_from_import_clause(&mut mutation, import_clause).ok()?; + if specifier_list.len() == 1 { + remove_import_specifier(&mut mutation, &specifier_list.syntax().parent()?)?; } else { let following_separator = specifier_list .iter() @@ -138,12 +128,9 @@ impl Rule for NoUnusedImports { mutation.remove_node(declaration); } } - AnyJsBindingDeclaration::JsDefaultImportSpecifier(declaration) => { - mutation.remove_node(declaration); - } - AnyJsBindingDeclaration::JsNamespaceImportSpecifier(_) => { - let import_clause = JsImportNamedClause::cast(declaration.syntax().parent()?)?; - remove_named_import_from_import_clause(&mut mutation, import_clause).ok()?; + AnyJsBindingDeclaration::JsDefaultImportSpecifier(_) + | AnyJsBindingDeclaration::JsNamespaceImportSpecifier(_) => { + remove_import_specifier(&mut mutation, declaration.syntax())?; } AnyJsBindingDeclaration::TsImportEqualsDeclaration(_) => { mutation.remove_node(declaration); @@ -161,34 +148,74 @@ impl Rule for NoUnusedImports { } } -fn remove_named_import_from_import_clause( +fn remove_import_specifier( mutation: &mut BatchMutation, - import_clause: JsImportNamedClause, -) -> SyntaxResult<()> { - if let Some(default_specifier) = import_clause.default_specifier() { - let default_clause = make::js_import_default_clause( - default_specifier.local_name()?, - make::token_decorated_with_space(T![from]), - import_clause.source()?, - ) - .build(); - mutation.replace_node( - AnyJsImportClause::from(import_clause), - default_clause.into(), - ); - } else if let Some(import) = import_clause.syntax().parent() { - mutation.transfer_leading_trivia_to_sibling(&import); - mutation.remove_element(NodeOrToken::Node(import)); + specifier: &JsSyntaxNode, +) -> Option<()> { + let clause = specifier.parent().and_then(AnyJsImportClause::cast)?; + match &clause { + AnyJsImportClause::JsImportDefaultExtraClause(default_extra_clause) => { + let default_specifier = default_extra_clause.default_specifier().ok()?; + let from_token = default_extra_clause.from_token().ok()?; + let source = default_extra_clause.source().ok()?; + let assertion = default_extra_clause.assertion(); + if default_specifier.syntax() == specifier { + let new_clause = match default_extra_clause.extra_specifier().ok()? { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(named_specifier) => { + let named_clause = + make::js_import_named_clause(named_specifier, from_token, source); + let named_clause = if let Some(assertion) = assertion { + named_clause.with_assertion(assertion) + } else { + named_clause + }; + AnyJsImportClause::JsImportNamedClause(named_clause.build()) + } + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(namespace_specifier) => { + let namespace_clause = make::js_import_namespace_clause( + namespace_specifier, + from_token, + source, + ); + let namespace_clause = if let Some(assertion) = assertion { + namespace_clause.with_assertion(assertion) + } else { + namespace_clause + }; + AnyJsImportClause::JsImportNamespaceClause(namespace_clause.build()) + } + }; + mutation.replace_node(clause, new_clause); + } else { + let from_token = make::token_decorated_with_space(T![from]) + .with_trailing_trivia_pieces(from_token.trailing_trivia().pieces()); + let default_clause = + make::js_import_default_clause(default_specifier, from_token, source); + let default_clause = if let Some(assertion) = assertion { + default_clause.with_assertion(assertion) + } else { + default_clause + }; + mutation.replace_node(clause, default_clause.build().into()); + } + } + AnyJsImportClause::JsImportBareClause(_) + | AnyJsImportClause::JsImportDefaultClause(_) + | AnyJsImportClause::JsImportNamedClause(_) + | AnyJsImportClause::JsImportNamespaceClause(_) => { + // Remove the entire statement + let import = clause.parent::()?; + mutation.transfer_leading_trivia_to_sibling(import.syntax()); + mutation.remove_node(import); + } } - Ok(()) + Some(()) } const fn is_import(declaration: &AnyJsBindingDeclaration) -> bool { matches!( declaration, AnyJsBindingDeclaration::JsDefaultImportSpecifier(_) - | AnyJsBindingDeclaration::JsImportDefaultClause(_) - | AnyJsBindingDeclaration::JsImportNamespaceClause(_) | AnyJsBindingDeclaration::JsNamedImportSpecifier(_) | AnyJsBindingDeclaration::JsNamespaceImportSpecifier(_) | AnyJsBindingDeclaration::JsShorthandNamedImportSpecifier(_) diff --git a/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs b/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs index d1bc77c7aed1..db9a485e7b4a 100644 --- a/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs +++ b/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs @@ -840,8 +840,7 @@ impl Named { AnyJsBindingDeclaration::JsCatchDeclaration(_) => Some(Named::CatchParameter), AnyJsBindingDeclaration::TsPropertyParameter(_) => Some(Named::ParameterProperty), AnyJsBindingDeclaration::TsIndexSignatureParameter(_) => Some(Named::IndexParameter), - AnyJsBindingDeclaration::JsNamespaceImportSpecifier(_) - | AnyJsBindingDeclaration::JsImportNamespaceClause(_) => Some(Named::ImportNamespace), + AnyJsBindingDeclaration::JsNamespaceImportSpecifier(_) => Some(Named::ImportNamespace), AnyJsBindingDeclaration::JsFunctionDeclaration(_) | AnyJsBindingDeclaration::JsFunctionExpression(_) | AnyJsBindingDeclaration::JsFunctionExportDefaultDeclaration(_) @@ -849,8 +848,7 @@ impl Named { | AnyJsBindingDeclaration::TsDeclareFunctionExportDefaultDeclaration(_) => { Some(Named::Function) } - AnyJsBindingDeclaration::JsImportDefaultClause(_) - | AnyJsBindingDeclaration::TsImportEqualsDeclaration(_) + AnyJsBindingDeclaration::TsImportEqualsDeclaration(_) | AnyJsBindingDeclaration::JsDefaultImportSpecifier(_) | AnyJsBindingDeclaration::JsNamedImportSpecifier(_) => Some(Named::ImportAlias), AnyJsBindingDeclaration::TsModuleDeclaration(_) => Some(Named::Namespace), diff --git a/crates/biome_js_analyze/src/semantic_analyzers/suspicious/no_import_assign.rs b/crates/biome_js_analyze/src/semantic_analyzers/suspicious/no_import_assign.rs index 78463a077298..1c8a757680d7 100644 --- a/crates/biome_js_analyze/src/semantic_analyzers/suspicious/no_import_assign.rs +++ b/crates/biome_js_analyze/src/semantic_analyzers/suspicious/no_import_assign.rs @@ -3,9 +3,8 @@ use biome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic}; use biome_console::markup; use biome_js_semantic::ReferencesExtensions; use biome_js_syntax::{ - JsDefaultImportSpecifier, JsIdentifierAssignment, JsIdentifierBinding, JsImportDefaultClause, - JsImportNamespaceClause, JsNamedImportSpecifier, JsNamespaceImportSpecifier, - JsShorthandNamedImportSpecifier, + JsDefaultImportSpecifier, JsIdentifierAssignment, JsIdentifierBinding, JsNamedImportSpecifier, + JsNamespaceImportSpecifier, JsShorthandNamedImportSpecifier, }; use biome_rowan::{declare_node_union, AstNode}; @@ -67,10 +66,6 @@ impl Rule for NoImportAssign { let label_statement = ctx.query(); let mut invalid_assign_list = vec![]; let local_name_binding = match label_statement { - // `import xx from 'y'` - AnyJsImportLike::JsImportDefaultClause(clause) => clause.local_name().ok(), - // `import * as xxx from 'y'` - AnyJsImportLike::JsImportNamespaceClause(clause) => clause.local_name().ok(), // `import {x as xx} from 'y'` // ^^^^^^^ AnyJsImportLike::JsNamedImportSpecifier(specifier) => specifier.local_name().ok(), @@ -79,9 +74,13 @@ impl Rule for NoImportAssign { AnyJsImportLike::JsShorthandNamedImportSpecifier(specifier) => { specifier.local_name().ok() } + // `import * as xxx from 'y'` + // ^^^^^^^^ // `import a, * as b from 'y'` // ^^^^^^ AnyJsImportLike::JsNamespaceImportSpecifier(specifier) => specifier.local_name().ok(), + // `import xx from 'y'` + // ^^ // `import a, * as b from 'y'` // ^ AnyJsImportLike::JsDefaultImportSpecifier(specifier) => specifier.local_name().ok(), @@ -125,5 +124,5 @@ impl Rule for NoImportAssign { } declare_node_union! { - pub(crate) AnyJsImportLike = JsImportDefaultClause | JsImportNamespaceClause | JsNamedImportSpecifier | JsShorthandNamedImportSpecifier | JsNamespaceImportSpecifier | JsDefaultImportSpecifier + pub(crate) AnyJsImportLike = JsNamedImportSpecifier | JsShorthandNamedImportSpecifier | JsNamespaceImportSpecifier | JsDefaultImportSpecifier } diff --git a/crates/biome_js_factory/src/generated/node_factory.rs b/crates/biome_js_factory/src/generated/node_factory.rs index 6e36c9a9193a..fd48bef74cd5 100644 --- a/crates/biome_js_factory/src/generated/node_factory.rs +++ b/crates/biome_js_factory/src/generated/node_factory.rs @@ -813,16 +813,10 @@ pub fn js_default_clause( ], )) } -pub fn js_default_import_specifier( - local_name: AnyJsBinding, - trailing_comma_token: SyntaxToken, -) -> JsDefaultImportSpecifier { +pub fn js_default_import_specifier(local_name: AnyJsBinding) -> JsDefaultImportSpecifier { JsDefaultImportSpecifier::unwrap_cast(SyntaxNode::new_detached( JsSyntaxKind::JS_DEFAULT_IMPORT_SPECIFIER, - [ - Some(SyntaxElement::Node(local_name.into_syntax())), - Some(SyntaxElement::Token(trailing_comma_token)), - ], + [Some(SyntaxElement::Node(local_name.into_syntax()))], )) } pub fn js_directive(value_token: SyntaxToken) -> JsDirectiveBuilder { @@ -2034,12 +2028,12 @@ pub fn js_import_call_expression( )) } pub fn js_import_default_clause( - local_name: AnyJsBinding, + default_specifier: JsDefaultImportSpecifier, from_token: SyntaxToken, source: JsModuleSource, ) -> JsImportDefaultClauseBuilder { JsImportDefaultClauseBuilder { - local_name, + default_specifier, from_token, source, type_token: None, @@ -2047,7 +2041,7 @@ pub fn js_import_default_clause( } } pub struct JsImportDefaultClauseBuilder { - local_name: AnyJsBinding, + default_specifier: JsDefaultImportSpecifier, from_token: SyntaxToken, source: JsModuleSource, type_token: Option, @@ -2067,7 +2061,51 @@ impl JsImportDefaultClauseBuilder { JsSyntaxKind::JS_IMPORT_DEFAULT_CLAUSE, [ self.type_token.map(|token| SyntaxElement::Token(token)), - Some(SyntaxElement::Node(self.local_name.into_syntax())), + Some(SyntaxElement::Node(self.default_specifier.into_syntax())), + Some(SyntaxElement::Token(self.from_token)), + Some(SyntaxElement::Node(self.source.into_syntax())), + self.assertion + .map(|token| SyntaxElement::Node(token.into_syntax())), + ], + )) + } +} +pub fn js_import_default_extra_clause( + default_specifier: JsDefaultImportSpecifier, + comma_token: SyntaxToken, + extra_specifier: AnyJsExtraImportSpecifier, + from_token: SyntaxToken, + source: JsModuleSource, +) -> JsImportDefaultExtraClauseBuilder { + JsImportDefaultExtraClauseBuilder { + default_specifier, + comma_token, + extra_specifier, + from_token, + source, + assertion: None, + } +} +pub struct JsImportDefaultExtraClauseBuilder { + default_specifier: JsDefaultImportSpecifier, + comma_token: SyntaxToken, + extra_specifier: AnyJsExtraImportSpecifier, + from_token: SyntaxToken, + source: JsModuleSource, + assertion: Option, +} +impl JsImportDefaultExtraClauseBuilder { + pub fn with_assertion(mut self, assertion: JsImportAssertion) -> Self { + self.assertion = Some(assertion); + self + } + pub fn build(self) -> JsImportDefaultExtraClause { + JsImportDefaultExtraClause::unwrap_cast(SyntaxNode::new_detached( + JsSyntaxKind::JS_IMPORT_DEFAULT_EXTRA_CLAUSE, + [ + Some(SyntaxElement::Node(self.default_specifier.into_syntax())), + Some(SyntaxElement::Token(self.comma_token)), + Some(SyntaxElement::Node(self.extra_specifier.into_syntax())), Some(SyntaxElement::Token(self.from_token)), Some(SyntaxElement::Node(self.source.into_syntax())), self.assertion @@ -2091,25 +2129,23 @@ pub fn js_import_meta_expression( )) } pub fn js_import_named_clause( - named_import: AnyJsNamedImport, + named_specifiers: JsNamedImportSpecifiers, from_token: SyntaxToken, source: JsModuleSource, ) -> JsImportNamedClauseBuilder { JsImportNamedClauseBuilder { - named_import, + named_specifiers, from_token, source, type_token: None, - default_specifier: None, assertion: None, } } pub struct JsImportNamedClauseBuilder { - named_import: AnyJsNamedImport, + named_specifiers: JsNamedImportSpecifiers, from_token: SyntaxToken, source: JsModuleSource, type_token: Option, - default_specifier: Option, assertion: Option, } impl JsImportNamedClauseBuilder { @@ -2117,10 +2153,6 @@ impl JsImportNamedClauseBuilder { self.type_token = Some(type_token); self } - pub fn with_default_specifier(mut self, default_specifier: JsDefaultImportSpecifier) -> Self { - self.default_specifier = Some(default_specifier); - self - } pub fn with_assertion(mut self, assertion: JsImportAssertion) -> Self { self.assertion = Some(assertion); self @@ -2130,9 +2162,7 @@ impl JsImportNamedClauseBuilder { JsSyntaxKind::JS_IMPORT_NAMED_CLAUSE, [ self.type_token.map(|token| SyntaxElement::Token(token)), - self.default_specifier - .map(|token| SyntaxElement::Node(token.into_syntax())), - Some(SyntaxElement::Node(self.named_import.into_syntax())), + Some(SyntaxElement::Node(self.named_specifiers.into_syntax())), Some(SyntaxElement::Token(self.from_token)), Some(SyntaxElement::Node(self.source.into_syntax())), self.assertion @@ -2142,16 +2172,12 @@ impl JsImportNamedClauseBuilder { } } pub fn js_import_namespace_clause( - star_token: SyntaxToken, - as_token: SyntaxToken, - local_name: AnyJsBinding, + namespace_specifier: JsNamespaceImportSpecifier, from_token: SyntaxToken, source: JsModuleSource, ) -> JsImportNamespaceClauseBuilder { JsImportNamespaceClauseBuilder { - star_token, - as_token, - local_name, + namespace_specifier, from_token, source, type_token: None, @@ -2159,9 +2185,7 @@ pub fn js_import_namespace_clause( } } pub struct JsImportNamespaceClauseBuilder { - star_token: SyntaxToken, - as_token: SyntaxToken, - local_name: AnyJsBinding, + namespace_specifier: JsNamespaceImportSpecifier, from_token: SyntaxToken, source: JsModuleSource, type_token: Option, @@ -2181,9 +2205,7 @@ impl JsImportNamespaceClauseBuilder { JsSyntaxKind::JS_IMPORT_NAMESPACE_CLAUSE, [ self.type_token.map(|token| SyntaxElement::Token(token)), - Some(SyntaxElement::Token(self.star_token)), - Some(SyntaxElement::Token(self.as_token)), - Some(SyntaxElement::Node(self.local_name.into_syntax())), + Some(SyntaxElement::Node(self.namespace_specifier.into_syntax())), Some(SyntaxElement::Token(self.from_token)), Some(SyntaxElement::Node(self.source.into_syntax())), self.assertion diff --git a/crates/biome_js_factory/src/generated/syntax_factory.rs b/crates/biome_js_factory/src/generated/syntax_factory.rs index fdc24f47d1cf..a15b8779296c 100644 --- a/crates/biome_js_factory/src/generated/syntax_factory.rs +++ b/crates/biome_js_factory/src/generated/syntax_factory.rs @@ -1347,7 +1347,7 @@ impl SyntaxFactory for JsSyntaxFactory { } JS_DEFAULT_IMPORT_SPECIFIER => { let mut elements = (&children).into_iter(); - let mut slots: RawNodeSlots<2usize> = RawNodeSlots::default(); + let mut slots: RawNodeSlots<1usize> = RawNodeSlots::default(); let mut current_element = elements.next(); if let Some(element) = ¤t_element { if AnyJsBinding::can_cast(element.kind()) { @@ -1356,13 +1356,6 @@ 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 current_element.is_some() { return RawSyntaxNode::new( JS_DEFAULT_IMPORT_SPECIFIER.to_bogus(), @@ -2957,7 +2950,7 @@ impl SyntaxFactory for JsSyntaxFactory { } slots.next_slot(); if let Some(element) = ¤t_element { - if AnyJsBinding::can_cast(element.kind()) { + if JsDefaultImportSpecifier::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } @@ -2992,6 +2985,60 @@ impl SyntaxFactory for JsSyntaxFactory { } slots.into_node(JS_IMPORT_DEFAULT_CLAUSE, children) } + JS_IMPORT_DEFAULT_EXTRA_CLAUSE => { + let mut elements = (&children).into_iter(); + let mut slots: RawNodeSlots<6usize> = RawNodeSlots::default(); + let mut current_element = elements.next(); + if let Some(element) = ¤t_element { + if JsDefaultImportSpecifier::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + 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 AnyJsExtraImportSpecifier::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if element.kind() == T![from] { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if JsModuleSource::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if JsImportAssertion::can_cast(element.kind()) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if current_element.is_some() { + return RawSyntaxNode::new( + JS_IMPORT_DEFAULT_EXTRA_CLAUSE.to_bogus(), + children.into_iter().map(Some), + ); + } + slots.into_node(JS_IMPORT_DEFAULT_EXTRA_CLAUSE, children) + } JS_IMPORT_META_EXPRESSION => { let mut elements = (&children).into_iter(); let mut slots: RawNodeSlots<3usize> = RawNodeSlots::default(); @@ -3027,7 +3074,7 @@ impl SyntaxFactory for JsSyntaxFactory { } JS_IMPORT_NAMED_CLAUSE => { let mut elements = (&children).into_iter(); - let mut slots: RawNodeSlots<6usize> = 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![type] { @@ -3037,14 +3084,7 @@ impl SyntaxFactory for JsSyntaxFactory { } slots.next_slot(); if let Some(element) = ¤t_element { - if JsDefaultImportSpecifier::can_cast(element.kind()) { - slots.mark_present(); - current_element = elements.next(); - } - } - slots.next_slot(); - if let Some(element) = ¤t_element { - if AnyJsNamedImport::can_cast(element.kind()) { + if JsNamedImportSpecifiers::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } @@ -3081,7 +3121,7 @@ impl SyntaxFactory for JsSyntaxFactory { } JS_IMPORT_NAMESPACE_CLAUSE => { 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![type] { @@ -3091,21 +3131,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() == T![as] { - slots.mark_present(); - current_element = elements.next(); - } - } - slots.next_slot(); - if let Some(element) = ¤t_element { - if AnyJsBinding::can_cast(element.kind()) { + if JsNamespaceImportSpecifier::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } diff --git a/crates/biome_js_formatter/src/generated.rs b/crates/biome_js_formatter/src/generated.rs index ff073d685bd8..4113cf9b33e7 100644 --- a/crates/biome_js_formatter/src/generated.rs +++ b/crates/biome_js_formatter/src/generated.rs @@ -6384,6 +6384,40 @@ impl IntoFormat for biome_js_syntax::JsImportNamespaceClause { ) } } +impl FormatRule + for crate::js::module::import_default_extra_clause::FormatJsImportDefaultExtraClause +{ + type Context = JsFormatContext; + #[inline(always)] + fn fmt( + &self, + node: &biome_js_syntax::JsImportDefaultExtraClause, + f: &mut JsFormatter, + ) -> FormatResult<()> { + FormatNodeRule::::fmt(self, node, f) + } +} +impl AsFormat for biome_js_syntax::JsImportDefaultExtraClause { + type Format<'a> = FormatRefWithRule< + 'a, + biome_js_syntax::JsImportDefaultExtraClause, + crate::js::module::import_default_extra_clause::FormatJsImportDefaultExtraClause, + >; + fn format(&self) -> Self::Format<'_> { + #![allow(clippy::default_constructed_unit_structs)] + FormatRefWithRule :: new (self , crate :: js :: module :: import_default_extra_clause :: FormatJsImportDefaultExtraClause :: default ()) + } +} +impl IntoFormat for biome_js_syntax::JsImportDefaultExtraClause { + type Format = FormatOwnedWithRule< + biome_js_syntax::JsImportDefaultExtraClause, + crate::js::module::import_default_extra_clause::FormatJsImportDefaultExtraClause, + >; + fn into_format(self) -> Self::Format { + #![allow(clippy::default_constructed_unit_structs)] + FormatOwnedWithRule :: new (self , crate :: js :: module :: import_default_extra_clause :: FormatJsImportDefaultExtraClause :: default ()) + } +} impl FormatRule for crate::js::module::module_source::FormatJsModuleSource { @@ -6500,78 +6534,78 @@ impl IntoFormat for biome_js_syntax::JsDefaultImportSpecifier { ) } } -impl FormatRule - for crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers +impl FormatRule + for crate::js::module::namespace_import_specifier::FormatJsNamespaceImportSpecifier { type Context = JsFormatContext; #[inline(always)] fn fmt( &self, - node: &biome_js_syntax::JsNamedImportSpecifiers, + node: &biome_js_syntax::JsNamespaceImportSpecifier, f: &mut JsFormatter, ) -> FormatResult<()> { - FormatNodeRule::::fmt(self, node, f) + FormatNodeRule::::fmt(self, node, f) } } -impl AsFormat for biome_js_syntax::JsNamedImportSpecifiers { +impl AsFormat for biome_js_syntax::JsNamespaceImportSpecifier { type Format<'a> = FormatRefWithRule< 'a, - biome_js_syntax::JsNamedImportSpecifiers, - crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers, + biome_js_syntax::JsNamespaceImportSpecifier, + crate::js::module::namespace_import_specifier::FormatJsNamespaceImportSpecifier, >; fn format(&self) -> Self::Format<'_> { #![allow(clippy::default_constructed_unit_structs)] - FormatRefWithRule::new( - self, - crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers::default(), - ) + FormatRefWithRule :: new (self , crate :: js :: module :: namespace_import_specifier :: FormatJsNamespaceImportSpecifier :: default ()) } } -impl IntoFormat for biome_js_syntax::JsNamedImportSpecifiers { +impl IntoFormat for biome_js_syntax::JsNamespaceImportSpecifier { type Format = FormatOwnedWithRule< - biome_js_syntax::JsNamedImportSpecifiers, - crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers, + biome_js_syntax::JsNamespaceImportSpecifier, + crate::js::module::namespace_import_specifier::FormatJsNamespaceImportSpecifier, >; fn into_format(self) -> Self::Format { #![allow(clippy::default_constructed_unit_structs)] - FormatOwnedWithRule::new( - self, - crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers::default(), - ) + FormatOwnedWithRule :: new (self , crate :: js :: module :: namespace_import_specifier :: FormatJsNamespaceImportSpecifier :: default ()) } } -impl FormatRule - for crate::js::module::namespace_import_specifier::FormatJsNamespaceImportSpecifier +impl FormatRule + for crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers { type Context = JsFormatContext; #[inline(always)] fn fmt( &self, - node: &biome_js_syntax::JsNamespaceImportSpecifier, + node: &biome_js_syntax::JsNamedImportSpecifiers, f: &mut JsFormatter, ) -> FormatResult<()> { - FormatNodeRule::::fmt(self, node, f) + FormatNodeRule::::fmt(self, node, f) } } -impl AsFormat for biome_js_syntax::JsNamespaceImportSpecifier { +impl AsFormat for biome_js_syntax::JsNamedImportSpecifiers { type Format<'a> = FormatRefWithRule< 'a, - biome_js_syntax::JsNamespaceImportSpecifier, - crate::js::module::namespace_import_specifier::FormatJsNamespaceImportSpecifier, + biome_js_syntax::JsNamedImportSpecifiers, + crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers, >; fn format(&self) -> Self::Format<'_> { #![allow(clippy::default_constructed_unit_structs)] - FormatRefWithRule :: new (self , crate :: js :: module :: namespace_import_specifier :: FormatJsNamespaceImportSpecifier :: default ()) + FormatRefWithRule::new( + self, + crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers::default(), + ) } } -impl IntoFormat for biome_js_syntax::JsNamespaceImportSpecifier { +impl IntoFormat for biome_js_syntax::JsNamedImportSpecifiers { type Format = FormatOwnedWithRule< - biome_js_syntax::JsNamespaceImportSpecifier, - crate::js::module::namespace_import_specifier::FormatJsNamespaceImportSpecifier, + biome_js_syntax::JsNamedImportSpecifiers, + crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers, >; fn into_format(self) -> Self::Format { #![allow(clippy::default_constructed_unit_structs)] - FormatOwnedWithRule :: new (self , crate :: js :: module :: namespace_import_specifier :: FormatJsNamespaceImportSpecifier :: default ()) + FormatOwnedWithRule::new( + self, + crate::js::module::named_import_specifiers::FormatJsNamedImportSpecifiers::default(), + ) } } impl FormatRule @@ -12791,30 +12825,30 @@ impl IntoFormat for biome_js_syntax::AnyJsImportClause { ) } } -impl AsFormat for biome_js_syntax::AnyJsNamedImport { +impl AsFormat for biome_js_syntax::AnyJsExtraImportSpecifier { type Format<'a> = FormatRefWithRule< 'a, - biome_js_syntax::AnyJsNamedImport, - crate::js::any::named_import::FormatAnyJsNamedImport, + biome_js_syntax::AnyJsExtraImportSpecifier, + crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier, >; fn format(&self) -> Self::Format<'_> { #![allow(clippy::default_constructed_unit_structs)] FormatRefWithRule::new( self, - crate::js::any::named_import::FormatAnyJsNamedImport::default(), + crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier::default(), ) } } -impl IntoFormat for biome_js_syntax::AnyJsNamedImport { +impl IntoFormat for biome_js_syntax::AnyJsExtraImportSpecifier { type Format = FormatOwnedWithRule< - biome_js_syntax::AnyJsNamedImport, - crate::js::any::named_import::FormatAnyJsNamedImport, + biome_js_syntax::AnyJsExtraImportSpecifier, + crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier, >; fn into_format(self) -> Self::Format { #![allow(clippy::default_constructed_unit_structs)] FormatOwnedWithRule::new( self, - crate::js::any::named_import::FormatAnyJsNamedImport::default(), + crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier::default(), ) } } diff --git a/crates/biome_js_formatter/src/js/any/extra_import_specifier.rs b/crates/biome_js_formatter/src/js/any/extra_import_specifier.rs new file mode 100644 index 000000000000..02fd16616a22 --- /dev/null +++ b/crates/biome_js_formatter/src/js/any/extra_import_specifier.rs @@ -0,0 +1,15 @@ +//! This is a generated file. Don't modify it by hand! Run 'cargo codegen formatter' to re-generate the file. + +use crate::prelude::*; +use biome_js_syntax::AnyJsExtraImportSpecifier; +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatAnyJsExtraImportSpecifier; +impl FormatRule for FormatAnyJsExtraImportSpecifier { + type Context = JsFormatContext; + fn fmt(&self, node: &AnyJsExtraImportSpecifier, f: &mut JsFormatter) -> FormatResult<()> { + match node { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(node) => node.format().fmt(f), + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(node) => node.format().fmt(f), + } + } +} diff --git a/crates/biome_js_formatter/src/js/any/import_clause.rs b/crates/biome_js_formatter/src/js/any/import_clause.rs index 8131fd386c07..68dc26c52861 100644 --- a/crates/biome_js_formatter/src/js/any/import_clause.rs +++ b/crates/biome_js_formatter/src/js/any/import_clause.rs @@ -12,6 +12,7 @@ impl FormatRule for FormatAnyJsImportClause { AnyJsImportClause::JsImportNamedClause(node) => node.format().fmt(f), AnyJsImportClause::JsImportDefaultClause(node) => node.format().fmt(f), AnyJsImportClause::JsImportNamespaceClause(node) => node.format().fmt(f), + AnyJsImportClause::JsImportDefaultExtraClause(node) => node.format().fmt(f), } } } diff --git a/crates/biome_js_formatter/src/js/any/mod.rs b/crates/biome_js_formatter/src/js/any/mod.rs index 819ea8d7cda6..864f2550f38a 100644 --- a/crates/biome_js_formatter/src/js/any/mod.rs +++ b/crates/biome_js_formatter/src/js/any/mod.rs @@ -20,6 +20,7 @@ pub(crate) mod export_clause; pub(crate) mod export_default_declaration; pub(crate) mod export_named_specifier; pub(crate) mod expression; +pub(crate) mod extra_import_specifier; pub(crate) mod for_in_or_of_initializer; pub(crate) mod for_initializer; pub(crate) mod formal_parameter; @@ -32,7 +33,6 @@ pub(crate) mod literal_expression; pub(crate) mod method_modifier; pub(crate) mod module_item; pub(crate) mod name; -pub(crate) mod named_import; pub(crate) mod named_import_specifier; pub(crate) mod object_assignment_pattern_member; pub(crate) mod object_binding_pattern_member; diff --git a/crates/biome_js_formatter/src/js/any/named_import.rs b/crates/biome_js_formatter/src/js/any/named_import.rs deleted file mode 100644 index 46aa1f9a7154..000000000000 --- a/crates/biome_js_formatter/src/js/any/named_import.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! This is a generated file. Don't modify it by hand! Run 'cargo codegen formatter' to re-generate the file. - -use crate::prelude::*; -use biome_js_syntax::AnyJsNamedImport; -#[derive(Debug, Clone, Default)] -pub(crate) struct FormatAnyJsNamedImport; -impl FormatRule for FormatAnyJsNamedImport { - type Context = JsFormatContext; - fn fmt(&self, node: &AnyJsNamedImport, f: &mut JsFormatter) -> FormatResult<()> { - match node { - AnyJsNamedImport::JsNamedImportSpecifiers(node) => node.format().fmt(f), - AnyJsNamedImport::JsNamespaceImportSpecifier(node) => node.format().fmt(f), - } - } -} diff --git a/crates/biome_js_formatter/src/js/module/default_import_specifier.rs b/crates/biome_js_formatter/src/js/module/default_import_specifier.rs index d7bd03bf02fe..5e14c258ec24 100644 --- a/crates/biome_js_formatter/src/js/module/default_import_specifier.rs +++ b/crates/biome_js_formatter/src/js/module/default_import_specifier.rs @@ -9,11 +9,7 @@ pub(crate) struct FormatJsDefaultImportSpecifier; impl FormatNodeRule for FormatJsDefaultImportSpecifier { fn fmt_fields(&self, node: &JsDefaultImportSpecifier, f: &mut JsFormatter) -> FormatResult<()> { - let JsDefaultImportSpecifierFields { - local_name, - trailing_comma_token, - } = node.as_fields(); - - write![f, [local_name.format(), trailing_comma_token.format()]] + let JsDefaultImportSpecifierFields { local_name } = node.as_fields(); + write![f, [local_name.format()]] } } diff --git a/crates/biome_js_formatter/src/js/module/import_default_clause.rs b/crates/biome_js_formatter/src/js/module/import_default_clause.rs index fee76fbe8df0..5097d00a6467 100644 --- a/crates/biome_js_formatter/src/js/module/import_default_clause.rs +++ b/crates/biome_js_formatter/src/js/module/import_default_clause.rs @@ -11,7 +11,7 @@ impl FormatNodeRule for FormatJsImportDefaultClause { fn fmt_fields(&self, node: &JsImportDefaultClause, f: &mut JsFormatter) -> FormatResult<()> { let JsImportDefaultClauseFields { type_token, - local_name, + default_specifier, from_token, source, assertion, @@ -24,7 +24,7 @@ impl FormatNodeRule for FormatJsImportDefaultClause { write![ f, [ - local_name.format(), + default_specifier.format(), space(), from_token.format(), space(), diff --git a/crates/biome_js_formatter/src/js/module/import_default_extra_clause.rs b/crates/biome_js_formatter/src/js/module/import_default_extra_clause.rs new file mode 100644 index 000000000000..82147d4cd5fe --- /dev/null +++ b/crates/biome_js_formatter/src/js/module/import_default_extra_clause.rs @@ -0,0 +1,44 @@ +use crate::prelude::*; + +use biome_formatter::write; +use biome_js_syntax::JsImportDefaultExtraClause; +use biome_js_syntax::JsImportDefaultExtraClauseFields; + +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatJsImportDefaultExtraClause; + +impl FormatNodeRule for FormatJsImportDefaultExtraClause { + fn fmt_fields( + &self, + node: &JsImportDefaultExtraClause, + f: &mut JsFormatter, + ) -> FormatResult<()> { + let JsImportDefaultExtraClauseFields { + default_specifier, + comma_token, + extra_specifier, + from_token, + source, + assertion, + } = node.as_fields(); + write![ + f, + [ + default_specifier.format(), + comma_token.format(), + space(), + extra_specifier.format(), + space(), + from_token.format(), + space(), + source.format(), + ] + ]?; + + if let Some(assertion) = assertion { + write!(f, [assertion.format()])?; + } + + Ok(()) + } +} diff --git a/crates/biome_js_formatter/src/js/module/import_named_clause.rs b/crates/biome_js_formatter/src/js/module/import_named_clause.rs index 3391707f0cc9..1e274aa664d8 100644 --- a/crates/biome_js_formatter/src/js/module/import_named_clause.rs +++ b/crates/biome_js_formatter/src/js/module/import_named_clause.rs @@ -1,8 +1,6 @@ use crate::prelude::*; use biome_formatter::{write, CstFormatContext}; -use biome_js_syntax::AnyJsNamedImport; -use biome_js_syntax::AnyJsNamedImportSpecifier; use biome_js_syntax::JsImportNamedClause; use biome_js_syntax::JsImportNamedClauseFields; use biome_js_syntax::JsNamedImportSpecifiersFields; @@ -14,8 +12,7 @@ impl FormatNodeRule for FormatJsImportNamedClause { fn fmt_fields(&self, node: &JsImportNamedClause, f: &mut JsFormatter) -> FormatResult<()> { let JsImportNamedClauseFields { type_token, - default_specifier, - named_import, + named_specifiers, from_token, source, assertion, @@ -25,13 +22,8 @@ impl FormatNodeRule for FormatJsImportNamedClause { write!(f, [type_token.format(), space()])?; } - let is_default_specifier_empty = default_specifier.is_none(); - - if let Some(default_specifier) = default_specifier { - write!(f, [default_specifier.format(), space()])?; - } - - let named_import = named_import?; + let named_specifiers = named_specifiers?; + let specifiers = named_specifiers.specifiers(); // can_break implementation, return `format_element` instead of boolean to reduce enum conversion overhead. // if `can_break` is true we just use the previous format strategy, otherwise we use the new format strategy. @@ -43,102 +35,55 @@ impl FormatNodeRule for FormatJsImportNamedClause { // Here we use an opposite way of thinking, we only thinking about the way that can not break // That's to say - // 1. `default_specifier` need to be none. // 2. length of `JsNamedImportSpecifiers` at least is one // 3. Surrounding of the only `JsNamedImportSpecifiers` should not have any comments - if !is_default_specifier_empty { - // `can_break` is true. - write![f, [named_import.format()]] - } else { - match named_import { - AnyJsNamedImport::JsNamedImportSpecifiers(ref specifiers) - if specifiers.specifiers().len() == 1 - && !f.context().comments().is_suppressed(specifiers.syntax()) => - { - // SAFETY: we know that the `specifiers.specifiers().len() == 1`, so unwrap `iter().next()` is safe. - let first_specifier = specifiers.specifiers().elements().next().unwrap(); - match (first_specifier.node(), first_specifier.trailing_separator()) { - ( - Ok(AnyJsNamedImportSpecifier::JsShorthandNamedImportSpecifier( - specifier, - )), - Ok(separator), - ) => { - if f.comments().has_comments(specifier.syntax()) { - write!(f, [named_import.format()]) - } else { - let JsNamedImportSpecifiersFields { - l_curly_token, - specifiers: _, - r_curly_token, - } = specifiers.as_fields(); - let should_insert_space_around_brackets = - f.options().bracket_spacing().value(); - - write!( - f, - [ - l_curly_token.format(), - maybe_space(should_insert_space_around_brackets), - specifier.format(), - ] - )?; - - if let Some(separator) = separator { - format_removed(separator).fmt(f)?; - } - - write!( - f, - [ - maybe_space(should_insert_space_around_brackets), - r_curly_token.format() - ] - ) - } - } - ( - Ok(AnyJsNamedImportSpecifier::JsNamedImportSpecifier(specifier)), - Ok(separator), - ) => { - if f.comments().has_comments(specifier.syntax()) { - write!(f, [named_import.format()]) - } else { - let JsNamedImportSpecifiersFields { - l_curly_token, - specifiers: _, - r_curly_token, - } = specifiers.as_fields(); - let should_insert_space_around_brackets = - f.options().bracket_spacing().value(); - - write!( - f, - [ - l_curly_token.format(), - maybe_space(should_insert_space_around_brackets), - specifier.format(), - ] - )?; - - if let Some(separator) = separator { - format_removed(separator).fmt(f)?; - } - - write!( - f, - [ - maybe_space(should_insert_space_around_brackets), - r_curly_token.format() - ] - ) - } - } - _ => write![f, [named_import.format()]], + if specifiers.len() == 1 + && !f + .context() + .comments() + .is_suppressed(named_specifiers.syntax()) + { + // SAFETY: we know that the `specifiers.specifiers().len() == 1`, so unwrap `iter().next()` is safe. + let first_specifier = specifiers.elements().next().unwrap(); + if let (Ok(specifier), Ok(separator)) = + (first_specifier.node(), first_specifier.trailing_separator()) + { + if f.comments().has_comments(specifier.syntax()) { + write!(f, [named_specifiers.format()]) + } else { + let JsNamedImportSpecifiersFields { + l_curly_token, + specifiers: _, + r_curly_token, + } = named_specifiers.as_fields(); + let should_insert_space_around_brackets = f.options().bracket_spacing().value(); + + write!( + f, + [ + l_curly_token.format(), + maybe_space(should_insert_space_around_brackets), + specifier.format(), + ] + )?; + + if let Some(separator) = separator { + format_removed(separator).fmt(f)?; } + + write!( + f, + [ + maybe_space(should_insert_space_around_brackets), + r_curly_token.format() + ] + ) } - _ => write![f, [named_import.format()]], + } else { + write![f, [named_specifiers.format()]] } + } else { + write![f, [named_specifiers.format()]] }?; write![f, [space(), from_token.format(), space(), source.format(),]]?; diff --git a/crates/biome_js_formatter/src/js/module/import_namespace_clause.rs b/crates/biome_js_formatter/src/js/module/import_namespace_clause.rs index 9464edc1e4c8..0ddc63937025 100644 --- a/crates/biome_js_formatter/src/js/module/import_namespace_clause.rs +++ b/crates/biome_js_formatter/src/js/module/import_namespace_clause.rs @@ -11,9 +11,7 @@ impl FormatNodeRule for FormatJsImportNamespaceClause { fn fmt_fields(&self, node: &JsImportNamespaceClause, f: &mut JsFormatter) -> FormatResult<()> { let JsImportNamespaceClauseFields { type_token, - star_token, - as_token, - local_name, + namespace_specifier, from_token, source, assertion, @@ -26,11 +24,7 @@ impl FormatNodeRule for FormatJsImportNamespaceClause { write![ f, [ - star_token.format(), - space(), - as_token.format(), - space(), - local_name.format(), + namespace_specifier.format(), space(), from_token.format(), space(), diff --git a/crates/biome_js_formatter/src/js/module/mod.rs b/crates/biome_js_formatter/src/js/module/mod.rs index bfe8e8a9a990..a871a1f891b7 100644 --- a/crates/biome_js_formatter/src/js/module/mod.rs +++ b/crates/biome_js_formatter/src/js/module/mod.rs @@ -16,6 +16,7 @@ pub(crate) mod import_assertion; pub(crate) mod import_assertion_entry; pub(crate) mod import_bare_clause; pub(crate) mod import_default_clause; +pub(crate) mod import_default_extra_clause; pub(crate) mod import_named_clause; pub(crate) mod import_namespace_clause; pub(crate) mod literal_export_name; diff --git a/crates/biome_js_formatter/tests/specs/prettier/js/babel-plugins/deferred-import-evaluation.js.snap b/crates/biome_js_formatter/tests/specs/prettier/js/babel-plugins/deferred-import-evaluation.js.snap deleted file mode 100644 index e461c5188ece..000000000000 --- a/crates/biome_js_formatter/tests/specs/prettier/js/babel-plugins/deferred-import-evaluation.js.snap +++ /dev/null @@ -1,47 +0,0 @@ ---- -source: crates/biome_formatter_test/src/snapshot_builder.rs -info: js/babel-plugins/deferred-import-evaluation.js ---- - -# Input - -```js -import defer * as ns from "x"; - -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Biome -@@ -1 +1,2 @@ --import defer * as ns from "x"; -+import defer -+* as ns from "x" -``` - -# Output - -```js -import defer -* as ns from "x" -``` - -# Errors -``` -deferred-import-evaluation.js:1:14 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × expected `from` but instead found `*` - - > 1 │ import defer * as ns from "x"; - │ ^ - 2 │ - - i Remove * - - -``` - - diff --git a/crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer-attributes-declaration.js.snap b/crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer-attributes-declaration.js.snap deleted file mode 100644 index 4dbe6f4f109b..000000000000 --- a/crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer-attributes-declaration.js.snap +++ /dev/null @@ -1,67 +0,0 @@ ---- -source: crates/biome_formatter_test/src/snapshot_builder.rs -info: js/deferred-import-evaluation/import-defer-attributes-declaration.js ---- - -# Input - -```js -import defer * as ns from "x" with { attr: "val" }; - -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Biome -@@ -1 +1,3 @@ --import defer * as ns from "x" with { attr: "val" }; -+import defer -+* as ns from "x" -+with { attr: "val" } -``` - -# Output - -```js -import defer -* as ns from "x" -with { attr: "val" } -``` - -# Errors -``` -import-defer-attributes-declaration.js:1:14 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × expected `from` but instead found `*` - - > 1 │ import defer * as ns from "x" with { attr: "val" }; - │ ^ - 2 │ - - i Remove * - -import-defer-attributes-declaration.js:1:36 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × expected `(` but instead found `{` - - > 1 │ import defer * as ns from "x" with { attr: "val" }; - │ ^ - 2 │ - - i Remove { - -import-defer-attributes-declaration.js:1:31 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × `with` statements are not allowed in strict mode - - > 1 │ import defer * as ns from "x" with { attr: "val" }; - │ ^^^^^^^^^^^^^^^^^^^^ - 2 │ - - -``` - - diff --git a/crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer.js.snap b/crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer.js.snap deleted file mode 100644 index a3478f4ad18d..000000000000 --- a/crates/biome_js_formatter/tests/specs/prettier/js/deferred-import-evaluation/import-defer.js.snap +++ /dev/null @@ -1,47 +0,0 @@ ---- -source: crates/biome_formatter_test/src/snapshot_builder.rs -info: js/deferred-import-evaluation/import-defer.js ---- - -# Input - -```js -import defer * as ns from "x"; - -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Biome -@@ -1 +1,2 @@ --import defer * as ns from "x"; -+import defer -+* as ns from "x" -``` - -# Output - -```js -import defer -* as ns from "x" -``` - -# Errors -``` -import-defer.js:1:14 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × expected `from` but instead found `*` - - > 1 │ import defer * as ns from "x"; - │ ^ - 2 │ - - i Remove * - - -``` - - diff --git a/crates/biome_js_parser/src/syntax/js_parse_error.rs b/crates/biome_js_parser/src/syntax/js_parse_error.rs index 7338ffa5aa42..a802e098781a 100644 --- a/crates/biome_js_parser/src/syntax/js_parse_error.rs +++ b/crates/biome_js_parser/src/syntax/js_parse_error.rs @@ -124,6 +124,17 @@ pub(crate) fn expected_module_source(p: &JsParser, range: TextRange) -> ParseDia } pub(crate) fn expected_named_import(p: &JsParser, range: TextRange) -> ParseDiagnostic { + expected_any(&["named imports"], range, p) +} + +pub(crate) fn expected_namespace_import(p: &JsParser, range: TextRange) -> ParseDiagnostic { + expected_any(&["namespace imports"], range, p) +} + +pub(crate) fn expected_namespace_or_named_import( + p: &JsParser, + range: TextRange, +) -> ParseDiagnostic { expected_any(&["namespace import", "named imports"], range, p) } diff --git a/crates/biome_js_parser/src/syntax/module.rs b/crates/biome_js_parser/src/syntax/module.rs index a8cb12b49fb3..5782e99b8d64 100644 --- a/crates/biome_js_parser/src/syntax/module.rs +++ b/crates/biome_js_parser/src/syntax/module.rs @@ -20,7 +20,7 @@ use crate::syntax::js_parse_error::{ decorators_not_allowed, duplicate_assertion_keys_error, expected_binding, expected_declaration, expected_export_clause, expected_export_default_declaration, expected_export_name_specifier, expected_expression, expected_identifier, expected_literal_export_name, expected_module_source, - expected_named_import, expected_named_import_specifier, expected_statement, + expected_named_import_specifier, expected_namespace_or_named_import, expected_statement, }; use crate::syntax::stmt::{parse_statement, semi, StatementContext, STMT_RECOVERY_SET}; use crate::syntax::typescript::ts_parse_error::ts_only_syntax_error; @@ -39,6 +39,7 @@ use biome_parser::ParserProgress; use rustc_hash::FxHashMap; use super::auxiliary::{is_nth_at_declaration_clause, parse_declaration_clause}; +use super::js_parse_error::{expected_named_import, expected_namespace_import}; // test js module // import a from "b"; @@ -296,8 +297,10 @@ fn parse_import_clause(p: &mut JsParser) -> ParsedSyntax { T![*] => parse_import_namespace_clause_rest(p, m), T!['{'] => parse_import_named_clause_rest(p, m), _ if is_at_identifier_binding(p) => { + let default_specifier = p.start(); parse_identifier_binding(p).unwrap(); - parse_import_default_or_named_clause_rest(p, m, is_typed) + default_specifier.complete(p, JS_DEFAULT_IMPORT_SPECIFIER); + parse_import_default_clauses_rest(p, m, is_typed) } _ => { // SAFETY: Safe because the parser only eats the "type" keyword if it's followed by @@ -317,47 +320,42 @@ fn parse_import_clause(p: &mut JsParser) -> ParsedSyntax { } } -/// Parses the rest of an import named or default clause. +// test js import_default_clauses +// import e, { f } from "b"; + +// import g, * as lorem from "c"; +/// Parses the rest of a default clause or default named clause. /// Rest meaning, everything after `type binding` -fn parse_import_default_or_named_clause_rest( +fn parse_import_default_clauses_rest( p: &mut JsParser, m: Marker, is_typed: bool, ) -> CompletedMarker { - match p.cur() { - T![,] | T!['{'] => { + let syntax_type = match p.cur() { + T![,] | T!['{'] | T![*] => { p.expect(T![,]); - - let default_specifier = m.complete(p, JS_DEFAULT_IMPORT_SPECIFIER); - let default_start = default_specifier.range(p).start(); - - let named_clause = default_specifier.precede(p); - - parse_named_import(p).or_add_diagnostic(p, expected_named_import); - + match p.cur() { + T![*] => parse_namespace_import_specifier(p), + _ => parse_named_import_specifier_list(p), + } + .or_add_diagnostic(p, expected_namespace_or_named_import); if is_typed { + let start = m.start(); let end = p.last_end().unwrap_or_else(|| p.cur_range().start()); // test_err ts ts_typed_default_import_with_named // import type A, { B, C } from './a'; p.error(p.err_builder("A type-only import can specify a default import or named bindings, but not both.", - default_start..end,)) + start..end,)) } - - p.expect(T![from]); - parse_module_source(p).or_add_diagnostic(p, expected_module_source); - parse_import_assertion(p).ok(); - - named_clause.complete(p, JS_IMPORT_NAMED_CLAUSE) - } - _ => { - p.expect(T![from]); - parse_module_source(p).or_add_diagnostic(p, expected_module_source); - parse_import_assertion(p).ok(); - - m.complete(p, JS_IMPORT_DEFAULT_CLAUSE) + JS_IMPORT_DEFAULT_EXTRA_CLAUSE } - } + _ => JS_IMPORT_DEFAULT_CLAUSE, + }; + p.expect(T![from]); + parse_module_source(p).or_add_diagnostic(p, expected_module_source); + parse_import_assertion(p).ok(); + m.complete(p, syntax_type) } // test js import_bare_clause @@ -374,10 +372,7 @@ fn parse_import_bare_clause(p: &mut JsParser) -> ParsedSyntax { // test js import_decl // import * as foo from "bla"; fn parse_import_namespace_clause_rest(p: &mut JsParser, m: Marker) -> CompletedMarker { - p.expect(T![*]); - - p.expect(T![as]); - parse_binding(p).or_add_diagnostic(p, expected_binding); + parse_namespace_import_specifier(p).or_add_diagnostic(p, expected_namespace_import); p.expect(T![from]); parse_module_source(p).or_add_diagnostic(p, expected_module_source); parse_import_assertion(p).ok(); @@ -388,12 +383,9 @@ fn parse_import_namespace_clause_rest(p: &mut JsParser, m: Marker) -> CompletedM // test js import_named_clause // import {} from "a"; // import { a, b, c, } from "b"; -// import e, { f } from "b"; -// import g, * as lorem from "c"; // import { f as x, default as w, "a-b-c" as y } from "b"; fn parse_import_named_clause_rest(p: &mut JsParser, m: Marker) -> CompletedMarker { - parse_default_import_specifier(p).ok(); - parse_named_import(p).or_add_diagnostic(p, expected_named_import); + parse_named_import_specifier_list(p).or_add_diagnostic(p, expected_named_import); p.expect(T![from]); parse_module_source(p).or_add_diagnostic(p, expected_module_source); parse_import_assertion(p).ok(); @@ -401,21 +393,6 @@ fn parse_import_named_clause_rest(p: &mut JsParser, m: Marker) -> CompletedMarke m.complete(p, JS_IMPORT_NAMED_CLAUSE) } -fn parse_default_import_specifier(p: &mut JsParser) -> ParsedSyntax { - parse_binding(p).map(|binding| { - let m = binding.precede(p); - p.expect(T![,]); - m.complete(p, JS_DEFAULT_IMPORT_SPECIFIER) - }) -} - -fn parse_named_import(p: &mut JsParser) -> ParsedSyntax { - match p.cur() { - T![*] => parse_namespace_import_specifier(p), - _ => parse_named_import_specifier_list(p), - } -} - fn parse_namespace_import_specifier(p: &mut JsParser) -> ParsedSyntax { if !p.at(T![*]) { return Absent; diff --git a/crates/biome_js_parser/test_data/inline/err/import_as_identifier_err.rast b/crates/biome_js_parser/test_data/inline/err/import_as_identifier_err.rast index f4ba161f26f2..7754de5f8b1e 100644 --- a/crates/biome_js_parser/test_data/inline/err/import_as_identifier_err.rast +++ b/crates/biome_js_parser/test_data/inline/err/import_as_identifier_err.rast @@ -7,8 +7,7 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@7..9 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -43,8 +42,7 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@7..27 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@7..16 + 1: JS_NAMED_IMPORT_SPECIFIERS@7..16 0: L_CURLY@7..9 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@9..14 0: JS_NAMED_IMPORT_SPECIFIER@9..14 @@ -54,10 +52,10 @@ JsModule { 3: JS_IDENTIFIER_BINDING@12..14 0: IDENT@12..14 "c" [] [Whitespace(" ")] 2: R_CURLY@14..16 "}" [] [Whitespace(" ")] - 3: FROM_KW@16..21 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@21..27 + 2: FROM_KW@16..21 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@21..27 0: JS_STRING_LITERAL@21..27 "\"test\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@27..28 ";" [] [] 4: EOF@28..29 "" [Newline("\n")] [] -- diff --git a/crates/biome_js_parser/test_data/inline/err/import_assertion_err.rast b/crates/biome_js_parser/test_data/inline/err/import_assertion_err.rast index 100833239522..56e6ee81ee9f 100644 --- a/crates/biome_js_parser/test_data/inline/err/import_assertion_err.rast +++ b/crates/biome_js_parser/test_data/inline/err/import_assertion_err.rast @@ -61,8 +61,7 @@ JsModule { import_token: IMPORT_KW@80..88 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@88..90 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -131,8 +130,10 @@ JsModule { import_token: IMPORT_KW@159..167 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@167..172 "foo2" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@167..172 "foo2" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@172..177 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -188,8 +189,10 @@ JsModule { import_token: IMPORT_KW@261..269 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@269..275 "ipsum" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@269..275 "ipsum" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@275..280 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -238,8 +241,7 @@ JsModule { import_token: IMPORT_KW@345..353 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@353..355 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -312,8 +314,7 @@ JsModule { 0: IMPORT_KW@80..88 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@88..119 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@88..96 + 1: JS_NAMED_IMPORT_SPECIFIERS@88..96 0: L_CURLY@88..90 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@90..94 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@90..94 @@ -321,9 +322,9 @@ JsModule { 1: JS_IDENTIFIER_BINDING@90..94 0: IDENT@90..94 "foo" [] [Whitespace(" ")] 2: R_CURLY@94..96 "}" [] [Whitespace(" ")] + 2: (empty) 3: (empty) - 4: (empty) - 5: JS_IMPORT_ASSERTION@96..119 + 4: JS_IMPORT_ASSERTION@96..119 0: ASSERT_KW@96..103 "assert" [] [Whitespace(" ")] 1: L_CURLY@103..105 "{" [] [Whitespace(" ")] 2: JS_IMPORT_ASSERTION_ENTRY_LIST@105..118 @@ -361,8 +362,9 @@ JsModule { 0: IMPORT_KW@159..167 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@167..241 0: (empty) - 1: JS_IDENTIFIER_BINDING@167..172 - 0: IDENT@167..172 "foo2" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@167..172 + 0: JS_IDENTIFIER_BINDING@167..172 + 0: IDENT@167..172 "foo2" [] [Whitespace(" ")] 2: FROM_KW@172..177 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@177..188 0: JS_STRING_LITERAL@177..188 "\"foo.json\"" [] [Whitespace(" ")] @@ -401,8 +403,9 @@ JsModule { 0: IMPORT_KW@261..269 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@269..344 0: (empty) - 1: JS_IDENTIFIER_BINDING@269..275 - 0: IDENT@269..275 "ipsum" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@269..275 + 0: JS_IDENTIFIER_BINDING@269..275 + 0: IDENT@269..275 "ipsum" [] [Whitespace(" ")] 2: FROM_KW@275..280 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@280..293 0: JS_STRING_LITERAL@280..293 "\"ipsum.json\"" [] [Whitespace(" ")] @@ -438,8 +441,7 @@ JsModule { 0: IMPORT_KW@345..353 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@353..379 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@353..359 + 1: JS_NAMED_IMPORT_SPECIFIERS@353..359 0: L_CURLY@353..355 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@355..357 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@355..357 @@ -447,10 +449,10 @@ JsModule { 1: JS_IDENTIFIER_BINDING@355..357 0: IDENT@355..357 "a" [] [Whitespace(" ")] 2: R_CURLY@357..359 "}" [] [Whitespace(" ")] - 3: FROM_KW@359..364 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@364..373 + 2: FROM_KW@359..364 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@364..373 0: JS_STRING_LITERAL@364..373 "\"a.json\"" [] [Whitespace(" ")] - 5: JS_IMPORT_ASSERTION@373..379 + 4: JS_IMPORT_ASSERTION@373..379 0: ASSERT_KW@373..379 "assert" [] [] 1: (empty) 2: JS_IMPORT_ASSERTION_ENTRY_LIST@379..379 diff --git a/crates/biome_js_parser/test_data/inline/err/import_attribute_err.rast b/crates/biome_js_parser/test_data/inline/err/import_attribute_err.rast index c220c4e2b44e..d7b0cb42cca5 100644 --- a/crates/biome_js_parser/test_data/inline/err/import_attribute_err.rast +++ b/crates/biome_js_parser/test_data/inline/err/import_attribute_err.rast @@ -34,8 +34,7 @@ JsModule { import_token: IMPORT_KW@35..43 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@43..45 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -104,8 +103,10 @@ JsModule { import_token: IMPORT_KW@112..120 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@120..125 "foo2" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@120..125 "foo2" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@125..130 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -161,8 +162,10 @@ JsModule { import_token: IMPORT_KW@210..218 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@218..224 "ipsum" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@218..224 "ipsum" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@224..229 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -211,8 +214,7 @@ JsModule { import_token: IMPORT_KW@292..300 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@300..302 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -270,8 +272,7 @@ JsModule { 0: IMPORT_KW@35..43 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@43..72 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@43..51 + 1: JS_NAMED_IMPORT_SPECIFIERS@43..51 0: L_CURLY@43..45 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@45..49 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@45..49 @@ -279,9 +280,9 @@ JsModule { 1: JS_IDENTIFIER_BINDING@45..49 0: IDENT@45..49 "foo" [] [Whitespace(" ")] 2: R_CURLY@49..51 "}" [] [Whitespace(" ")] + 2: (empty) 3: (empty) - 4: (empty) - 5: JS_IMPORT_ASSERTION@51..72 + 4: JS_IMPORT_ASSERTION@51..72 0: WITH_KW@51..56 "with" [] [Whitespace(" ")] 1: L_CURLY@56..58 "{" [] [Whitespace(" ")] 2: JS_IMPORT_ASSERTION_ENTRY_LIST@58..71 @@ -319,8 +320,9 @@ JsModule { 0: IMPORT_KW@112..120 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@120..192 0: (empty) - 1: JS_IDENTIFIER_BINDING@120..125 - 0: IDENT@120..125 "foo2" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@120..125 + 0: JS_IDENTIFIER_BINDING@120..125 + 0: IDENT@120..125 "foo2" [] [Whitespace(" ")] 2: FROM_KW@125..130 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@130..141 0: JS_STRING_LITERAL@130..141 "\"foo.json\"" [] [Whitespace(" ")] @@ -359,8 +361,9 @@ JsModule { 0: IMPORT_KW@210..218 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@218..291 0: (empty) - 1: JS_IDENTIFIER_BINDING@218..224 - 0: IDENT@218..224 "ipsum" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@218..224 + 0: JS_IDENTIFIER_BINDING@218..224 + 0: IDENT@218..224 "ipsum" [] [Whitespace(" ")] 2: FROM_KW@224..229 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@229..242 0: JS_STRING_LITERAL@229..242 "\"ipsum.json\"" [] [Whitespace(" ")] @@ -396,8 +399,7 @@ JsModule { 0: IMPORT_KW@292..300 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@300..324 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@300..306 + 1: JS_NAMED_IMPORT_SPECIFIERS@300..306 0: L_CURLY@300..302 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@302..304 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@302..304 @@ -405,10 +407,10 @@ JsModule { 1: JS_IDENTIFIER_BINDING@302..304 0: IDENT@302..304 "a" [] [Whitespace(" ")] 2: R_CURLY@304..306 "}" [] [Whitespace(" ")] - 3: FROM_KW@306..311 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@311..320 + 2: FROM_KW@306..311 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@311..320 0: JS_STRING_LITERAL@311..320 "\"a.json\"" [] [Whitespace(" ")] - 5: JS_IMPORT_ASSERTION@320..324 + 4: JS_IMPORT_ASSERTION@320..324 0: WITH_KW@320..324 "with" [] [] 1: (empty) 2: JS_IMPORT_ASSERTION_ENTRY_LIST@324..324 diff --git a/crates/biome_js_parser/test_data/inline/err/import_decl_not_top_level.rast b/crates/biome_js_parser/test_data/inline/err/import_decl_not_top_level.rast index 7522521d5352..3db1686c5362 100644 --- a/crates/biome_js_parser/test_data/inline/err/import_decl_not_top_level.rast +++ b/crates/biome_js_parser/test_data/inline/err/import_decl_not_top_level.rast @@ -11,8 +11,10 @@ JsModule { IMPORT_KW@1..10 "import" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@10..14 "foo" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@10..14 "foo" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@14..19 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -42,8 +44,9 @@ JsModule { 0: IMPORT_KW@1..10 "import" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@10..24 0: (empty) - 1: JS_IDENTIFIER_BINDING@10..14 - 0: IDENT@10..14 "foo" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@10..14 + 0: JS_IDENTIFIER_BINDING@10..14 + 0: IDENT@10..14 "foo" [] [Whitespace(" ")] 2: FROM_KW@14..19 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@19..24 0: JS_STRING_LITERAL@19..24 "\"bar\"" [] [] diff --git a/crates/biome_js_parser/test_data/inline/err/import_err.rast b/crates/biome_js_parser/test_data/inline/err/import_err.rast index b24323fc57a5..33550b72d731 100644 --- a/crates/biome_js_parser/test_data/inline/err/import_err.rast +++ b/crates/biome_js_parser/test_data/inline/err/import_err.rast @@ -12,9 +12,11 @@ JsModule { import_token: IMPORT_KW@7..15 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamespaceClause { type_token: missing (optional), - star_token: STAR@15..16 "*" [] [], - as_token: missing (required), - local_name: missing (required), + namespace_specifier: JsNamespaceImportSpecifier { + star_token: STAR@15..16 "*" [] [], + as_token: missing (required), + local_name: missing (required), + }, from_token: missing (required), source: missing (required), assertion: missing (optional), @@ -25,10 +27,12 @@ JsModule { import_token: IMPORT_KW@17..25 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamespaceClause { type_token: missing (optional), - star_token: STAR@25..27 "*" [] [Whitespace(" ")], - as_token: AS_KW@27..30 "as" [] [Whitespace(" ")], - local_name: JsIdentifierBinding { - name_token: IDENT@30..31 "c" [] [], + namespace_specifier: JsNamespaceImportSpecifier { + star_token: STAR@25..27 "*" [] [Whitespace(" ")], + as_token: AS_KW@27..30 "as" [] [Whitespace(" ")], + local_name: JsIdentifierBinding { + name_token: IDENT@30..31 "c" [] [], + }, }, from_token: missing (required), source: missing (required), @@ -81,8 +85,7 @@ JsModule { import_token: IMPORT_KW@51..59 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@59..61 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -120,8 +123,7 @@ JsModule { import_token: IMPORT_KW@84..92 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@92..94 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -152,8 +154,7 @@ JsModule { import_token: IMPORT_KW@112..120 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@120..122 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -179,8 +180,7 @@ JsModule { import_token: IMPORT_KW@141..149 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@149..151 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -206,8 +206,7 @@ JsModule { import_token: IMPORT_KW@166..174 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@174..176 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -258,8 +257,10 @@ JsModule { import_token: IMPORT_KW@211..219 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@219..221 "y" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@219..221 "y" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@221..226 "from" [] [Whitespace(" ")], source: missing (required), @@ -290,24 +291,26 @@ JsModule { 0: IMPORT_KW@7..15 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMESPACE_CLAUSE@15..16 0: (empty) - 1: STAR@15..16 "*" [] [] + 1: JS_NAMESPACE_IMPORT_SPECIFIER@15..16 + 0: STAR@15..16 "*" [] [] + 1: (empty) + 2: (empty) 2: (empty) 3: (empty) 4: (empty) - 5: (empty) - 6: (empty) 2: SEMICOLON@16..17 ";" [] [] 2: JS_IMPORT@17..31 0: IMPORT_KW@17..25 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMESPACE_CLAUSE@25..31 0: (empty) - 1: STAR@25..27 "*" [] [Whitespace(" ")] - 2: AS_KW@27..30 "as" [] [Whitespace(" ")] - 3: JS_IDENTIFIER_BINDING@30..31 - 0: IDENT@30..31 "c" [] [] + 1: JS_NAMESPACE_IMPORT_SPECIFIER@25..31 + 0: STAR@25..27 "*" [] [Whitespace(" ")] + 1: AS_KW@27..30 "as" [] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@30..31 + 0: IDENT@30..31 "c" [] [] + 2: (empty) + 3: (empty) 4: (empty) - 5: (empty) - 6: (empty) 2: (empty) 3: JS_BOGUS_STATEMENT@31..33 0: COMMA@31..33 "," [] [Whitespace(" ")] @@ -338,8 +341,7 @@ JsModule { 0: IMPORT_KW@51..59 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@59..83 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@59..75 + 1: JS_NAMED_IMPORT_SPECIFIERS@59..75 0: L_CURLY@59..61 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@61..73 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@61..64 @@ -356,17 +358,16 @@ JsModule { 1: JS_IDENTIFIER_BINDING@70..73 0: IDENT@70..73 "dd" [] [Whitespace(" ")] 2: R_CURLY@73..75 "}" [] [Whitespace(" ")] - 3: FROM_KW@75..80 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@80..83 + 2: FROM_KW@75..80 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@80..83 0: JS_STRING_LITERAL@80..83 "\"c\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@83..84 ";" [] [] 8: JS_IMPORT@84..112 0: IMPORT_KW@84..92 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@92..111 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@92..103 + 1: JS_NAMED_IMPORT_SPECIFIERS@92..103 0: L_CURLY@92..94 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@94..101 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@94..96 @@ -379,17 +380,16 @@ JsModule { 1: JS_IDENTIFIER_BINDING@98..101 0: IDENT@98..101 "ac" [] [Whitespace(" ")] 2: R_CURLY@101..103 "}" [] [Whitespace(" ")] - 3: FROM_KW@103..108 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@108..111 + 2: FROM_KW@103..108 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@108..111 0: JS_STRING_LITERAL@108..111 "\"c\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@111..112 ";" [] [] 9: JS_IMPORT@112..141 0: IMPORT_KW@112..120 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@120..140 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@120..132 + 1: JS_NAMED_IMPORT_SPECIFIERS@120..132 0: L_CURLY@120..122 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@122..130 0: JS_NAMED_IMPORT_SPECIFIER@122..130 @@ -399,17 +399,16 @@ JsModule { 2: (empty) 3: (empty) 2: R_CURLY@130..132 "}" [] [Whitespace(" ")] - 3: FROM_KW@132..137 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@137..140 + 2: FROM_KW@132..137 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@137..140 0: JS_STRING_LITERAL@137..140 "\"c\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@140..141 ";" [] [] 10: JS_IMPORT@141..166 0: IMPORT_KW@141..149 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@149..165 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@149..157 + 1: JS_NAMED_IMPORT_SPECIFIERS@149..157 0: L_CURLY@149..151 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@151..155 0: JS_NAMED_IMPORT_SPECIFIER@151..155 @@ -419,17 +418,16 @@ JsModule { 2: (empty) 3: (empty) 2: R_CURLY@155..157 "}" [] [Whitespace(" ")] - 3: FROM_KW@157..162 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@162..165 + 2: FROM_KW@157..162 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@162..165 0: JS_STRING_LITERAL@162..165 "\"c\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@165..166 ";" [] [] 11: JS_IMPORT@166..192 0: IMPORT_KW@166..174 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@174..191 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@174..183 + 1: JS_NAMED_IMPORT_SPECIFIERS@174..183 0: L_CURLY@174..176 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@176..181 0: JS_NAMED_IMPORT_SPECIFIER@176..181 @@ -439,10 +437,10 @@ JsModule { 3: JS_IDENTIFIER_BINDING@179..181 0: IDENT@179..181 "x" [] [Whitespace(" ")] 2: R_CURLY@181..183 "}" [] [Whitespace(" ")] - 3: FROM_KW@183..188 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@188..191 + 2: FROM_KW@183..188 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@188..191 0: JS_STRING_LITERAL@188..191 "\"c\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@191..192 ";" [] [] 12: JS_IMPORT@192..200 0: IMPORT_KW@192..200 "import" [Newline("\n")] [Whitespace(" ")] @@ -465,8 +463,9 @@ JsModule { 0: IMPORT_KW@211..219 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@219..226 0: (empty) - 1: JS_IDENTIFIER_BINDING@219..221 - 0: IDENT@219..221 "y" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@219..221 + 0: JS_IDENTIFIER_BINDING@219..221 + 0: IDENT@219..221 "y" [] [Whitespace(" ")] 2: FROM_KW@221..226 "from" [] [Whitespace(" ")] 3: (empty) 4: (empty) diff --git a/crates/biome_js_parser/test_data/inline/err/ts_named_import_specifier_error.rast b/crates/biome_js_parser/test_data/inline/err/ts_named_import_specifier_error.rast index 0b9d9703d340..d7651765879b 100644 --- a/crates/biome_js_parser/test_data/inline/err/ts_named_import_specifier_error.rast +++ b/crates/biome_js_parser/test_data/inline/err/ts_named_import_specifier_error.rast @@ -7,8 +7,7 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@7..9 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -34,8 +33,7 @@ JsModule { import_token: IMPORT_KW@32..40 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@40..42 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -61,8 +59,7 @@ JsModule { import_token: IMPORT_KW@70..78 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@78..80 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -88,8 +85,7 @@ JsModule { import_token: IMPORT_KW@110..118 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@118..120 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -115,8 +111,7 @@ JsModule { import_token: IMPORT_KW@155..163 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@163..164 "{" [] [], specifiers: JsNamedImportSpecifierList [], r_curly_token: missing (required), @@ -140,8 +135,7 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@7..31 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@7..19 + 1: JS_NAMED_IMPORT_SPECIFIERS@7..19 0: L_CURLY@7..9 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@9..17 0: JS_NAMED_IMPORT_SPECIFIER@9..17 @@ -151,17 +145,16 @@ JsModule { 2: (empty) 3: (empty) 2: R_CURLY@17..19 "}" [] [Whitespace(" ")] - 3: FROM_KW@19..24 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@24..31 + 2: FROM_KW@19..24 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@24..31 0: JS_STRING_LITERAL@24..31 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@31..32 ";" [] [] 1: JS_IMPORT@32..70 0: IMPORT_KW@32..40 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@40..69 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@40..57 + 1: JS_NAMED_IMPORT_SPECIFIERS@40..57 0: L_CURLY@40..42 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@42..55 0: JS_NAMED_IMPORT_SPECIFIER@42..55 @@ -171,17 +164,16 @@ JsModule { 2: (empty) 3: (empty) 2: R_CURLY@55..57 "}" [] [Whitespace(" ")] - 3: FROM_KW@57..62 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@62..69 + 2: FROM_KW@57..62 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@62..69 0: JS_STRING_LITERAL@62..69 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@69..70 ";" [] [] 2: JS_IMPORT@70..110 0: IMPORT_KW@70..78 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@78..109 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@78..97 + 1: JS_NAMED_IMPORT_SPECIFIERS@78..97 0: L_CURLY@78..80 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@80..95 0: JS_NAMED_IMPORT_SPECIFIER@80..95 @@ -191,17 +183,16 @@ JsModule { 2: (empty) 3: (empty) 2: R_CURLY@95..97 "}" [] [Whitespace(" ")] - 3: FROM_KW@97..102 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@102..109 + 2: FROM_KW@97..102 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@102..109 0: JS_STRING_LITERAL@102..109 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@109..110 ";" [] [] 3: JS_IMPORT@110..155 0: IMPORT_KW@110..118 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@118..154 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@118..142 + 1: JS_NAMED_IMPORT_SPECIFIERS@118..142 0: L_CURLY@118..120 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@120..140 0: JS_NAMED_IMPORT_SPECIFIER@120..140 @@ -211,23 +202,22 @@ JsModule { 2: (empty) 3: (empty) 2: R_CURLY@140..142 "}" [] [Whitespace(" ")] - 3: FROM_KW@142..147 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@147..154 + 2: FROM_KW@142..147 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@147..154 0: JS_STRING_LITERAL@147..154 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@154..155 ";" [] [] 4: JS_IMPORT@155..164 0: IMPORT_KW@155..163 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@163..164 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@163..164 + 1: JS_NAMED_IMPORT_SPECIFIERS@163..164 0: L_CURLY@163..164 "{" [] [] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@164..164 2: (empty) + 2: (empty) 3: (empty) 4: (empty) - 5: (empty) 2: (empty) 4: EOF@164..165 "" [Newline("\n")] [] -- diff --git a/crates/biome_js_parser/test_data/inline/err/ts_typed_default_import_with_named.rast b/crates/biome_js_parser/test_data/inline/err/ts_typed_default_import_with_named.rast index 4b1bfc8824ef..07e47a565dbc 100644 --- a/crates/biome_js_parser/test_data/inline/err/ts_typed_default_import_with_named.rast +++ b/crates/biome_js_parser/test_data/inline/err/ts_typed_default_import_with_named.rast @@ -8,15 +8,13 @@ JsModule { IMPORT_KW@0..7 "import" [] [Whitespace(" ")], JsBogus { items: [ - JsBogus { - items: [ - TYPE_KW@7..12 "type" [] [Whitespace(" ")], - JsIdentifierBinding { - name_token: IDENT@12..13 "A" [] [], - }, - COMMA@13..15 "," [] [Whitespace(" ")], - ], + TYPE_KW@7..12 "type" [] [Whitespace(" ")], + JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@12..13 "A" [] [], + }, }, + COMMA@13..15 "," [] [Whitespace(" ")], JsNamedImportSpecifiers { l_curly_token: L_CURLY@15..17 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ @@ -57,12 +55,12 @@ JsModule { 0: JS_BOGUS_STATEMENT@0..35 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_BOGUS@7..34 - 0: JS_BOGUS@7..15 - 0: TYPE_KW@7..12 "type" [] [Whitespace(" ")] - 1: JS_IDENTIFIER_BINDING@12..13 + 0: TYPE_KW@7..12 "type" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@12..13 + 0: JS_IDENTIFIER_BINDING@12..13 0: IDENT@12..13 "A" [] [] - 2: COMMA@13..15 "," [] [Whitespace(" ")] - 1: JS_NAMED_IMPORT_SPECIFIERS@15..24 + 2: COMMA@13..15 "," [] [Whitespace(" ")] + 3: JS_NAMED_IMPORT_SPECIFIERS@15..24 0: L_CURLY@15..17 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@17..22 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@17..18 @@ -75,8 +73,8 @@ JsModule { 1: JS_IDENTIFIER_BINDING@20..22 0: IDENT@20..22 "C" [] [Whitespace(" ")] 2: R_CURLY@22..24 "}" [] [Whitespace(" ")] - 2: FROM_KW@24..29 "from" [] [Whitespace(" ")] - 3: JS_MODULE_SOURCE@29..34 + 4: FROM_KW@24..29 "from" [] [Whitespace(" ")] + 5: JS_MODULE_SOURCE@29..34 0: JS_STRING_LITERAL@29..34 "'./a'" [] [] 2: SEMICOLON@34..35 ";" [] [] 4: EOF@35..36 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_as_as_as_identifier.rast b/crates/biome_js_parser/test_data/inline/ok/import_as_as_as_identifier.rast index 5797441e93bc..5dc1a7efe871 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_as_as_as_identifier.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_as_as_as_identifier.rast @@ -7,8 +7,7 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@7..9 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -45,8 +44,7 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@7..31 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@7..20 + 1: JS_NAMED_IMPORT_SPECIFIERS@7..20 0: L_CURLY@7..9 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@9..18 0: JS_NAMED_IMPORT_SPECIFIER@9..18 @@ -57,9 +55,9 @@ JsModule { 3: JS_IDENTIFIER_BINDING@15..18 0: IDENT@15..18 "as" [] [Whitespace(" ")] 2: R_CURLY@18..20 "}" [] [Whitespace(" ")] - 3: FROM_KW@20..25 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@25..31 + 2: FROM_KW@20..25 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@25..31 0: JS_STRING_LITERAL@25..31 "\"test\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@31..32 ";" [] [] 4: EOF@32..33 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_as_identifier.rast b/crates/biome_js_parser/test_data/inline/ok/import_as_identifier.rast index 4790da6346dd..abd11356bc90 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_as_identifier.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_as_identifier.rast @@ -7,8 +7,7 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@7..9 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -41,8 +40,7 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@7..25 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@7..14 + 1: JS_NAMED_IMPORT_SPECIFIERS@7..14 0: L_CURLY@7..9 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@9..12 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@9..12 @@ -50,9 +48,9 @@ JsModule { 1: JS_IDENTIFIER_BINDING@9..12 0: IDENT@9..12 "as" [] [Whitespace(" ")] 2: R_CURLY@12..14 "}" [] [Whitespace(" ")] - 3: FROM_KW@14..19 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@19..25 + 2: FROM_KW@14..19 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@19..25 0: JS_STRING_LITERAL@19..25 "\"test\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@25..26 ";" [] [] 4: EOF@26..27 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_assertion.rast b/crates/biome_js_parser/test_data/inline/ok/import_assertion.rast index b1cc2e5b7888..1a633c69035b 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_assertion.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_assertion.rast @@ -49,8 +49,10 @@ JsModule { import_token: IMPORT_KW@74..82 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@82..86 "foo" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@82..86 "foo" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@86..91 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -75,8 +77,7 @@ JsModule { import_token: IMPORT_KW@126..134 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@134..135 "{" [] [], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -111,8 +112,10 @@ JsModule { import_token: IMPORT_KW@178..186 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@186..195 "foo_json" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@186..195 "foo_json" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@195..200 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -203,8 +206,9 @@ JsModule { 0: IMPORT_KW@74..82 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@82..125 0: (empty) - 1: JS_IDENTIFIER_BINDING@82..86 - 0: IDENT@82..86 "foo" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@82..86 + 0: JS_IDENTIFIER_BINDING@82..86 + 0: IDENT@82..86 "foo" [] [Whitespace(" ")] 2: FROM_KW@86..91 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@91..102 0: JS_STRING_LITERAL@91..102 "\"foo.json\"" [] [Whitespace(" ")] @@ -222,8 +226,7 @@ JsModule { 0: IMPORT_KW@126..134 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@134..178 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@134..141 + 1: JS_NAMED_IMPORT_SPECIFIERS@134..141 0: L_CURLY@134..135 "{" [] [] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@135..139 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@135..139 @@ -231,10 +234,10 @@ JsModule { 1: JS_IDENTIFIER_BINDING@135..139 0: IDENT@135..139 "test" [] [] 2: R_CURLY@139..141 "}" [] [Whitespace(" ")] - 3: FROM_KW@141..146 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@146..157 + 2: FROM_KW@141..146 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@146..157 0: JS_STRING_LITERAL@146..157 "\"foo.json\"" [] [Whitespace(" ")] - 5: JS_IMPORT_ASSERTION@157..178 + 4: JS_IMPORT_ASSERTION@157..178 0: ASSERT_KW@157..164 "assert" [] [Whitespace(" ")] 1: L_CURLY@164..166 "{" [] [Whitespace(" ")] 2: JS_IMPORT_ASSERTION_ENTRY_LIST@166..177 @@ -248,8 +251,9 @@ JsModule { 0: IMPORT_KW@178..186 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@186..258 0: (empty) - 1: JS_IDENTIFIER_BINDING@186..195 - 0: IDENT@186..195 "foo_json" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@186..195 + 0: JS_IDENTIFIER_BINDING@186..195 + 0: IDENT@186..195 "foo_json" [] [Whitespace(" ")] 2: FROM_KW@195..200 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@200..211 0: JS_STRING_LITERAL@200..211 "\"foo.json\"" [] [Whitespace(" ")] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_attribute.rast b/crates/biome_js_parser/test_data/inline/ok/import_attribute.rast index ec43e6726045..a8db8ee4574a 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_attribute.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_attribute.rast @@ -49,8 +49,10 @@ JsModule { import_token: IMPORT_KW@70..78 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@78..82 "foo" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@78..82 "foo" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@82..87 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -75,8 +77,7 @@ JsModule { import_token: IMPORT_KW@120..128 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@128..129 "{" [] [], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -111,8 +112,10 @@ JsModule { import_token: IMPORT_KW@170..178 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@178..187 "foo_json" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@178..187 "foo_json" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@187..192 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -203,8 +206,9 @@ JsModule { 0: IMPORT_KW@70..78 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@78..119 0: (empty) - 1: JS_IDENTIFIER_BINDING@78..82 - 0: IDENT@78..82 "foo" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@78..82 + 0: JS_IDENTIFIER_BINDING@78..82 + 0: IDENT@78..82 "foo" [] [Whitespace(" ")] 2: FROM_KW@82..87 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@87..98 0: JS_STRING_LITERAL@87..98 "\"foo.json\"" [] [Whitespace(" ")] @@ -222,8 +226,7 @@ JsModule { 0: IMPORT_KW@120..128 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@128..170 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@128..135 + 1: JS_NAMED_IMPORT_SPECIFIERS@128..135 0: L_CURLY@128..129 "{" [] [] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@129..133 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@129..133 @@ -231,10 +234,10 @@ JsModule { 1: JS_IDENTIFIER_BINDING@129..133 0: IDENT@129..133 "test" [] [] 2: R_CURLY@133..135 "}" [] [Whitespace(" ")] - 3: FROM_KW@135..140 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@140..151 + 2: FROM_KW@135..140 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@140..151 0: JS_STRING_LITERAL@140..151 "\"foo.json\"" [] [Whitespace(" ")] - 5: JS_IMPORT_ASSERTION@151..170 + 4: JS_IMPORT_ASSERTION@151..170 0: WITH_KW@151..156 "with" [] [Whitespace(" ")] 1: L_CURLY@156..158 "{" [] [Whitespace(" ")] 2: JS_IMPORT_ASSERTION_ENTRY_LIST@158..169 @@ -248,8 +251,9 @@ JsModule { 0: IMPORT_KW@170..178 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@178..248 0: (empty) - 1: JS_IDENTIFIER_BINDING@178..187 - 0: IDENT@178..187 "foo_json" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@178..187 + 0: JS_IDENTIFIER_BINDING@178..187 + 0: IDENT@178..187 "foo_json" [] [Whitespace(" ")] 2: FROM_KW@187..192 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@192..203 0: JS_STRING_LITERAL@192..203 "\"foo.json\"" [] [Whitespace(" ")] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_decl.rast b/crates/biome_js_parser/test_data/inline/ok/import_decl.rast index eac9767b6a52..7b59b6d531a6 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_decl.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_decl.rast @@ -7,10 +7,12 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportNamespaceClause { type_token: missing (optional), - star_token: STAR@7..9 "*" [] [Whitespace(" ")], - as_token: AS_KW@9..12 "as" [] [Whitespace(" ")], - local_name: JsIdentifierBinding { - name_token: IDENT@12..16 "foo" [] [Whitespace(" ")], + namespace_specifier: JsNamespaceImportSpecifier { + star_token: STAR@7..9 "*" [] [Whitespace(" ")], + as_token: AS_KW@9..12 "as" [] [Whitespace(" ")], + local_name: JsIdentifierBinding { + name_token: IDENT@12..16 "foo" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@16..21 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -33,13 +35,14 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_NAMESPACE_CLAUSE@7..26 0: (empty) - 1: STAR@7..9 "*" [] [Whitespace(" ")] - 2: AS_KW@9..12 "as" [] [Whitespace(" ")] - 3: JS_IDENTIFIER_BINDING@12..16 - 0: IDENT@12..16 "foo" [] [Whitespace(" ")] - 4: FROM_KW@16..21 "from" [] [Whitespace(" ")] - 5: JS_MODULE_SOURCE@21..26 + 1: JS_NAMESPACE_IMPORT_SPECIFIER@7..16 + 0: STAR@7..9 "*" [] [Whitespace(" ")] + 1: AS_KW@9..12 "as" [] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@12..16 + 0: IDENT@12..16 "foo" [] [Whitespace(" ")] + 2: FROM_KW@16..21 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@21..26 0: JS_STRING_LITERAL@21..26 "\"bla\"" [] [] - 6: (empty) + 4: (empty) 2: SEMICOLON@26..27 ";" [] [] 4: EOF@27..28 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_default_clause.rast b/crates/biome_js_parser/test_data/inline/ok/import_default_clause.rast index 89416870b04f..256867c59fe5 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_default_clause.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_default_clause.rast @@ -7,8 +7,10 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@7..11 "foo" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@7..11 "foo" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@11..16 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -31,8 +33,9 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@7..22 0: (empty) - 1: JS_IDENTIFIER_BINDING@7..11 - 0: IDENT@7..11 "foo" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@7..11 + 0: JS_IDENTIFIER_BINDING@7..11 + 0: IDENT@7..11 "foo" [] [Whitespace(" ")] 2: FROM_KW@11..16 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@16..22 0: JS_STRING_LITERAL@16..22 "\"test\"" [] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.js b/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.js new file mode 100644 index 000000000000..08c1c8cae131 --- /dev/null +++ b/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.js @@ -0,0 +1 @@ +import e, { f } from "b"; diff --git a/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast b/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast new file mode 100644 index 000000000000..d5a737e178cb --- /dev/null +++ b/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast @@ -0,0 +1,64 @@ +JsModule { + bom_token: missing (optional), + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsImport { + import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], + import_clause: JsImportDefaultExtraClause { + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@7..8 "e" [] [], + }, + }, + comma_token: COMMA@8..10 "," [] [Whitespace(" ")], + extra_specifier: JsNamedImportSpecifiers { + l_curly_token: L_CURLY@10..12 "{" [] [Whitespace(" ")], + specifiers: JsNamedImportSpecifierList [ + JsShorthandNamedImportSpecifier { + type_token: missing (optional), + local_name: JsIdentifierBinding { + name_token: IDENT@12..14 "f" [] [Whitespace(" ")], + }, + }, + ], + r_curly_token: R_CURLY@14..16 "}" [] [Whitespace(" ")], + }, + from_token: FROM_KW@16..21 "from" [] [Whitespace(" ")], + source: JsModuleSource { + value_token: JS_STRING_LITERAL@21..24 "\"b\"" [] [], + }, + assertion: missing (optional), + }, + semicolon_token: SEMICOLON@24..25 ";" [] [], + }, + ], + eof_token: EOF@25..26 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..26 + 0: (empty) + 1: (empty) + 2: JS_DIRECTIVE_LIST@0..0 + 3: JS_MODULE_ITEM_LIST@0..25 + 0: JS_IMPORT@0..25 + 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] + 1: JS_IMPORT_DEFAULT_EXTRA_CLAUSE@7..24 + 0: JS_DEFAULT_IMPORT_SPECIFIER@7..8 + 0: JS_IDENTIFIER_BINDING@7..8 + 0: IDENT@7..8 "e" [] [] + 1: COMMA@8..10 "," [] [Whitespace(" ")] + 2: JS_NAMED_IMPORT_SPECIFIERS@10..16 + 0: L_CURLY@10..12 "{" [] [Whitespace(" ")] + 1: JS_NAMED_IMPORT_SPECIFIER_LIST@12..14 + 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@12..14 + 0: (empty) + 1: JS_IDENTIFIER_BINDING@12..14 + 0: IDENT@12..14 "f" [] [Whitespace(" ")] + 2: R_CURLY@14..16 "}" [] [Whitespace(" ")] + 3: FROM_KW@16..21 "from" [] [Whitespace(" ")] + 4: JS_MODULE_SOURCE@21..24 + 0: JS_STRING_LITERAL@21..24 "\"b\"" [] [] + 5: (empty) + 2: SEMICOLON@24..25 ";" [] [] + 4: EOF@25..26 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/import_named_clause.js b/crates/biome_js_parser/test_data/inline/ok/import_named_clause.js index 21214eff17cd..3c51b5a2d8cd 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_named_clause.js +++ b/crates/biome_js_parser/test_data/inline/ok/import_named_clause.js @@ -1,5 +1,3 @@ import {} from "a"; import { a, b, c, } from "b"; -import e, { f } from "b"; -import g, * as lorem from "c"; import { f as x, default as w, "a-b-c" as y } from "b"; diff --git a/crates/biome_js_parser/test_data/inline/ok/import_named_clause.rast b/crates/biome_js_parser/test_data/inline/ok/import_named_clause.rast index 190faa6ac67b..41242827a991 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_named_clause.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_named_clause.rast @@ -7,8 +7,7 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@7..8 "{" [] [], specifiers: JsNamedImportSpecifierList [], r_curly_token: R_CURLY@8..10 "}" [] [Whitespace(" ")], @@ -25,8 +24,7 @@ JsModule { import_token: IMPORT_KW@19..27 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@27..29 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -65,137 +63,79 @@ JsModule { import_token: IMPORT_KW@49..57 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: JsDefaultImportSpecifier { - local_name: JsIdentifierBinding { - name_token: IDENT@57..58 "e" [] [], - }, - trailing_comma_token: COMMA@58..60 "," [] [Whitespace(" ")], - }, - named_import: JsNamedImportSpecifiers { - l_curly_token: L_CURLY@60..62 "{" [] [Whitespace(" ")], - specifiers: JsNamedImportSpecifierList [ - JsShorthandNamedImportSpecifier { - type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@62..64 "f" [] [Whitespace(" ")], - }, - }, - ], - r_curly_token: R_CURLY@64..66 "}" [] [Whitespace(" ")], - }, - from_token: FROM_KW@66..71 "from" [] [Whitespace(" ")], - source: JsModuleSource { - value_token: JS_STRING_LITERAL@71..74 "\"b\"" [] [], - }, - assertion: missing (optional), - }, - semicolon_token: SEMICOLON@74..75 ";" [] [], - }, - JsImport { - import_token: IMPORT_KW@75..83 "import" [Newline("\n")] [Whitespace(" ")], - import_clause: JsImportNamedClause { - type_token: missing (optional), - default_specifier: JsDefaultImportSpecifier { - local_name: JsIdentifierBinding { - name_token: IDENT@83..84 "g" [] [], - }, - trailing_comma_token: COMMA@84..86 "," [] [Whitespace(" ")], - }, - named_import: JsNamespaceImportSpecifier { - star_token: STAR@86..88 "*" [] [Whitespace(" ")], - as_token: AS_KW@88..91 "as" [] [Whitespace(" ")], - local_name: JsIdentifierBinding { - name_token: IDENT@91..97 "lorem" [] [Whitespace(" ")], - }, - }, - from_token: FROM_KW@97..102 "from" [] [Whitespace(" ")], - source: JsModuleSource { - value_token: JS_STRING_LITERAL@102..105 "\"c\"" [] [], - }, - assertion: missing (optional), - }, - semicolon_token: SEMICOLON@105..106 ";" [] [], - }, - JsImport { - import_token: IMPORT_KW@106..114 "import" [Newline("\n")] [Whitespace(" ")], - import_clause: JsImportNamedClause { - type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { - l_curly_token: L_CURLY@114..116 "{" [] [Whitespace(" ")], + named_specifiers: JsNamedImportSpecifiers { + l_curly_token: L_CURLY@57..59 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { type_token: missing (optional), name: JsLiteralExportName { - value: IDENT@116..118 "f" [] [Whitespace(" ")], + value: IDENT@59..61 "f" [] [Whitespace(" ")], }, - as_token: AS_KW@118..121 "as" [] [Whitespace(" ")], + as_token: AS_KW@61..64 "as" [] [Whitespace(" ")], local_name: JsIdentifierBinding { - name_token: IDENT@121..122 "x" [] [], + name_token: IDENT@64..65 "x" [] [], }, }, - COMMA@122..124 "," [] [Whitespace(" ")], + COMMA@65..67 "," [] [Whitespace(" ")], JsNamedImportSpecifier { type_token: missing (optional), name: JsLiteralExportName { - value: IDENT@124..132 "default" [] [Whitespace(" ")], + value: IDENT@67..75 "default" [] [Whitespace(" ")], }, - as_token: AS_KW@132..135 "as" [] [Whitespace(" ")], + as_token: AS_KW@75..78 "as" [] [Whitespace(" ")], local_name: JsIdentifierBinding { - name_token: IDENT@135..136 "w" [] [], + name_token: IDENT@78..79 "w" [] [], }, }, - COMMA@136..138 "," [] [Whitespace(" ")], + COMMA@79..81 "," [] [Whitespace(" ")], JsNamedImportSpecifier { type_token: missing (optional), name: JsLiteralExportName { - value: JS_STRING_LITERAL@138..146 "\"a-b-c\"" [] [Whitespace(" ")], + value: JS_STRING_LITERAL@81..89 "\"a-b-c\"" [] [Whitespace(" ")], }, - as_token: AS_KW@146..149 "as" [] [Whitespace(" ")], + as_token: AS_KW@89..92 "as" [] [Whitespace(" ")], local_name: JsIdentifierBinding { - name_token: IDENT@149..151 "y" [] [Whitespace(" ")], + name_token: IDENT@92..94 "y" [] [Whitespace(" ")], }, }, ], - r_curly_token: R_CURLY@151..153 "}" [] [Whitespace(" ")], + r_curly_token: R_CURLY@94..96 "}" [] [Whitespace(" ")], }, - from_token: FROM_KW@153..158 "from" [] [Whitespace(" ")], + from_token: FROM_KW@96..101 "from" [] [Whitespace(" ")], source: JsModuleSource { - value_token: JS_STRING_LITERAL@158..161 "\"b\"" [] [], + value_token: JS_STRING_LITERAL@101..104 "\"b\"" [] [], }, assertion: missing (optional), }, - semicolon_token: SEMICOLON@161..162 ";" [] [], + semicolon_token: SEMICOLON@104..105 ";" [] [], }, ], - eof_token: EOF@162..163 "" [Newline("\n")] [], + eof_token: EOF@105..106 "" [Newline("\n")] [], } -0: JS_MODULE@0..163 +0: JS_MODULE@0..106 0: (empty) 1: (empty) 2: JS_DIRECTIVE_LIST@0..0 - 3: JS_MODULE_ITEM_LIST@0..162 + 3: JS_MODULE_ITEM_LIST@0..105 0: JS_IMPORT@0..19 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@7..18 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@7..10 + 1: JS_NAMED_IMPORT_SPECIFIERS@7..10 0: L_CURLY@7..8 "{" [] [] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@8..8 2: R_CURLY@8..10 "}" [] [Whitespace(" ")] - 3: FROM_KW@10..15 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@15..18 + 2: FROM_KW@10..15 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@15..18 0: JS_STRING_LITERAL@15..18 "\"a\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@18..19 ";" [] [] 1: JS_IMPORT@19..49 0: IMPORT_KW@19..27 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@27..48 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@27..40 + 1: JS_NAMED_IMPORT_SPECIFIERS@27..40 0: L_CURLY@27..29 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@29..38 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@29..30 @@ -214,85 +154,45 @@ JsModule { 0: IDENT@35..36 "c" [] [] 5: COMMA@36..38 "," [] [Whitespace(" ")] 2: R_CURLY@38..40 "}" [] [Whitespace(" ")] - 3: FROM_KW@40..45 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@45..48 + 2: FROM_KW@40..45 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@45..48 0: JS_STRING_LITERAL@45..48 "\"b\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@48..49 ";" [] [] - 2: JS_IMPORT@49..75 + 2: JS_IMPORT@49..105 0: IMPORT_KW@49..57 "import" [Newline("\n")] [Whitespace(" ")] - 1: JS_IMPORT_NAMED_CLAUSE@57..74 - 0: (empty) - 1: JS_DEFAULT_IMPORT_SPECIFIER@57..60 - 0: JS_IDENTIFIER_BINDING@57..58 - 0: IDENT@57..58 "e" [] [] - 1: COMMA@58..60 "," [] [Whitespace(" ")] - 2: JS_NAMED_IMPORT_SPECIFIERS@60..66 - 0: L_CURLY@60..62 "{" [] [Whitespace(" ")] - 1: JS_NAMED_IMPORT_SPECIFIER_LIST@62..64 - 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@62..64 - 0: (empty) - 1: JS_IDENTIFIER_BINDING@62..64 - 0: IDENT@62..64 "f" [] [Whitespace(" ")] - 2: R_CURLY@64..66 "}" [] [Whitespace(" ")] - 3: FROM_KW@66..71 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@71..74 - 0: JS_STRING_LITERAL@71..74 "\"b\"" [] [] - 5: (empty) - 2: SEMICOLON@74..75 ";" [] [] - 3: JS_IMPORT@75..106 - 0: IMPORT_KW@75..83 "import" [Newline("\n")] [Whitespace(" ")] - 1: JS_IMPORT_NAMED_CLAUSE@83..105 - 0: (empty) - 1: JS_DEFAULT_IMPORT_SPECIFIER@83..86 - 0: JS_IDENTIFIER_BINDING@83..84 - 0: IDENT@83..84 "g" [] [] - 1: COMMA@84..86 "," [] [Whitespace(" ")] - 2: JS_NAMESPACE_IMPORT_SPECIFIER@86..97 - 0: STAR@86..88 "*" [] [Whitespace(" ")] - 1: AS_KW@88..91 "as" [] [Whitespace(" ")] - 2: JS_IDENTIFIER_BINDING@91..97 - 0: IDENT@91..97 "lorem" [] [Whitespace(" ")] - 3: FROM_KW@97..102 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@102..105 - 0: JS_STRING_LITERAL@102..105 "\"c\"" [] [] - 5: (empty) - 2: SEMICOLON@105..106 ";" [] [] - 4: JS_IMPORT@106..162 - 0: IMPORT_KW@106..114 "import" [Newline("\n")] [Whitespace(" ")] - 1: JS_IMPORT_NAMED_CLAUSE@114..161 + 1: JS_IMPORT_NAMED_CLAUSE@57..104 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@114..153 - 0: L_CURLY@114..116 "{" [] [Whitespace(" ")] - 1: JS_NAMED_IMPORT_SPECIFIER_LIST@116..151 - 0: JS_NAMED_IMPORT_SPECIFIER@116..122 + 1: JS_NAMED_IMPORT_SPECIFIERS@57..96 + 0: L_CURLY@57..59 "{" [] [Whitespace(" ")] + 1: JS_NAMED_IMPORT_SPECIFIER_LIST@59..94 + 0: JS_NAMED_IMPORT_SPECIFIER@59..65 0: (empty) - 1: JS_LITERAL_EXPORT_NAME@116..118 - 0: IDENT@116..118 "f" [] [Whitespace(" ")] - 2: AS_KW@118..121 "as" [] [Whitespace(" ")] - 3: JS_IDENTIFIER_BINDING@121..122 - 0: IDENT@121..122 "x" [] [] - 1: COMMA@122..124 "," [] [Whitespace(" ")] - 2: JS_NAMED_IMPORT_SPECIFIER@124..136 + 1: JS_LITERAL_EXPORT_NAME@59..61 + 0: IDENT@59..61 "f" [] [Whitespace(" ")] + 2: AS_KW@61..64 "as" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@64..65 + 0: IDENT@64..65 "x" [] [] + 1: COMMA@65..67 "," [] [Whitespace(" ")] + 2: JS_NAMED_IMPORT_SPECIFIER@67..79 0: (empty) - 1: JS_LITERAL_EXPORT_NAME@124..132 - 0: IDENT@124..132 "default" [] [Whitespace(" ")] - 2: AS_KW@132..135 "as" [] [Whitespace(" ")] - 3: JS_IDENTIFIER_BINDING@135..136 - 0: IDENT@135..136 "w" [] [] - 3: COMMA@136..138 "," [] [Whitespace(" ")] - 4: JS_NAMED_IMPORT_SPECIFIER@138..151 + 1: JS_LITERAL_EXPORT_NAME@67..75 + 0: IDENT@67..75 "default" [] [Whitespace(" ")] + 2: AS_KW@75..78 "as" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@78..79 + 0: IDENT@78..79 "w" [] [] + 3: COMMA@79..81 "," [] [Whitespace(" ")] + 4: JS_NAMED_IMPORT_SPECIFIER@81..94 0: (empty) - 1: JS_LITERAL_EXPORT_NAME@138..146 - 0: JS_STRING_LITERAL@138..146 "\"a-b-c\"" [] [Whitespace(" ")] - 2: AS_KW@146..149 "as" [] [Whitespace(" ")] - 3: JS_IDENTIFIER_BINDING@149..151 - 0: IDENT@149..151 "y" [] [Whitespace(" ")] - 2: R_CURLY@151..153 "}" [] [Whitespace(" ")] - 3: FROM_KW@153..158 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@158..161 - 0: JS_STRING_LITERAL@158..161 "\"b\"" [] [] - 5: (empty) - 2: SEMICOLON@161..162 ";" [] [] - 4: EOF@162..163 "" [Newline("\n")] [] + 1: JS_LITERAL_EXPORT_NAME@81..89 + 0: JS_STRING_LITERAL@81..89 "\"a-b-c\"" [] [Whitespace(" ")] + 2: AS_KW@89..92 "as" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@92..94 + 0: IDENT@92..94 "y" [] [Whitespace(" ")] + 2: R_CURLY@94..96 "}" [] [Whitespace(" ")] + 2: FROM_KW@96..101 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@101..104 + 0: JS_STRING_LITERAL@101..104 "\"b\"" [] [] + 4: (empty) + 2: SEMICOLON@104..105 ";" [] [] + 4: EOF@105..106 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/module.rast b/crates/biome_js_parser/test_data/inline/ok/module.rast index d2860c12925a..9f5eb380ff8f 100644 --- a/crates/biome_js_parser/test_data/inline/ok/module.rast +++ b/crates/biome_js_parser/test_data/inline/ok/module.rast @@ -7,8 +7,10 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@7..9 "a" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@7..9 "a" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@9..14 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -57,8 +59,7 @@ JsModule { import_token: IMPORT_KW@37..45 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@45..47 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -91,8 +92,9 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@7..17 0: (empty) - 1: JS_IDENTIFIER_BINDING@7..9 - 0: IDENT@7..9 "a" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@7..9 + 0: JS_IDENTIFIER_BINDING@7..9 + 0: IDENT@7..9 "a" [] [Whitespace(" ")] 2: FROM_KW@9..14 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@14..17 0: JS_STRING_LITERAL@14..17 "\"b\"" [] [] @@ -127,8 +129,7 @@ JsModule { 0: IMPORT_KW@37..45 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@45..59 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@45..51 + 1: JS_NAMED_IMPORT_SPECIFIERS@45..51 0: L_CURLY@45..47 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@47..49 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@47..49 @@ -136,9 +137,9 @@ JsModule { 1: JS_IDENTIFIER_BINDING@47..49 0: IDENT@47..49 "c" [] [Whitespace(" ")] 2: R_CURLY@49..51 "}" [] [Whitespace(" ")] - 3: FROM_KW@51..56 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@56..59 + 2: FROM_KW@51..56 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@56..59 0: JS_STRING_LITERAL@56..59 "\"c\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@59..60 ";" [] [] 4: EOF@60..61 "" [Newline("\n")] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/ts_import_clause_types.rast b/crates/biome_js_parser/test_data/inline/ok/ts_import_clause_types.rast index 2bfceb303fb7..379f48b097a6 100644 --- a/crates/biome_js_parser/test_data/inline/ok/ts_import_clause_types.rast +++ b/crates/biome_js_parser/test_data/inline/ok/ts_import_clause_types.rast @@ -7,8 +7,10 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: missing (optional), - local_name: JsIdentifierBinding { - name_token: IDENT@7..12 "type" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@7..12 "type" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@12..17 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -22,8 +24,10 @@ JsModule { import_token: IMPORT_KW@39..47 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: TYPE_KW@47..52 "type" [] [Whitespace(" ")], - local_name: JsIdentifierBinding { - name_token: IDENT@52..56 "foo" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@52..56 "foo" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@56..61 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -37,10 +41,12 @@ JsModule { import_token: IMPORT_KW@69..77 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamespaceClause { type_token: TYPE_KW@77..82 "type" [] [Whitespace(" ")], - star_token: STAR@82..84 "*" [] [Whitespace(" ")], - as_token: AS_KW@84..87 "as" [] [Whitespace(" ")], - local_name: JsIdentifierBinding { - name_token: IDENT@87..92 "foo2" [] [Whitespace(" ")], + namespace_specifier: JsNamespaceImportSpecifier { + star_token: STAR@82..84 "*" [] [Whitespace(" ")], + as_token: AS_KW@84..87 "as" [] [Whitespace(" ")], + local_name: JsIdentifierBinding { + name_token: IDENT@87..92 "foo2" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@92..97 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -54,8 +60,7 @@ JsModule { import_token: IMPORT_KW@105..113 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: TYPE_KW@113..118 "type" [] [Whitespace(" ")], - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@118..120 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -79,8 +84,10 @@ JsModule { import_token: IMPORT_KW@138..146 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportDefaultClause { type_token: TYPE_KW@146..151 "type" [] [Whitespace(" ")], - local_name: JsIdentifierBinding { - name_token: IDENT@151..156 "from" [] [Whitespace(" ")], + default_specifier: JsDefaultImportSpecifier { + local_name: JsIdentifierBinding { + name_token: IDENT@151..156 "from" [] [Whitespace(" ")], + }, }, from_token: FROM_KW@156..161 "from" [] [Whitespace(" ")], source: JsModuleSource { @@ -103,8 +110,9 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@7..24 0: (empty) - 1: JS_IDENTIFIER_BINDING@7..12 - 0: IDENT@7..12 "type" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@7..12 + 0: JS_IDENTIFIER_BINDING@7..12 + 0: IDENT@7..12 "type" [] [Whitespace(" ")] 2: FROM_KW@12..17 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@17..24 0: JS_STRING_LITERAL@17..24 "\"./mod\"" [] [] @@ -114,8 +122,9 @@ JsModule { 0: IMPORT_KW@39..47 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@47..68 0: TYPE_KW@47..52 "type" [] [Whitespace(" ")] - 1: JS_IDENTIFIER_BINDING@52..56 - 0: IDENT@52..56 "foo" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@52..56 + 0: JS_IDENTIFIER_BINDING@52..56 + 0: IDENT@52..56 "foo" [] [Whitespace(" ")] 2: FROM_KW@56..61 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@61..68 0: JS_STRING_LITERAL@61..68 "\"./mod\"" [] [] @@ -125,21 +134,21 @@ JsModule { 0: IMPORT_KW@69..77 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMESPACE_CLAUSE@77..104 0: TYPE_KW@77..82 "type" [] [Whitespace(" ")] - 1: STAR@82..84 "*" [] [Whitespace(" ")] - 2: AS_KW@84..87 "as" [] [Whitespace(" ")] - 3: JS_IDENTIFIER_BINDING@87..92 - 0: IDENT@87..92 "foo2" [] [Whitespace(" ")] - 4: FROM_KW@92..97 "from" [] [Whitespace(" ")] - 5: JS_MODULE_SOURCE@97..104 + 1: JS_NAMESPACE_IMPORT_SPECIFIER@82..92 + 0: STAR@82..84 "*" [] [Whitespace(" ")] + 1: AS_KW@84..87 "as" [] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@87..92 + 0: IDENT@87..92 "foo2" [] [Whitespace(" ")] + 2: FROM_KW@92..97 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@97..104 0: JS_STRING_LITERAL@97..104 "\"./mod\"" [] [] - 6: (empty) + 4: (empty) 2: SEMICOLON@104..105 ";" [] [] 3: JS_IMPORT@105..138 0: IMPORT_KW@105..113 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@113..137 0: TYPE_KW@113..118 "type" [] [Whitespace(" ")] - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@118..127 + 1: JS_NAMED_IMPORT_SPECIFIERS@118..127 0: L_CURLY@118..120 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@120..125 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@120..125 @@ -147,17 +156,18 @@ JsModule { 1: JS_IDENTIFIER_BINDING@120..125 0: IDENT@120..125 "foo3" [] [Whitespace(" ")] 2: R_CURLY@125..127 "}" [] [Whitespace(" ")] - 3: FROM_KW@127..132 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@132..137 + 2: FROM_KW@127..132 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@132..137 0: JS_STRING_LITERAL@132..137 "\"mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@137..138 ";" [] [] 4: JS_IMPORT@138..169 0: IMPORT_KW@138..146 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_DEFAULT_CLAUSE@146..168 0: TYPE_KW@146..151 "type" [] [Whitespace(" ")] - 1: JS_IDENTIFIER_BINDING@151..156 - 0: IDENT@151..156 "from" [] [Whitespace(" ")] + 1: JS_DEFAULT_IMPORT_SPECIFIER@151..156 + 0: JS_IDENTIFIER_BINDING@151..156 + 0: IDENT@151..156 "from" [] [Whitespace(" ")] 2: FROM_KW@156..161 "from" [] [Whitespace(" ")] 3: JS_MODULE_SOURCE@161..168 0: JS_STRING_LITERAL@161..168 "\"./mod\"" [] [] diff --git a/crates/biome_js_parser/test_data/inline/ok/ts_named_import_specifier_with_type.rast b/crates/biome_js_parser/test_data/inline/ok/ts_named_import_specifier_with_type.rast index cd465b77d3d1..45b198d49c43 100644 --- a/crates/biome_js_parser/test_data/inline/ok/ts_named_import_specifier_with_type.rast +++ b/crates/biome_js_parser/test_data/inline/ok/ts_named_import_specifier_with_type.rast @@ -7,8 +7,7 @@ JsModule { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@7..9 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -39,8 +38,7 @@ JsModule { import_token: IMPORT_KW@38..46 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@46..48 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -68,8 +66,7 @@ JsModule { import_token: IMPORT_KW@76..84 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@84..86 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -97,8 +94,7 @@ JsModule { import_token: IMPORT_KW@112..120 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@120..122 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -126,8 +122,7 @@ JsModule { import_token: IMPORT_KW@150..158 "import" [Newline("\n")] [Whitespace(" ")], import_clause: JsImportNamedClause { type_token: missing (optional), - default_specifier: missing (optional), - named_import: JsNamedImportSpecifiers { + named_specifiers: JsNamedImportSpecifiers { l_curly_token: L_CURLY@158..160 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsNamedImportSpecifier { @@ -164,8 +159,7 @@ JsModule { 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@7..37 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@7..25 + 1: JS_NAMED_IMPORT_SPECIFIERS@7..25 0: L_CURLY@7..9 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@9..23 0: JS_SHORTHAND_NAMED_IMPORT_SPECIFIER@9..13 @@ -178,17 +172,16 @@ JsModule { 1: JS_IDENTIFIER_BINDING@20..23 0: IDENT@20..23 "as" [] [Whitespace(" ")] 2: R_CURLY@23..25 "}" [] [Whitespace(" ")] - 3: FROM_KW@25..30 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@30..37 + 2: FROM_KW@25..30 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@30..37 0: JS_STRING_LITERAL@30..37 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@37..38 ";" [] [] 1: JS_IMPORT@38..76 0: IMPORT_KW@38..46 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@46..76 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@46..64 + 1: JS_NAMED_IMPORT_SPECIFIERS@46..64 0: L_CURLY@46..48 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@48..62 0: JS_NAMED_IMPORT_SPECIFIER@48..62 @@ -199,17 +192,16 @@ JsModule { 3: JS_IDENTIFIER_BINDING@56..62 0: IDENT@56..62 "other" [] [Whitespace(" ")] 2: R_CURLY@62..64 "}" [] [Whitespace(" ")] - 3: FROM_KW@64..69 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@69..76 + 2: FROM_KW@64..69 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@69..76 0: JS_STRING_LITERAL@69..76 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: (empty) 2: JS_IMPORT@76..112 0: IMPORT_KW@76..84 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@84..111 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@84..99 + 1: JS_NAMED_IMPORT_SPECIFIERS@84..99 0: L_CURLY@84..86 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@86..97 0: JS_NAMED_IMPORT_SPECIFIER@86..97 @@ -220,17 +212,16 @@ JsModule { 3: JS_IDENTIFIER_BINDING@94..97 0: IDENT@94..97 "as" [] [Whitespace(" ")] 2: R_CURLY@97..99 "}" [] [Whitespace(" ")] - 3: FROM_KW@99..104 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@104..111 + 2: FROM_KW@99..104 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@104..111 0: JS_STRING_LITERAL@104..111 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@111..112 ";" [] [] 3: JS_IMPORT@112..150 0: IMPORT_KW@112..120 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@120..150 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@120..138 + 1: JS_NAMED_IMPORT_SPECIFIERS@120..138 0: L_CURLY@120..122 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@122..136 0: JS_NAMED_IMPORT_SPECIFIER@122..136 @@ -241,17 +232,16 @@ JsModule { 3: JS_IDENTIFIER_BINDING@133..136 0: IDENT@133..136 "as" [] [Whitespace(" ")] 2: R_CURLY@136..138 "}" [] [Whitespace(" ")] - 3: FROM_KW@138..143 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@143..150 + 2: FROM_KW@138..143 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@143..150 0: JS_STRING_LITERAL@143..150 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: (empty) 4: JS_IMPORT@150..200 0: IMPORT_KW@150..158 "import" [Newline("\n")] [Whitespace(" ")] 1: JS_IMPORT_NAMED_CLAUSE@158..199 0: (empty) - 1: (empty) - 2: JS_NAMED_IMPORT_SPECIFIERS@158..187 + 1: JS_NAMED_IMPORT_SPECIFIERS@158..187 0: L_CURLY@158..160 "{" [] [Whitespace(" ")] 1: JS_NAMED_IMPORT_SPECIFIER_LIST@160..185 0: JS_NAMED_IMPORT_SPECIFIER@160..185 @@ -262,9 +252,9 @@ JsModule { 3: JS_IDENTIFIER_BINDING@180..185 0: IDENT@180..185 "test" [] [Whitespace(" ")] 2: R_CURLY@185..187 "}" [] [Whitespace(" ")] - 3: FROM_KW@187..192 "from" [] [Whitespace(" ")] - 4: JS_MODULE_SOURCE@192..199 + 2: FROM_KW@187..192 "from" [] [Whitespace(" ")] + 3: JS_MODULE_SOURCE@192..199 0: JS_STRING_LITERAL@192..199 "\"./mod\"" [] [] - 5: (empty) + 4: (empty) 2: SEMICOLON@199..200 ";" [] [] 4: EOF@200..201 "" [Newline("\n")] [] diff --git a/crates/biome_js_semantic/src/events.rs b/crates/biome_js_semantic/src/events.rs index df575105b237..77cc872e24b4 100644 --- a/crates/biome_js_semantic/src/events.rs +++ b/crates/biome_js_semantic/src/events.rs @@ -2,7 +2,7 @@ use biome_js_syntax::binding_ext::{AnyJsBindingDeclaration, AnyJsIdentifierBinding}; use biome_js_syntax::{ - AnyJsExportNamedSpecifier, AnyJsNamedImportSpecifier, AnyTsType, JsImportNamedClause, + AnyJsExportNamedSpecifier, AnyJsImportClause, AnyJsNamedImportSpecifier, AnyTsType, }; use biome_js_syntax::{ AnyJsIdentifierUsage, JsLanguage, JsSyntaxKind, JsSyntaxNode, TextRange, TsTypeParameterName, @@ -442,20 +442,6 @@ impl SemanticEventExtractor { | AnyJsBindingDeclaration::TsTypeParameter(_) => { self.push_binding(None, BindingName::Type(name), info); } - AnyJsBindingDeclaration::JsImportDefaultClause(clause) => { - let info = info.into_imported(); - if clause.type_token().is_none() { - self.push_binding(None, BindingName::Value(name.clone()), info.clone()); - } - self.push_binding(None, BindingName::Type(name), info); - } - AnyJsBindingDeclaration::JsImportNamespaceClause(clause) => { - let info = info.into_imported(); - if clause.type_token().is_none() { - self.push_binding(None, BindingName::Value(name.clone()), info.clone()); - } - self.push_binding(None, BindingName::Type(name), info); - } AnyJsBindingDeclaration::TsImportEqualsDeclaration(declaration) => { let info = info.into_imported(); if declaration.type_token().is_none() { @@ -465,12 +451,11 @@ impl SemanticEventExtractor { } AnyJsBindingDeclaration::JsDefaultImportSpecifier(_) | AnyJsBindingDeclaration::JsNamespaceImportSpecifier(_) => { - let is_import_type = declaration - .parent::() - .map(|clause| clause.type_token().is_none()) - .unwrap_or(false); + let type_token = declaration + .parent::() + .and_then(|clause| clause.type_token()); let info = info.into_imported(); - if is_import_type { + if type_token.is_none() { self.push_binding(None, BindingName::Value(name.clone()), info.clone()); } self.push_binding(None, BindingName::Type(name), info); diff --git a/crates/biome_js_syntax/src/binding_ext.rs b/crates/biome_js_syntax/src/binding_ext.rs index 938f5fe89aeb..8e8d64139ab6 100644 --- a/crates/biome_js_syntax/src/binding_ext.rs +++ b/crates/biome_js_syntax/src/binding_ext.rs @@ -4,14 +4,13 @@ use crate::{ JsClassExportDefaultDeclaration, JsClassExpression, JsConstructorClassMember, JsConstructorParameterList, JsConstructorParameters, JsDefaultImportSpecifier, JsExport, JsFormalParameter, JsFunctionDeclaration, JsFunctionExportDefaultDeclaration, - JsFunctionExpression, JsIdentifierBinding, JsImportDefaultClause, JsImportNamespaceClause, - JsMethodClassMember, JsMethodObjectMember, JsNamedImportSpecifier, JsNamespaceImportSpecifier, - JsParameterList, JsParameters, JsRestParameter, JsSetterClassMember, JsSetterObjectMember, - JsShorthandNamedImportSpecifier, JsSyntaxKind, JsSyntaxNode, JsSyntaxToken, - JsVariableDeclarator, TsCallSignatureTypeMember, TsConstructSignatureTypeMember, - TsConstructorSignatureClassMember, TsConstructorType, TsDeclareFunctionDeclaration, - TsDeclareFunctionExportDefaultDeclaration, TsEnumDeclaration, TsFunctionType, - TsIdentifierBinding, TsImportEqualsDeclaration, TsIndexSignatureClassMember, + JsFunctionExpression, JsIdentifierBinding, JsMethodClassMember, JsMethodObjectMember, + JsNamedImportSpecifier, JsNamespaceImportSpecifier, JsParameterList, JsParameters, + JsRestParameter, JsSetterClassMember, JsSetterObjectMember, JsShorthandNamedImportSpecifier, + JsSyntaxKind, JsSyntaxNode, JsSyntaxToken, JsVariableDeclarator, TsCallSignatureTypeMember, + TsConstructSignatureTypeMember, TsConstructorSignatureClassMember, TsConstructorType, + TsDeclareFunctionDeclaration, TsDeclareFunctionExportDefaultDeclaration, TsEnumDeclaration, + TsFunctionType, TsIdentifierBinding, TsImportEqualsDeclaration, TsIndexSignatureClassMember, TsIndexSignatureParameter, TsInferType, TsInterfaceDeclaration, TsMappedType, TsMethodSignatureClassMember, TsMethodSignatureTypeMember, TsModuleDeclaration, TsPropertyParameter, TsSetterSignatureClassMember, TsSetterSignatureTypeMember, @@ -35,7 +34,7 @@ declare_node_union! { | JsClassDeclaration | JsClassExpression | TsInterfaceDeclaration | TsTypeAliasDeclaration | TsEnumDeclaration | TsModuleDeclaration // import - | JsImportDefaultClause | JsImportNamespaceClause | JsShorthandNamedImportSpecifier + | JsShorthandNamedImportSpecifier | JsNamedImportSpecifier | JsBogusNamedImportSpecifier | JsDefaultImportSpecifier | JsNamespaceImportSpecifier | TsImportEqualsDeclaration @@ -298,7 +297,11 @@ impl AnyJsIdentifierBinding { if let Some(specifier) = binding.parent::() { return specifier.imports_only_types(); } - if let Some(clause) = binding.parent::() { + if let Some(clause) = binding + .syntax() + .grand_parent() + .and_then(AnyJsImportClause::cast) + { return clause.type_token().is_some(); } } diff --git a/crates/biome_js_syntax/src/generated/kind.rs b/crates/biome_js_syntax/src/generated/kind.rs index a454b7384c76..37048a60c1c9 100644 --- a/crates/biome_js_syntax/src/generated/kind.rs +++ b/crates/biome_js_syntax/src/generated/kind.rs @@ -341,6 +341,7 @@ pub enum JsSyntaxKind { JS_IMPORT_DEFAULT_CLAUSE, JS_IMPORT_NAMESPACE_CLAUSE, JS_IMPORT_NAMED_CLAUSE, + JS_IMPORT_DEFAULT_EXTRA_CLAUSE, JS_NAMED_IMPORT_SPECIFIERS, JS_NAMED_IMPORT_SPECIFIER_LIST, JS_NAMESPACE_IMPORT_SPECIFIER, diff --git a/crates/biome_js_syntax/src/generated/macros.rs b/crates/biome_js_syntax/src/generated/macros.rs index 0dbbfcc98fde..32f782325f26 100644 --- a/crates/biome_js_syntax/src/generated/macros.rs +++ b/crates/biome_js_syntax/src/generated/macros.rs @@ -334,6 +334,11 @@ macro_rules! map_syntax_node { let $pattern = unsafe { $crate::JsImportDefaultClause::new_unchecked(node) }; $body } + $crate::JsSyntaxKind::JS_IMPORT_DEFAULT_EXTRA_CLAUSE => { + let $pattern = + unsafe { $crate::JsImportDefaultExtraClause::new_unchecked(node) }; + $body + } $crate::JsSyntaxKind::JS_IMPORT_META_EXPRESSION => { let $pattern = unsafe { $crate::JsImportMetaExpression::new_unchecked(node) }; $body diff --git a/crates/biome_js_syntax/src/generated/nodes.rs b/crates/biome_js_syntax/src/generated/nodes.rs index 8464c647ddba..eb8098ddf43f 100644 --- a/crates/biome_js_syntax/src/generated/nodes.rs +++ b/crates/biome_js_syntax/src/generated/nodes.rs @@ -1734,15 +1734,11 @@ impl JsDefaultImportSpecifier { pub fn as_fields(&self) -> JsDefaultImportSpecifierFields { JsDefaultImportSpecifierFields { local_name: self.local_name(), - trailing_comma_token: self.trailing_comma_token(), } } pub fn local_name(&self) -> SyntaxResult { support::required_node(&self.syntax, 0usize) } - pub fn trailing_comma_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 1usize) - } } #[cfg(feature = "serde")] impl Serialize for JsDefaultImportSpecifier { @@ -1756,7 +1752,6 @@ impl Serialize for JsDefaultImportSpecifier { #[cfg_attr(feature = "serde", derive(Serialize))] pub struct JsDefaultImportSpecifierFields { pub local_name: SyntaxResult, - pub trailing_comma_token: SyntaxResult, } #[derive(Clone, PartialEq, Eq, Hash)] pub struct JsDirective { @@ -3772,7 +3767,7 @@ impl JsImportDefaultClause { pub fn as_fields(&self) -> JsImportDefaultClauseFields { JsImportDefaultClauseFields { type_token: self.type_token(), - local_name: self.local_name(), + default_specifier: self.default_specifier(), from_token: self.from_token(), source: self.source(), assertion: self.assertion(), @@ -3781,7 +3776,7 @@ impl JsImportDefaultClause { pub fn type_token(&self) -> Option { support::token(&self.syntax, 0usize) } - pub fn local_name(&self) -> SyntaxResult { + pub fn default_specifier(&self) -> SyntaxResult { support::required_node(&self.syntax, 1usize) } pub fn from_token(&self) -> SyntaxResult { @@ -3806,7 +3801,68 @@ impl Serialize for JsImportDefaultClause { #[cfg_attr(feature = "serde", derive(Serialize))] pub struct JsImportDefaultClauseFields { pub type_token: Option, - pub local_name: SyntaxResult, + pub default_specifier: SyntaxResult, + pub from_token: SyntaxResult, + pub source: SyntaxResult, + pub assertion: Option, +} +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct JsImportDefaultExtraClause { + pub(crate) syntax: SyntaxNode, +} +impl JsImportDefaultExtraClause { + #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"] + #[doc = r" or a match on [SyntaxNode::kind]"] + #[inline] + pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self { + Self { syntax } + } + pub fn as_fields(&self) -> JsImportDefaultExtraClauseFields { + JsImportDefaultExtraClauseFields { + default_specifier: self.default_specifier(), + comma_token: self.comma_token(), + extra_specifier: self.extra_specifier(), + from_token: self.from_token(), + source: self.source(), + assertion: self.assertion(), + } + } + pub fn default_specifier(&self) -> SyntaxResult { + support::required_node(&self.syntax, 0usize) + } + pub fn comma_token(&self) -> SyntaxResult { + support::required_token(&self.syntax, 1usize) + } + pub fn extra_specifier(&self) -> SyntaxResult { + support::required_node(&self.syntax, 2usize) + } + pub fn from_token(&self) -> SyntaxResult { + support::required_token(&self.syntax, 3usize) + } + pub fn source(&self) -> SyntaxResult { + support::required_node(&self.syntax, 4usize) + } + pub fn assertion(&self) -> Option { + support::node(&self.syntax, 5usize) + } +} +#[cfg(feature = "serde")] +impl Serialize for JsImportDefaultExtraClause { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.as_fields().serialize(serializer) + } +} +#[cfg_attr(feature = "serde", derive(Serialize))] +pub struct JsImportDefaultExtraClauseFields { + pub default_specifier: SyntaxResult, + pub comma_token: SyntaxResult, + pub extra_specifier: SyntaxResult, pub from_token: SyntaxResult, pub source: SyntaxResult, pub assertion: Option, @@ -3874,8 +3930,7 @@ impl JsImportNamedClause { pub fn as_fields(&self) -> JsImportNamedClauseFields { JsImportNamedClauseFields { type_token: self.type_token(), - default_specifier: self.default_specifier(), - named_import: self.named_import(), + named_specifiers: self.named_specifiers(), from_token: self.from_token(), source: self.source(), assertion: self.assertion(), @@ -3884,20 +3939,17 @@ impl JsImportNamedClause { pub fn type_token(&self) -> Option { support::token(&self.syntax, 0usize) } - pub fn default_specifier(&self) -> Option { - support::node(&self.syntax, 1usize) - } - pub fn named_import(&self) -> SyntaxResult { - support::required_node(&self.syntax, 2usize) + pub fn named_specifiers(&self) -> SyntaxResult { + support::required_node(&self.syntax, 1usize) } pub fn from_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 3usize) + support::required_token(&self.syntax, 2usize) } pub fn source(&self) -> SyntaxResult { - support::required_node(&self.syntax, 4usize) + support::required_node(&self.syntax, 3usize) } pub fn assertion(&self) -> Option { - support::node(&self.syntax, 5usize) + support::node(&self.syntax, 4usize) } } #[cfg(feature = "serde")] @@ -3912,8 +3964,7 @@ impl Serialize for JsImportNamedClause { #[cfg_attr(feature = "serde", derive(Serialize))] pub struct JsImportNamedClauseFields { pub type_token: Option, - pub default_specifier: Option, - pub named_import: SyntaxResult, + pub named_specifiers: SyntaxResult, pub from_token: SyntaxResult, pub source: SyntaxResult, pub assertion: Option, @@ -3935,9 +3986,7 @@ impl JsImportNamespaceClause { pub fn as_fields(&self) -> JsImportNamespaceClauseFields { JsImportNamespaceClauseFields { type_token: self.type_token(), - star_token: self.star_token(), - as_token: self.as_token(), - local_name: self.local_name(), + namespace_specifier: self.namespace_specifier(), from_token: self.from_token(), source: self.source(), assertion: self.assertion(), @@ -3946,23 +3995,17 @@ impl JsImportNamespaceClause { pub fn type_token(&self) -> Option { support::token(&self.syntax, 0usize) } - pub fn star_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 1usize) - } - pub fn as_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 2usize) - } - pub fn local_name(&self) -> SyntaxResult { - support::required_node(&self.syntax, 3usize) + pub fn namespace_specifier(&self) -> SyntaxResult { + support::required_node(&self.syntax, 1usize) } pub fn from_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 4usize) + support::required_token(&self.syntax, 2usize) } pub fn source(&self) -> SyntaxResult { - support::required_node(&self.syntax, 5usize) + support::required_node(&self.syntax, 3usize) } pub fn assertion(&self) -> Option { - support::node(&self.syntax, 6usize) + support::node(&self.syntax, 4usize) } } #[cfg(feature = "serde")] @@ -3977,9 +4020,7 @@ impl Serialize for JsImportNamespaceClause { #[cfg_attr(feature = "serde", derive(Serialize))] pub struct JsImportNamespaceClauseFields { pub type_token: Option, - pub star_token: SyntaxResult, - pub as_token: SyntaxResult, - pub local_name: SyntaxResult, + pub namespace_specifier: SyntaxResult, pub from_token: SyntaxResult, pub source: SyntaxResult, pub assertion: Option, @@ -14501,6 +14542,26 @@ impl AnyJsExpression { } #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize))] +pub enum AnyJsExtraImportSpecifier { + JsNamedImportSpecifiers(JsNamedImportSpecifiers), + JsNamespaceImportSpecifier(JsNamespaceImportSpecifier), +} +impl AnyJsExtraImportSpecifier { + pub fn as_js_named_import_specifiers(&self) -> Option<&JsNamedImportSpecifiers> { + match &self { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(item) => Some(item), + _ => None, + } + } + pub fn as_js_namespace_import_specifier(&self) -> Option<&JsNamespaceImportSpecifier> { + match &self { + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(item) => Some(item), + _ => None, + } + } +} +#[derive(Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyJsForInOrOfInitializer { AnyJsAssignmentPattern(AnyJsAssignmentPattern), JsForVariableDeclaration(JsForVariableDeclaration), @@ -14640,6 +14701,7 @@ impl AnyJsImportAssertionEntry { pub enum AnyJsImportClause { JsImportBareClause(JsImportBareClause), JsImportDefaultClause(JsImportDefaultClause), + JsImportDefaultExtraClause(JsImportDefaultExtraClause), JsImportNamedClause(JsImportNamedClause), JsImportNamespaceClause(JsImportNamespaceClause), } @@ -14656,6 +14718,12 @@ impl AnyJsImportClause { _ => None, } } + pub fn as_js_import_default_extra_clause(&self) -> Option<&JsImportDefaultExtraClause> { + match &self { + AnyJsImportClause::JsImportDefaultExtraClause(item) => Some(item), + _ => None, + } + } pub fn as_js_import_named_clause(&self) -> Option<&JsImportNamedClause> { match &self { AnyJsImportClause::JsImportNamedClause(item) => Some(item), @@ -14820,26 +14888,6 @@ impl AnyJsName { } #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize))] -pub enum AnyJsNamedImport { - JsNamedImportSpecifiers(JsNamedImportSpecifiers), - JsNamespaceImportSpecifier(JsNamespaceImportSpecifier), -} -impl AnyJsNamedImport { - pub fn as_js_named_import_specifiers(&self) -> Option<&JsNamedImportSpecifiers> { - match &self { - AnyJsNamedImport::JsNamedImportSpecifiers(item) => Some(item), - _ => None, - } - } - pub fn as_js_namespace_import_specifier(&self) -> Option<&JsNamespaceImportSpecifier> { - match &self { - AnyJsNamedImport::JsNamespaceImportSpecifier(item) => Some(item), - _ => None, - } - } -} -#[derive(Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyJsNamedImportSpecifier { JsBogusNamedImportSpecifier(JsBogusNamedImportSpecifier), JsNamedImportSpecifier(JsNamedImportSpecifier), @@ -18011,10 +18059,6 @@ impl std::fmt::Debug for JsDefaultImportSpecifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("JsDefaultImportSpecifier") .field("local_name", &support::DebugSyntaxResult(self.local_name())) - .field( - "trailing_comma_token", - &support::DebugSyntaxResult(self.trailing_comma_token()), - ) .finish() } } @@ -19933,7 +19977,10 @@ impl std::fmt::Debug for JsImportDefaultClause { "type_token", &support::DebugOptionalElement(self.type_token()), ) - .field("local_name", &support::DebugSyntaxResult(self.local_name())) + .field( + "default_specifier", + &support::DebugSyntaxResult(self.default_specifier()), + ) .field("from_token", &support::DebugSyntaxResult(self.from_token())) .field("source", &support::DebugSyntaxResult(self.source())) .field( @@ -19953,6 +20000,61 @@ impl From for SyntaxElement { n.syntax.into() } } +impl AstNode for JsImportDefaultExtraClause { + type Language = Language; + const KIND_SET: SyntaxKindSet = + SyntaxKindSet::from_raw(RawSyntaxKind(JS_IMPORT_DEFAULT_EXTRA_CLAUSE as u16)); + fn can_cast(kind: SyntaxKind) -> bool { + kind == JS_IMPORT_DEFAULT_EXTRA_CLAUSE + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } + fn into_syntax(self) -> SyntaxNode { + self.syntax + } +} +impl std::fmt::Debug for JsImportDefaultExtraClause { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("JsImportDefaultExtraClause") + .field( + "default_specifier", + &support::DebugSyntaxResult(self.default_specifier()), + ) + .field( + "comma_token", + &support::DebugSyntaxResult(self.comma_token()), + ) + .field( + "extra_specifier", + &support::DebugSyntaxResult(self.extra_specifier()), + ) + .field("from_token", &support::DebugSyntaxResult(self.from_token())) + .field("source", &support::DebugSyntaxResult(self.source())) + .field( + "assertion", + &support::DebugOptionalElement(self.assertion()), + ) + .finish() + } +} +impl From for SyntaxNode { + fn from(n: JsImportDefaultExtraClause) -> SyntaxNode { + n.syntax + } +} +impl From for SyntaxElement { + fn from(n: JsImportDefaultExtraClause) -> SyntaxElement { + n.syntax.into() + } +} impl AstNode for JsImportMetaExpression { type Language = Language; const KIND_SET: SyntaxKindSet = @@ -20025,12 +20127,8 @@ impl std::fmt::Debug for JsImportNamedClause { &support::DebugOptionalElement(self.type_token()), ) .field( - "default_specifier", - &support::DebugOptionalElement(self.default_specifier()), - ) - .field( - "named_import", - &support::DebugSyntaxResult(self.named_import()), + "named_specifiers", + &support::DebugSyntaxResult(self.named_specifiers()), ) .field("from_token", &support::DebugSyntaxResult(self.from_token())) .field("source", &support::DebugSyntaxResult(self.source())) @@ -20079,9 +20177,10 @@ impl std::fmt::Debug for JsImportNamespaceClause { "type_token", &support::DebugOptionalElement(self.type_token()), ) - .field("star_token", &support::DebugSyntaxResult(self.star_token())) - .field("as_token", &support::DebugSyntaxResult(self.as_token())) - .field("local_name", &support::DebugSyntaxResult(self.local_name())) + .field( + "namespace_specifier", + &support::DebugSyntaxResult(self.namespace_specifier()), + ) .field("from_token", &support::DebugSyntaxResult(self.from_token())) .field("source", &support::DebugSyntaxResult(self.source())) .field( @@ -32061,6 +32160,79 @@ impl From for SyntaxElement { node.into() } } +impl From for AnyJsExtraImportSpecifier { + fn from(node: JsNamedImportSpecifiers) -> AnyJsExtraImportSpecifier { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(node) + } +} +impl From for AnyJsExtraImportSpecifier { + fn from(node: JsNamespaceImportSpecifier) -> AnyJsExtraImportSpecifier { + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(node) + } +} +impl AstNode for AnyJsExtraImportSpecifier { + type Language = Language; + const KIND_SET: SyntaxKindSet = + JsNamedImportSpecifiers::KIND_SET.union(JsNamespaceImportSpecifier::KIND_SET); + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + JS_NAMED_IMPORT_SPECIFIERS | JS_NAMESPACE_IMPORT_SPECIFIER + ) + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + JS_NAMED_IMPORT_SPECIFIERS => { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(JsNamedImportSpecifiers { + syntax, + }) + } + JS_NAMESPACE_IMPORT_SPECIFIER => { + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(JsNamespaceImportSpecifier { + syntax, + }) + } + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + match self { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => &it.syntax, + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => &it.syntax, + } + } + fn into_syntax(self) -> SyntaxNode { + match self { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => it.syntax, + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => it.syntax, + } + } +} +impl std::fmt::Debug for AnyJsExtraImportSpecifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => std::fmt::Debug::fmt(it, f), + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => { + std::fmt::Debug::fmt(it, f) + } + } + } +} +impl From for SyntaxNode { + fn from(n: AnyJsExtraImportSpecifier) -> SyntaxNode { + match n { + AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => it.into(), + AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => it.into(), + } + } +} +impl From for SyntaxElement { + fn from(n: AnyJsExtraImportSpecifier) -> SyntaxElement { + let node: SyntaxNode = n.into(); + node.into() + } +} impl From for AnyJsForInOrOfInitializer { fn from(node: JsForVariableDeclaration) -> AnyJsForInOrOfInitializer { AnyJsForInOrOfInitializer::JsForVariableDeclaration(node) @@ -32501,6 +32673,11 @@ impl From for AnyJsImportClause { AnyJsImportClause::JsImportDefaultClause(node) } } +impl From for AnyJsImportClause { + fn from(node: JsImportDefaultExtraClause) -> AnyJsImportClause { + AnyJsImportClause::JsImportDefaultExtraClause(node) + } +} impl From for AnyJsImportClause { fn from(node: JsImportNamedClause) -> AnyJsImportClause { AnyJsImportClause::JsImportNamedClause(node) @@ -32515,6 +32692,7 @@ impl AstNode for AnyJsImportClause { type Language = Language; const KIND_SET: SyntaxKindSet = JsImportBareClause::KIND_SET .union(JsImportDefaultClause::KIND_SET) + .union(JsImportDefaultExtraClause::KIND_SET) .union(JsImportNamedClause::KIND_SET) .union(JsImportNamespaceClause::KIND_SET); fn can_cast(kind: SyntaxKind) -> bool { @@ -32522,6 +32700,7 @@ impl AstNode for AnyJsImportClause { kind, JS_IMPORT_BARE_CLAUSE | JS_IMPORT_DEFAULT_CLAUSE + | JS_IMPORT_DEFAULT_EXTRA_CLAUSE | JS_IMPORT_NAMED_CLAUSE | JS_IMPORT_NAMESPACE_CLAUSE ) @@ -32534,6 +32713,9 @@ impl AstNode for AnyJsImportClause { JS_IMPORT_DEFAULT_CLAUSE => { AnyJsImportClause::JsImportDefaultClause(JsImportDefaultClause { syntax }) } + JS_IMPORT_DEFAULT_EXTRA_CLAUSE => { + AnyJsImportClause::JsImportDefaultExtraClause(JsImportDefaultExtraClause { syntax }) + } JS_IMPORT_NAMED_CLAUSE => { AnyJsImportClause::JsImportNamedClause(JsImportNamedClause { syntax }) } @@ -32548,6 +32730,7 @@ impl AstNode for AnyJsImportClause { match self { AnyJsImportClause::JsImportBareClause(it) => &it.syntax, AnyJsImportClause::JsImportDefaultClause(it) => &it.syntax, + AnyJsImportClause::JsImportDefaultExtraClause(it) => &it.syntax, AnyJsImportClause::JsImportNamedClause(it) => &it.syntax, AnyJsImportClause::JsImportNamespaceClause(it) => &it.syntax, } @@ -32556,6 +32739,7 @@ impl AstNode for AnyJsImportClause { match self { AnyJsImportClause::JsImportBareClause(it) => it.syntax, AnyJsImportClause::JsImportDefaultClause(it) => it.syntax, + AnyJsImportClause::JsImportDefaultExtraClause(it) => it.syntax, AnyJsImportClause::JsImportNamedClause(it) => it.syntax, AnyJsImportClause::JsImportNamespaceClause(it) => it.syntax, } @@ -32566,6 +32750,7 @@ impl std::fmt::Debug for AnyJsImportClause { match self { AnyJsImportClause::JsImportBareClause(it) => std::fmt::Debug::fmt(it, f), AnyJsImportClause::JsImportDefaultClause(it) => std::fmt::Debug::fmt(it, f), + AnyJsImportClause::JsImportDefaultExtraClause(it) => std::fmt::Debug::fmt(it, f), AnyJsImportClause::JsImportNamedClause(it) => std::fmt::Debug::fmt(it, f), AnyJsImportClause::JsImportNamespaceClause(it) => std::fmt::Debug::fmt(it, f), } @@ -32576,6 +32761,7 @@ impl From for SyntaxNode { match n { AnyJsImportClause::JsImportBareClause(it) => it.into(), AnyJsImportClause::JsImportDefaultClause(it) => it.into(), + AnyJsImportClause::JsImportDefaultExtraClause(it) => it.into(), AnyJsImportClause::JsImportNamedClause(it) => it.into(), AnyJsImportClause::JsImportNamespaceClause(it) => it.into(), } @@ -33008,73 +33194,6 @@ impl From for SyntaxElement { node.into() } } -impl From for AnyJsNamedImport { - fn from(node: JsNamedImportSpecifiers) -> AnyJsNamedImport { - AnyJsNamedImport::JsNamedImportSpecifiers(node) - } -} -impl From for AnyJsNamedImport { - fn from(node: JsNamespaceImportSpecifier) -> AnyJsNamedImport { - AnyJsNamedImport::JsNamespaceImportSpecifier(node) - } -} -impl AstNode for AnyJsNamedImport { - type Language = Language; - const KIND_SET: SyntaxKindSet = - JsNamedImportSpecifiers::KIND_SET.union(JsNamespaceImportSpecifier::KIND_SET); - fn can_cast(kind: SyntaxKind) -> bool { - matches!( - kind, - JS_NAMED_IMPORT_SPECIFIERS | JS_NAMESPACE_IMPORT_SPECIFIER - ) - } - fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - JS_NAMED_IMPORT_SPECIFIERS => { - AnyJsNamedImport::JsNamedImportSpecifiers(JsNamedImportSpecifiers { syntax }) - } - JS_NAMESPACE_IMPORT_SPECIFIER => { - AnyJsNamedImport::JsNamespaceImportSpecifier(JsNamespaceImportSpecifier { syntax }) - } - _ => return None, - }; - Some(res) - } - fn syntax(&self) -> &SyntaxNode { - match self { - AnyJsNamedImport::JsNamedImportSpecifiers(it) => &it.syntax, - AnyJsNamedImport::JsNamespaceImportSpecifier(it) => &it.syntax, - } - } - fn into_syntax(self) -> SyntaxNode { - match self { - AnyJsNamedImport::JsNamedImportSpecifiers(it) => it.syntax, - AnyJsNamedImport::JsNamespaceImportSpecifier(it) => it.syntax, - } - } -} -impl std::fmt::Debug for AnyJsNamedImport { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - AnyJsNamedImport::JsNamedImportSpecifiers(it) => std::fmt::Debug::fmt(it, f), - AnyJsNamedImport::JsNamespaceImportSpecifier(it) => std::fmt::Debug::fmt(it, f), - } - } -} -impl From for SyntaxNode { - fn from(n: AnyJsNamedImport) -> SyntaxNode { - match n { - AnyJsNamedImport::JsNamedImportSpecifiers(it) => it.into(), - AnyJsNamedImport::JsNamespaceImportSpecifier(it) => it.into(), - } - } -} -impl From for SyntaxElement { - fn from(n: AnyJsNamedImport) -> SyntaxElement { - let node: SyntaxNode = n.into(); - node.into() - } -} impl From for AnyJsNamedImportSpecifier { fn from(node: JsBogusNamedImportSpecifier) -> AnyJsNamedImportSpecifier { AnyJsNamedImportSpecifier::JsBogusNamedImportSpecifier(node) @@ -37070,6 +37189,11 @@ impl std::fmt::Display for AnyJsExpression { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for AnyJsExtraImportSpecifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for AnyJsForInOrOfInitializer { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -37130,11 +37254,6 @@ impl std::fmt::Display for AnyJsName { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for AnyJsNamedImport { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} impl std::fmt::Display for AnyJsNamedImportSpecifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -37700,6 +37819,11 @@ impl std::fmt::Display for JsImportDefaultClause { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for JsImportDefaultExtraClause { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for JsImportMetaExpression { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/crates/biome_js_syntax/src/generated/nodes_mut.rs b/crates/biome_js_syntax/src/generated/nodes_mut.rs index 11941fb03cf0..bd17a52366bd 100644 --- a/crates/biome_js_syntax/src/generated/nodes_mut.rs +++ b/crates/biome_js_syntax/src/generated/nodes_mut.rs @@ -817,12 +817,6 @@ impl JsDefaultImportSpecifier { .splice_slots(0usize..=0usize, once(Some(element.into_syntax().into()))), ) } - pub fn with_trailing_comma_token(self, element: SyntaxToken) -> Self { - Self::unwrap_cast( - self.syntax - .splice_slots(1usize..=1usize, once(Some(element.into()))), - ) - } } impl JsDirective { pub fn with_value_token(self, element: SyntaxToken) -> Self { @@ -1857,7 +1851,7 @@ impl JsImportDefaultClause { .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))), ) } - pub fn with_local_name(self, element: AnyJsBinding) -> Self { + pub fn with_default_specifier(self, element: JsDefaultImportSpecifier) -> Self { Self::unwrap_cast( self.syntax .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))), @@ -1882,6 +1876,44 @@ impl JsImportDefaultClause { )) } } +impl JsImportDefaultExtraClause { + pub fn with_default_specifier(self, element: JsDefaultImportSpecifier) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(0usize..=0usize, once(Some(element.into_syntax().into()))), + ) + } + pub fn with_comma_token(self, element: SyntaxToken) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(1usize..=1usize, once(Some(element.into()))), + ) + } + pub fn with_extra_specifier(self, element: AnyJsExtraImportSpecifier) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(2usize..=2usize, once(Some(element.into_syntax().into()))), + ) + } + pub fn with_from_token(self, element: SyntaxToken) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(3usize..=3usize, once(Some(element.into()))), + ) + } + pub fn with_source(self, element: JsModuleSource) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(4usize..=4usize, once(Some(element.into_syntax().into()))), + ) + } + pub fn with_assertion(self, element: Option) -> Self { + Self::unwrap_cast(self.syntax.splice_slots( + 5usize..=5usize, + once(element.map(|element| element.into_syntax().into())), + )) + } +} impl JsImportMetaExpression { pub fn with_import_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( @@ -1909,33 +1941,27 @@ impl JsImportNamedClause { .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))), ) } - pub fn with_default_specifier(self, element: Option) -> Self { - Self::unwrap_cast(self.syntax.splice_slots( - 1usize..=1usize, - once(element.map(|element| element.into_syntax().into())), - )) - } - pub fn with_named_import(self, element: AnyJsNamedImport) -> Self { + pub fn with_named_specifiers(self, element: JsNamedImportSpecifiers) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(2usize..=2usize, once(Some(element.into_syntax().into()))), + .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))), ) } pub fn with_from_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(3usize..=3usize, once(Some(element.into()))), + .splice_slots(2usize..=2usize, once(Some(element.into()))), ) } pub fn with_source(self, element: JsModuleSource) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(4usize..=4usize, once(Some(element.into_syntax().into()))), + .splice_slots(3usize..=3usize, once(Some(element.into_syntax().into()))), ) } pub fn with_assertion(self, element: Option) -> Self { Self::unwrap_cast(self.syntax.splice_slots( - 5usize..=5usize, + 4usize..=4usize, once(element.map(|element| element.into_syntax().into())), )) } @@ -1947,39 +1973,27 @@ impl JsImportNamespaceClause { .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))), ) } - pub fn with_star_token(self, element: SyntaxToken) -> Self { + pub fn with_namespace_specifier(self, element: JsNamespaceImportSpecifier) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(1usize..=1usize, once(Some(element.into()))), - ) - } - pub fn with_as_token(self, element: SyntaxToken) -> Self { - Self::unwrap_cast( - self.syntax - .splice_slots(2usize..=2usize, once(Some(element.into()))), - ) - } - pub fn with_local_name(self, element: AnyJsBinding) -> Self { - Self::unwrap_cast( - self.syntax - .splice_slots(3usize..=3usize, once(Some(element.into_syntax().into()))), + .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))), ) } pub fn with_from_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(4usize..=4usize, once(Some(element.into()))), + .splice_slots(2usize..=2usize, once(Some(element.into()))), ) } pub fn with_source(self, element: JsModuleSource) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(5usize..=5usize, once(Some(element.into_syntax().into()))), + .splice_slots(3usize..=3usize, once(Some(element.into_syntax().into()))), ) } pub fn with_assertion(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/crates/biome_js_syntax/src/import_ext.rs b/crates/biome_js_syntax/src/import_ext.rs index 6a40e3c237dd..dd81e43868d8 100644 --- a/crates/biome_js_syntax/src/import_ext.rs +++ b/crates/biome_js_syntax/src/import_ext.rs @@ -1,6 +1,6 @@ use crate::{ inner_string_text, AnyJsBinding, AnyJsImportClause, AnyJsNamedImportSpecifier, JsImport, - JsImportNamedClause, JsModuleSource, JsSyntaxToken, + JsModuleSource, JsSyntaxToken, }; use biome_rowan::{AstNode, SyntaxResult, TokenText}; @@ -15,7 +15,8 @@ impl JsImport { /// /// let source = make::js_module_source(make::js_string_literal("react")); /// let binding = make::js_identifier_binding(make::ident("React")); - /// let clause = make::js_import_default_clause(binding.into(), make::token(T![from]), source).build(); + /// let specifier = make::js_default_import_specifier(binding.into()); + /// let clause = make::js_import_default_clause(specifier, make::token(T![from]), source).build(); /// let import = make::js_import(make::token(T![import]), clause.into()).build(); /// /// assert_eq!(import.source_text().unwrap().text(), "react"); @@ -38,6 +39,7 @@ impl AnyJsImportClause { Self::JsImportDefaultClause(clause) => clause.type_token(), Self::JsImportNamedClause(clause) => clause.type_token(), Self::JsImportNamespaceClause(clause) => clause.type_token(), + Self::JsImportDefaultExtraClause(_) => None, } } @@ -49,16 +51,18 @@ impl AnyJsImportClause { /// /// let source = make::js_module_source(make::js_string_literal("react")); /// let binding = make::js_identifier_binding(make::ident("React")); - /// let clause = make::js_import_default_clause(binding.into(), make::token(T![from]), source).build(); + /// let specifier = make::js_default_import_specifier(binding.into()); + /// let clause = make::js_import_default_clause(specifier, make::token(T![from]), source).build(); /// /// assert_eq!(clause.source().unwrap().inner_string_text().unwrap().text(), "react"); /// ``` pub fn source(&self) -> SyntaxResult { match self { - Self::JsImportBareClause(node) => node.source(), - Self::JsImportDefaultClause(node) => node.source(), - Self::JsImportNamedClause(node) => node.source(), - Self::JsImportNamespaceClause(node) => node.source(), + Self::JsImportBareClause(clause) => clause.source(), + Self::JsImportDefaultClause(clause) => clause.source(), + Self::JsImportNamedClause(clause) => clause.source(), + Self::JsImportNamespaceClause(clause) => clause.source(), + Self::JsImportDefaultExtraClause(clause) => clause.source(), } } } @@ -79,17 +83,13 @@ impl AnyJsNamedImportSpecifier { } /// Returns the import clause that includes this specifier. - pub fn import_named_clause(&self) -> Option { - JsImportNamedClause::cast(self.syntax().ancestors().nth(3)?) + pub fn import_clause(&self) -> Option { + AnyJsImportClause::cast(self.syntax().ancestors().nth(3)?) } /// Returns `true` if this specifier or its import clause has **only** a type modifier. pub fn imports_only_types(&self) -> bool { - self.type_token().is_some() - || self - .import_named_clause() - .and_then(|x| x.type_token()) - .is_some() + self.type_token().is_some() || self.import_clause().and_then(|x| x.type_token()).is_some() } /// Imported name of this import specifier diff --git a/xtask/codegen/js.ungram b/xtask/codegen/js.ungram index ec9e58082e2d..3a1a1f6b79b7 100644 --- a/xtask/codegen/js.ungram +++ b/xtask/codegen/js.ungram @@ -1228,6 +1228,7 @@ AnyJsImportClause = | JsImportNamedClause | JsImportDefaultClause | JsImportNamespaceClause + | JsImportDefaultExtraClause // import "abcd" // import "abcd" assert ... @@ -1238,51 +1239,54 @@ JsImportBareClause = // import foo from "mod" // import type foo from "mod" JsImportDefaultClause = - 'type'? - local_name: AnyJsBinding - 'from' - source: JsModuleSource - assertion: JsImportAssertion? + 'type'? + default_specifier: JsDefaultImportSpecifier + 'from' + source: JsModuleSource + assertion: JsImportAssertion? // import * as foo from "mod"; // import type * as foo from "mod"; JsImportNamespaceClause = - 'type'? - '*' - 'as' - local_name: AnyJsBinding + 'type'? + namespace_specifier: JsNamespaceImportSpecifier 'from' source: JsModuleSource assertion: JsImportAssertion? -// import { a, b: c } from "d" +// import { a, b: c } from "d"; // ^^^^^^^^^^^^^^^^^^^^ -// import c, { b } from "c" -// ^^^^^^^^^^^^^^^^^ -// import { type a } from "c" +// import { type a } from "c"; // ^^^^^^^^^^^^^^^^^^^ -// import foo, * as bar from "mod" -// ^^^^^^^^^^^^^^^^^^^^^^^^ // import type { foo } from "mod"; // ^^^^^^^^^^^^^^^^^^^^^^^ -// import foo, { type bar } from "mod"; JsImportNamedClause = 'type'? - default_specifier: JsDefaultImportSpecifier? - named_import: AnyJsNamedImport + named_specifiers: JsNamedImportSpecifiers 'from' source: JsModuleSource assertion: JsImportAssertion? +// import c, { b } from "c" +// ^^^^^^^^^^^^^^^^^ +// import foo, { type bar } from "mod"; +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// import foo, * as bar from "mod"; +// ^^^^^^^^^^^^^^^^^^^^^^^^ +JsImportDefaultExtraClause = + default_specifier: JsDefaultImportSpecifier + ',' + extra_specifier: AnyJsExtraImportSpecifier + 'from' + source: JsModuleSource + assertion: JsImportAssertion? + +AnyJsExtraImportSpecifier = JsNamedImportSpecifiers | JsNamespaceImportSpecifier + // import a, { b, c } from "d"; // ^^ JsDefaultImportSpecifier = local_name: AnyJsBinding - trailing_comma: ',' - -AnyJsNamedImport = - JsNamedImportSpecifiers - | JsNamespaceImportSpecifier // import a, * as b from "d"; // ^^^^^^ diff --git a/xtask/codegen/src/generate_bindings.rs b/xtask/codegen/src/generate_bindings.rs index 943e958de432..de0def9e0912 100644 --- a/xtask/codegen/src/generate_bindings.rs +++ b/xtask/codegen/src/generate_bindings.rs @@ -3,10 +3,9 @@ use biome_js_formatter::{context::JsFormatOptions, format_node}; use biome_js_syntax::{ AnyJsBinding, AnyJsBindingPattern, AnyJsCallArgument, AnyJsDeclaration, AnyJsDeclarationClause, AnyJsExportClause, AnyJsExpression, AnyJsFormalParameter, AnyJsImportClause, - AnyJsLiteralExpression, AnyJsModuleItem, AnyJsName, AnyJsNamedImport, - AnyJsNamedImportSpecifier, AnyJsObjectMember, AnyJsObjectMemberName, AnyJsParameter, - AnyJsStatement, AnyTsName, AnyTsReturnType, AnyTsType, AnyTsTypeMember, JsFileSource, - TriviaPieceKind, T, + AnyJsLiteralExpression, AnyJsModuleItem, AnyJsName, AnyJsNamedImportSpecifier, + AnyJsObjectMember, AnyJsObjectMemberName, AnyJsParameter, AnyJsStatement, AnyTsName, + AnyTsReturnType, AnyTsType, AnyTsTypeMember, JsFileSource, TriviaPieceKind, T, }; use biome_rowan::AstNode; use biome_service::workspace_types::{generate_type, methods, ModuleQueue}; @@ -167,7 +166,7 @@ pub(crate) fn generate_workspace_bindings(mode: Mode) -> Result<()> { make::token(T![import]).with_leading_trivia(leading_comment.into_iter()), AnyJsImportClause::JsImportNamedClause( make::js_import_named_clause( - AnyJsNamedImport::JsNamedImportSpecifiers(make::js_named_import_specifiers( + make::js_named_import_specifiers( make::token(T!['{']), make::js_named_import_specifier_list( Some(AnyJsNamedImportSpecifier::JsShorthandNamedImportSpecifier( @@ -181,7 +180,7 @@ pub(crate) fn generate_workspace_bindings(mode: Mode) -> Result<()> { None, ), make::token(T!['}']), - )), + ), make::token(T![from]), make::js_module_source(make::js_string_literal("./transport")), ) diff --git a/xtask/codegen/src/kinds_src.rs b/xtask/codegen/src/kinds_src.rs index 6973d8f272d3..5a2fe4a53bab 100644 --- a/xtask/codegen/src/kinds_src.rs +++ b/xtask/codegen/src/kinds_src.rs @@ -359,6 +359,7 @@ pub const JS_KINDS_SRC: KindsSrc = KindsSrc { "JS_IMPORT_DEFAULT_CLAUSE", "JS_IMPORT_NAMESPACE_CLAUSE", "JS_IMPORT_NAMED_CLAUSE", + "JS_IMPORT_DEFAULT_EXTRA_CLAUSE", "JS_NAMED_IMPORT_SPECIFIERS", "JS_NAMED_IMPORT_SPECIFIER_LIST", "JS_NAMESPACE_IMPORT_SPECIFIER", From 8f858b77498159ff6a1c53a741089506e92a6f32 Mon Sep 17 00:00:00 2001 From: Victorien Elvinger Date: Wed, 13 Dec 2023 13:20:33 +0100 Subject: [PATCH 2/2] refactor: DefaultExtra -> Combined --- .../nursery/no_unused_imports.rs | 10 +- .../src/generated/node_factory.rs | 62 +-- .../src/generated/syntax_factory.rs | 38 +- crates/biome_js_formatter/src/generated.rs | 46 ++- .../src/js/any/combined_specifier.rs | 15 + .../src/js/any/extra_import_specifier.rs | 15 - .../src/js/any/import_clause.rs | 2 +- crates/biome_js_formatter/src/js/any/mod.rs | 2 +- ...ra_clause.rs => import_combined_clause.rs} | 20 +- .../biome_js_formatter/src/js/module/mod.rs | 2 +- crates/biome_js_parser/src/syntax/module.rs | 2 +- .../inline/ok/import_default_clauses.rast | 6 +- crates/biome_js_syntax/src/generated/kind.rs | 2 +- .../biome_js_syntax/src/generated/macros.rs | 9 +- crates/biome_js_syntax/src/generated/nodes.rs | 361 +++++++++--------- .../src/generated/nodes_mut.rs | 44 +-- crates/biome_js_syntax/src/import_ext.rs | 4 +- xtask/codegen/js.ungram | 8 +- xtask/codegen/src/kinds_src.rs | 2 +- 19 files changed, 322 insertions(+), 328 deletions(-) create mode 100644 crates/biome_js_formatter/src/js/any/combined_specifier.rs delete mode 100644 crates/biome_js_formatter/src/js/any/extra_import_specifier.rs rename crates/biome_js_formatter/src/js/module/{import_default_extra_clause.rs => import_combined_clause.rs} (57%) diff --git a/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs b/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs index 85a81b0126c0..ace9ab68a28e 100644 --- a/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs +++ b/crates/biome_js_analyze/src/semantic_analyzers/nursery/no_unused_imports.rs @@ -7,7 +7,7 @@ use biome_diagnostics::Applicability; use biome_js_factory::make; use biome_js_semantic::ReferencesExtensions; use biome_js_syntax::{ - binding_ext::AnyJsBindingDeclaration, AnyJsExtraImportSpecifier, AnyJsImportClause, + binding_ext::AnyJsBindingDeclaration, AnyJsCombinedSpecifier, AnyJsImportClause, JsIdentifierBinding, JsImport, JsLanguage, JsNamedImportSpecifierList, JsSyntaxNode, T, }; use biome_rowan::{AstNode, AstSeparatedList, BatchMutation, BatchMutationExt}; @@ -154,14 +154,14 @@ fn remove_import_specifier( ) -> Option<()> { let clause = specifier.parent().and_then(AnyJsImportClause::cast)?; match &clause { - AnyJsImportClause::JsImportDefaultExtraClause(default_extra_clause) => { + AnyJsImportClause::JsImportCombinedClause(default_extra_clause) => { let default_specifier = default_extra_clause.default_specifier().ok()?; let from_token = default_extra_clause.from_token().ok()?; let source = default_extra_clause.source().ok()?; let assertion = default_extra_clause.assertion(); if default_specifier.syntax() == specifier { - let new_clause = match default_extra_clause.extra_specifier().ok()? { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(named_specifier) => { + let new_clause = match default_extra_clause.specifier().ok()? { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(named_specifier) => { let named_clause = make::js_import_named_clause(named_specifier, from_token, source); let named_clause = if let Some(assertion) = assertion { @@ -171,7 +171,7 @@ fn remove_import_specifier( }; AnyJsImportClause::JsImportNamedClause(named_clause.build()) } - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(namespace_specifier) => { + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(namespace_specifier) => { let namespace_clause = make::js_import_namespace_clause( namespace_specifier, from_token, diff --git a/crates/biome_js_factory/src/generated/node_factory.rs b/crates/biome_js_factory/src/generated/node_factory.rs index fd48bef74cd5..af002d62af8b 100644 --- a/crates/biome_js_factory/src/generated/node_factory.rs +++ b/crates/biome_js_factory/src/generated/node_factory.rs @@ -2027,41 +2027,42 @@ pub fn js_import_call_expression( ], )) } -pub fn js_import_default_clause( +pub fn js_import_combined_clause( default_specifier: JsDefaultImportSpecifier, + comma_token: SyntaxToken, + specifier: AnyJsCombinedSpecifier, from_token: SyntaxToken, source: JsModuleSource, -) -> JsImportDefaultClauseBuilder { - JsImportDefaultClauseBuilder { +) -> JsImportCombinedClauseBuilder { + JsImportCombinedClauseBuilder { default_specifier, + comma_token, + specifier, from_token, source, - type_token: None, assertion: None, } } -pub struct JsImportDefaultClauseBuilder { +pub struct JsImportCombinedClauseBuilder { default_specifier: JsDefaultImportSpecifier, + comma_token: SyntaxToken, + specifier: AnyJsCombinedSpecifier, from_token: SyntaxToken, source: JsModuleSource, - type_token: Option, assertion: Option, } -impl JsImportDefaultClauseBuilder { - pub fn with_type_token(mut self, type_token: SyntaxToken) -> Self { - self.type_token = Some(type_token); - self - } +impl JsImportCombinedClauseBuilder { pub fn with_assertion(mut self, assertion: JsImportAssertion) -> Self { self.assertion = Some(assertion); self } - pub fn build(self) -> JsImportDefaultClause { - JsImportDefaultClause::unwrap_cast(SyntaxNode::new_detached( - JsSyntaxKind::JS_IMPORT_DEFAULT_CLAUSE, + pub fn build(self) -> JsImportCombinedClause { + JsImportCombinedClause::unwrap_cast(SyntaxNode::new_detached( + JsSyntaxKind::JS_IMPORT_COMBINED_CLAUSE, [ - self.type_token.map(|token| SyntaxElement::Token(token)), Some(SyntaxElement::Node(self.default_specifier.into_syntax())), + Some(SyntaxElement::Token(self.comma_token)), + Some(SyntaxElement::Node(self.specifier.into_syntax())), Some(SyntaxElement::Token(self.from_token)), Some(SyntaxElement::Node(self.source.into_syntax())), self.assertion @@ -2070,42 +2071,41 @@ impl JsImportDefaultClauseBuilder { )) } } -pub fn js_import_default_extra_clause( +pub fn js_import_default_clause( default_specifier: JsDefaultImportSpecifier, - comma_token: SyntaxToken, - extra_specifier: AnyJsExtraImportSpecifier, from_token: SyntaxToken, source: JsModuleSource, -) -> JsImportDefaultExtraClauseBuilder { - JsImportDefaultExtraClauseBuilder { +) -> JsImportDefaultClauseBuilder { + JsImportDefaultClauseBuilder { default_specifier, - comma_token, - extra_specifier, from_token, source, + type_token: None, assertion: None, } } -pub struct JsImportDefaultExtraClauseBuilder { +pub struct JsImportDefaultClauseBuilder { default_specifier: JsDefaultImportSpecifier, - comma_token: SyntaxToken, - extra_specifier: AnyJsExtraImportSpecifier, from_token: SyntaxToken, source: JsModuleSource, + type_token: Option, assertion: Option, } -impl JsImportDefaultExtraClauseBuilder { +impl JsImportDefaultClauseBuilder { + pub fn with_type_token(mut self, type_token: SyntaxToken) -> Self { + self.type_token = Some(type_token); + self + } pub fn with_assertion(mut self, assertion: JsImportAssertion) -> Self { self.assertion = Some(assertion); self } - pub fn build(self) -> JsImportDefaultExtraClause { - JsImportDefaultExtraClause::unwrap_cast(SyntaxNode::new_detached( - JsSyntaxKind::JS_IMPORT_DEFAULT_EXTRA_CLAUSE, + pub fn build(self) -> JsImportDefaultClause { + JsImportDefaultClause::unwrap_cast(SyntaxNode::new_detached( + JsSyntaxKind::JS_IMPORT_DEFAULT_CLAUSE, [ + self.type_token.map(|token| SyntaxElement::Token(token)), Some(SyntaxElement::Node(self.default_specifier.into_syntax())), - Some(SyntaxElement::Token(self.comma_token)), - Some(SyntaxElement::Node(self.extra_specifier.into_syntax())), Some(SyntaxElement::Token(self.from_token)), Some(SyntaxElement::Node(self.source.into_syntax())), self.assertion diff --git a/crates/biome_js_factory/src/generated/syntax_factory.rs b/crates/biome_js_factory/src/generated/syntax_factory.rs index a15b8779296c..27d8bc43d80d 100644 --- a/crates/biome_js_factory/src/generated/syntax_factory.rs +++ b/crates/biome_js_factory/src/generated/syntax_factory.rs @@ -2938,19 +2938,26 @@ impl SyntaxFactory for JsSyntaxFactory { } slots.into_node(JS_IMPORT_CALL_EXPRESSION, children) } - JS_IMPORT_DEFAULT_CLAUSE => { + JS_IMPORT_COMBINED_CLAUSE => { let mut elements = (&children).into_iter(); - let mut slots: RawNodeSlots<5usize> = RawNodeSlots::default(); + let mut slots: RawNodeSlots<6usize> = RawNodeSlots::default(); let mut current_element = elements.next(); if let Some(element) = ¤t_element { - if element.kind() == T![type] { + if JsDefaultImportSpecifier::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } } slots.next_slot(); if let Some(element) = ¤t_element { - if JsDefaultImportSpecifier::can_cast(element.kind()) { + if element.kind() == T ! [,] { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if let Some(element) = ¤t_element { + if AnyJsCombinedSpecifier::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } @@ -2979,32 +2986,25 @@ impl SyntaxFactory for JsSyntaxFactory { slots.next_slot(); if current_element.is_some() { return RawSyntaxNode::new( - JS_IMPORT_DEFAULT_CLAUSE.to_bogus(), + JS_IMPORT_COMBINED_CLAUSE.to_bogus(), children.into_iter().map(Some), ); } - slots.into_node(JS_IMPORT_DEFAULT_CLAUSE, children) + slots.into_node(JS_IMPORT_COMBINED_CLAUSE, children) } - JS_IMPORT_DEFAULT_EXTRA_CLAUSE => { + JS_IMPORT_DEFAULT_CLAUSE => { let mut elements = (&children).into_iter(); - let mut slots: RawNodeSlots<6usize> = RawNodeSlots::default(); + let mut slots: RawNodeSlots<5usize> = RawNodeSlots::default(); let mut current_element = elements.next(); if let Some(element) = ¤t_element { - if JsDefaultImportSpecifier::can_cast(element.kind()) { - slots.mark_present(); - current_element = elements.next(); - } - } - slots.next_slot(); - if let Some(element) = ¤t_element { - if element.kind() == T ! [,] { + if element.kind() == T![type] { slots.mark_present(); current_element = elements.next(); } } slots.next_slot(); if let Some(element) = ¤t_element { - if AnyJsExtraImportSpecifier::can_cast(element.kind()) { + if JsDefaultImportSpecifier::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } @@ -3033,11 +3033,11 @@ impl SyntaxFactory for JsSyntaxFactory { slots.next_slot(); if current_element.is_some() { return RawSyntaxNode::new( - JS_IMPORT_DEFAULT_EXTRA_CLAUSE.to_bogus(), + JS_IMPORT_DEFAULT_CLAUSE.to_bogus(), children.into_iter().map(Some), ); } - slots.into_node(JS_IMPORT_DEFAULT_EXTRA_CLAUSE, children) + slots.into_node(JS_IMPORT_DEFAULT_CLAUSE, children) } JS_IMPORT_META_EXPRESSION => { let mut elements = (&children).into_iter(); diff --git a/crates/biome_js_formatter/src/generated.rs b/crates/biome_js_formatter/src/generated.rs index 4113cf9b33e7..c28e87ab20c2 100644 --- a/crates/biome_js_formatter/src/generated.rs +++ b/crates/biome_js_formatter/src/generated.rs @@ -6384,38 +6384,44 @@ impl IntoFormat for biome_js_syntax::JsImportNamespaceClause { ) } } -impl FormatRule - for crate::js::module::import_default_extra_clause::FormatJsImportDefaultExtraClause +impl FormatRule + for crate::js::module::import_combined_clause::FormatJsImportCombinedClause { type Context = JsFormatContext; #[inline(always)] fn fmt( &self, - node: &biome_js_syntax::JsImportDefaultExtraClause, + node: &biome_js_syntax::JsImportCombinedClause, f: &mut JsFormatter, ) -> FormatResult<()> { - FormatNodeRule::::fmt(self, node, f) + FormatNodeRule::::fmt(self, node, f) } } -impl AsFormat for biome_js_syntax::JsImportDefaultExtraClause { +impl AsFormat for biome_js_syntax::JsImportCombinedClause { type Format<'a> = FormatRefWithRule< 'a, - biome_js_syntax::JsImportDefaultExtraClause, - crate::js::module::import_default_extra_clause::FormatJsImportDefaultExtraClause, + biome_js_syntax::JsImportCombinedClause, + crate::js::module::import_combined_clause::FormatJsImportCombinedClause, >; fn format(&self) -> Self::Format<'_> { #![allow(clippy::default_constructed_unit_structs)] - FormatRefWithRule :: new (self , crate :: js :: module :: import_default_extra_clause :: FormatJsImportDefaultExtraClause :: default ()) + FormatRefWithRule::new( + self, + crate::js::module::import_combined_clause::FormatJsImportCombinedClause::default(), + ) } } -impl IntoFormat for biome_js_syntax::JsImportDefaultExtraClause { +impl IntoFormat for biome_js_syntax::JsImportCombinedClause { type Format = FormatOwnedWithRule< - biome_js_syntax::JsImportDefaultExtraClause, - crate::js::module::import_default_extra_clause::FormatJsImportDefaultExtraClause, + biome_js_syntax::JsImportCombinedClause, + crate::js::module::import_combined_clause::FormatJsImportCombinedClause, >; fn into_format(self) -> Self::Format { #![allow(clippy::default_constructed_unit_structs)] - FormatOwnedWithRule :: new (self , crate :: js :: module :: import_default_extra_clause :: FormatJsImportDefaultExtraClause :: default ()) + FormatOwnedWithRule::new( + self, + crate::js::module::import_combined_clause::FormatJsImportCombinedClause::default(), + ) } } impl FormatRule @@ -12825,30 +12831,30 @@ impl IntoFormat for biome_js_syntax::AnyJsImportClause { ) } } -impl AsFormat for biome_js_syntax::AnyJsExtraImportSpecifier { +impl AsFormat for biome_js_syntax::AnyJsCombinedSpecifier { type Format<'a> = FormatRefWithRule< 'a, - biome_js_syntax::AnyJsExtraImportSpecifier, - crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier, + biome_js_syntax::AnyJsCombinedSpecifier, + crate::js::any::combined_specifier::FormatAnyJsCombinedSpecifier, >; fn format(&self) -> Self::Format<'_> { #![allow(clippy::default_constructed_unit_structs)] FormatRefWithRule::new( self, - crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier::default(), + crate::js::any::combined_specifier::FormatAnyJsCombinedSpecifier::default(), ) } } -impl IntoFormat for biome_js_syntax::AnyJsExtraImportSpecifier { +impl IntoFormat for biome_js_syntax::AnyJsCombinedSpecifier { type Format = FormatOwnedWithRule< - biome_js_syntax::AnyJsExtraImportSpecifier, - crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier, + biome_js_syntax::AnyJsCombinedSpecifier, + crate::js::any::combined_specifier::FormatAnyJsCombinedSpecifier, >; fn into_format(self) -> Self::Format { #![allow(clippy::default_constructed_unit_structs)] FormatOwnedWithRule::new( self, - crate::js::any::extra_import_specifier::FormatAnyJsExtraImportSpecifier::default(), + crate::js::any::combined_specifier::FormatAnyJsCombinedSpecifier::default(), ) } } diff --git a/crates/biome_js_formatter/src/js/any/combined_specifier.rs b/crates/biome_js_formatter/src/js/any/combined_specifier.rs new file mode 100644 index 000000000000..20bdc888a891 --- /dev/null +++ b/crates/biome_js_formatter/src/js/any/combined_specifier.rs @@ -0,0 +1,15 @@ +//! This is a generated file. Don't modify it by hand! Run 'cargo codegen formatter' to re-generate the file. + +use crate::prelude::*; +use biome_js_syntax::AnyJsCombinedSpecifier; +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatAnyJsCombinedSpecifier; +impl FormatRule for FormatAnyJsCombinedSpecifier { + type Context = JsFormatContext; + fn fmt(&self, node: &AnyJsCombinedSpecifier, f: &mut JsFormatter) -> FormatResult<()> { + match node { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(node) => node.format().fmt(f), + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(node) => node.format().fmt(f), + } + } +} diff --git a/crates/biome_js_formatter/src/js/any/extra_import_specifier.rs b/crates/biome_js_formatter/src/js/any/extra_import_specifier.rs deleted file mode 100644 index 02fd16616a22..000000000000 --- a/crates/biome_js_formatter/src/js/any/extra_import_specifier.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! This is a generated file. Don't modify it by hand! Run 'cargo codegen formatter' to re-generate the file. - -use crate::prelude::*; -use biome_js_syntax::AnyJsExtraImportSpecifier; -#[derive(Debug, Clone, Default)] -pub(crate) struct FormatAnyJsExtraImportSpecifier; -impl FormatRule for FormatAnyJsExtraImportSpecifier { - type Context = JsFormatContext; - fn fmt(&self, node: &AnyJsExtraImportSpecifier, f: &mut JsFormatter) -> FormatResult<()> { - match node { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(node) => node.format().fmt(f), - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(node) => node.format().fmt(f), - } - } -} diff --git a/crates/biome_js_formatter/src/js/any/import_clause.rs b/crates/biome_js_formatter/src/js/any/import_clause.rs index 68dc26c52861..847984d8b580 100644 --- a/crates/biome_js_formatter/src/js/any/import_clause.rs +++ b/crates/biome_js_formatter/src/js/any/import_clause.rs @@ -12,7 +12,7 @@ impl FormatRule for FormatAnyJsImportClause { AnyJsImportClause::JsImportNamedClause(node) => node.format().fmt(f), AnyJsImportClause::JsImportDefaultClause(node) => node.format().fmt(f), AnyJsImportClause::JsImportNamespaceClause(node) => node.format().fmt(f), - AnyJsImportClause::JsImportDefaultExtraClause(node) => node.format().fmt(f), + AnyJsImportClause::JsImportCombinedClause(node) => node.format().fmt(f), } } } diff --git a/crates/biome_js_formatter/src/js/any/mod.rs b/crates/biome_js_formatter/src/js/any/mod.rs index 864f2550f38a..fdb90790b24a 100644 --- a/crates/biome_js_formatter/src/js/any/mod.rs +++ b/crates/biome_js_formatter/src/js/any/mod.rs @@ -12,6 +12,7 @@ pub(crate) mod call_argument; pub(crate) mod class; pub(crate) mod class_member; pub(crate) mod class_member_name; +pub(crate) mod combined_specifier; pub(crate) mod constructor_parameter; pub(crate) mod declaration; pub(crate) mod declaration_clause; @@ -20,7 +21,6 @@ pub(crate) mod export_clause; pub(crate) mod export_default_declaration; pub(crate) mod export_named_specifier; pub(crate) mod expression; -pub(crate) mod extra_import_specifier; pub(crate) mod for_in_or_of_initializer; pub(crate) mod for_initializer; pub(crate) mod formal_parameter; diff --git a/crates/biome_js_formatter/src/js/module/import_default_extra_clause.rs b/crates/biome_js_formatter/src/js/module/import_combined_clause.rs similarity index 57% rename from crates/biome_js_formatter/src/js/module/import_default_extra_clause.rs rename to crates/biome_js_formatter/src/js/module/import_combined_clause.rs index 82147d4cd5fe..8b202726cf33 100644 --- a/crates/biome_js_formatter/src/js/module/import_default_extra_clause.rs +++ b/crates/biome_js_formatter/src/js/module/import_combined_clause.rs @@ -1,22 +1,18 @@ use crate::prelude::*; use biome_formatter::write; -use biome_js_syntax::JsImportDefaultExtraClause; -use biome_js_syntax::JsImportDefaultExtraClauseFields; +use biome_js_syntax::JsImportCombinedClause; +use biome_js_syntax::JsImportCombinedClauseFields; #[derive(Debug, Clone, Default)] -pub(crate) struct FormatJsImportDefaultExtraClause; +pub(crate) struct FormatJsImportCombinedClause; -impl FormatNodeRule for FormatJsImportDefaultExtraClause { - fn fmt_fields( - &self, - node: &JsImportDefaultExtraClause, - f: &mut JsFormatter, - ) -> FormatResult<()> { - let JsImportDefaultExtraClauseFields { +impl FormatNodeRule for FormatJsImportCombinedClause { + fn fmt_fields(&self, node: &JsImportCombinedClause, f: &mut JsFormatter) -> FormatResult<()> { + let JsImportCombinedClauseFields { default_specifier, comma_token, - extra_specifier, + specifier, from_token, source, assertion, @@ -27,7 +23,7 @@ impl FormatNodeRule for FormatJsImportDefaultExtraCl default_specifier.format(), comma_token.format(), space(), - extra_specifier.format(), + specifier.format(), space(), from_token.format(), space(), diff --git a/crates/biome_js_formatter/src/js/module/mod.rs b/crates/biome_js_formatter/src/js/module/mod.rs index a871a1f891b7..2cb017088f1c 100644 --- a/crates/biome_js_formatter/src/js/module/mod.rs +++ b/crates/biome_js_formatter/src/js/module/mod.rs @@ -15,8 +15,8 @@ pub(crate) mod import; pub(crate) mod import_assertion; pub(crate) mod import_assertion_entry; pub(crate) mod import_bare_clause; +pub(crate) mod import_combined_clause; pub(crate) mod import_default_clause; -pub(crate) mod import_default_extra_clause; pub(crate) mod import_named_clause; pub(crate) mod import_namespace_clause; pub(crate) mod literal_export_name; diff --git a/crates/biome_js_parser/src/syntax/module.rs b/crates/biome_js_parser/src/syntax/module.rs index 5782e99b8d64..182e3f36560b 100644 --- a/crates/biome_js_parser/src/syntax/module.rs +++ b/crates/biome_js_parser/src/syntax/module.rs @@ -348,7 +348,7 @@ fn parse_import_default_clauses_rest( p.error(p.err_builder("A type-only import can specify a default import or named bindings, but not both.", start..end,)) } - JS_IMPORT_DEFAULT_EXTRA_CLAUSE + JS_IMPORT_COMBINED_CLAUSE } _ => JS_IMPORT_DEFAULT_CLAUSE, }; diff --git a/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast b/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast index d5a737e178cb..709a24cb7b7f 100644 --- a/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast +++ b/crates/biome_js_parser/test_data/inline/ok/import_default_clauses.rast @@ -5,14 +5,14 @@ JsModule { items: JsModuleItemList [ JsImport { import_token: IMPORT_KW@0..7 "import" [] [Whitespace(" ")], - import_clause: JsImportDefaultExtraClause { + import_clause: JsImportCombinedClause { default_specifier: JsDefaultImportSpecifier { local_name: JsIdentifierBinding { name_token: IDENT@7..8 "e" [] [], }, }, comma_token: COMMA@8..10 "," [] [Whitespace(" ")], - extra_specifier: JsNamedImportSpecifiers { + specifier: JsNamedImportSpecifiers { l_curly_token: L_CURLY@10..12 "{" [] [Whitespace(" ")], specifiers: JsNamedImportSpecifierList [ JsShorthandNamedImportSpecifier { @@ -43,7 +43,7 @@ JsModule { 3: JS_MODULE_ITEM_LIST@0..25 0: JS_IMPORT@0..25 0: IMPORT_KW@0..7 "import" [] [Whitespace(" ")] - 1: JS_IMPORT_DEFAULT_EXTRA_CLAUSE@7..24 + 1: JS_IMPORT_COMBINED_CLAUSE@7..24 0: JS_DEFAULT_IMPORT_SPECIFIER@7..8 0: JS_IDENTIFIER_BINDING@7..8 0: IDENT@7..8 "e" [] [] diff --git a/crates/biome_js_syntax/src/generated/kind.rs b/crates/biome_js_syntax/src/generated/kind.rs index 37048a60c1c9..605e34387375 100644 --- a/crates/biome_js_syntax/src/generated/kind.rs +++ b/crates/biome_js_syntax/src/generated/kind.rs @@ -341,7 +341,7 @@ pub enum JsSyntaxKind { JS_IMPORT_DEFAULT_CLAUSE, JS_IMPORT_NAMESPACE_CLAUSE, JS_IMPORT_NAMED_CLAUSE, - JS_IMPORT_DEFAULT_EXTRA_CLAUSE, + JS_IMPORT_COMBINED_CLAUSE, JS_NAMED_IMPORT_SPECIFIERS, JS_NAMED_IMPORT_SPECIFIER_LIST, JS_NAMESPACE_IMPORT_SPECIFIER, diff --git a/crates/biome_js_syntax/src/generated/macros.rs b/crates/biome_js_syntax/src/generated/macros.rs index 32f782325f26..c0e82bdad0f7 100644 --- a/crates/biome_js_syntax/src/generated/macros.rs +++ b/crates/biome_js_syntax/src/generated/macros.rs @@ -330,13 +330,12 @@ macro_rules! map_syntax_node { let $pattern = unsafe { $crate::JsImportCallExpression::new_unchecked(node) }; $body } - $crate::JsSyntaxKind::JS_IMPORT_DEFAULT_CLAUSE => { - let $pattern = unsafe { $crate::JsImportDefaultClause::new_unchecked(node) }; + $crate::JsSyntaxKind::JS_IMPORT_COMBINED_CLAUSE => { + let $pattern = unsafe { $crate::JsImportCombinedClause::new_unchecked(node) }; $body } - $crate::JsSyntaxKind::JS_IMPORT_DEFAULT_EXTRA_CLAUSE => { - let $pattern = - unsafe { $crate::JsImportDefaultExtraClause::new_unchecked(node) }; + $crate::JsSyntaxKind::JS_IMPORT_DEFAULT_CLAUSE => { + let $pattern = unsafe { $crate::JsImportDefaultClause::new_unchecked(node) }; $body } $crate::JsSyntaxKind::JS_IMPORT_META_EXPRESSION => { diff --git a/crates/biome_js_syntax/src/generated/nodes.rs b/crates/biome_js_syntax/src/generated/nodes.rs index eb8098ddf43f..db65b7af098e 100644 --- a/crates/biome_js_syntax/src/generated/nodes.rs +++ b/crates/biome_js_syntax/src/generated/nodes.rs @@ -3751,10 +3751,10 @@ pub struct JsImportCallExpressionFields { pub arguments: SyntaxResult, } #[derive(Clone, PartialEq, Eq, Hash)] -pub struct JsImportDefaultClause { +pub struct JsImportCombinedClause { pub(crate) syntax: SyntaxNode, } -impl JsImportDefaultClause { +impl JsImportCombinedClause { #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"] #[doc = r""] #[doc = r" # Safety"] @@ -3764,33 +3764,37 @@ impl JsImportDefaultClause { pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self { Self { syntax } } - pub fn as_fields(&self) -> JsImportDefaultClauseFields { - JsImportDefaultClauseFields { - type_token: self.type_token(), + pub fn as_fields(&self) -> JsImportCombinedClauseFields { + JsImportCombinedClauseFields { default_specifier: self.default_specifier(), + comma_token: self.comma_token(), + specifier: self.specifier(), from_token: self.from_token(), source: self.source(), assertion: self.assertion(), } } - pub fn type_token(&self) -> Option { - support::token(&self.syntax, 0usize) - } pub fn default_specifier(&self) -> SyntaxResult { - support::required_node(&self.syntax, 1usize) + support::required_node(&self.syntax, 0usize) + } + pub fn comma_token(&self) -> SyntaxResult { + support::required_token(&self.syntax, 1usize) + } + pub fn specifier(&self) -> SyntaxResult { + support::required_node(&self.syntax, 2usize) } pub fn from_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 2usize) + support::required_token(&self.syntax, 3usize) } pub fn source(&self) -> SyntaxResult { - support::required_node(&self.syntax, 3usize) + support::required_node(&self.syntax, 4usize) } pub fn assertion(&self) -> Option { - support::node(&self.syntax, 4usize) + support::node(&self.syntax, 5usize) } } #[cfg(feature = "serde")] -impl Serialize for JsImportDefaultClause { +impl Serialize for JsImportCombinedClause { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -3799,18 +3803,19 @@ impl Serialize for JsImportDefaultClause { } } #[cfg_attr(feature = "serde", derive(Serialize))] -pub struct JsImportDefaultClauseFields { - pub type_token: Option, +pub struct JsImportCombinedClauseFields { pub default_specifier: SyntaxResult, + pub comma_token: SyntaxResult, + pub specifier: SyntaxResult, pub from_token: SyntaxResult, pub source: SyntaxResult, pub assertion: Option, } #[derive(Clone, PartialEq, Eq, Hash)] -pub struct JsImportDefaultExtraClause { +pub struct JsImportDefaultClause { pub(crate) syntax: SyntaxNode, } -impl JsImportDefaultExtraClause { +impl JsImportDefaultClause { #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"] #[doc = r""] #[doc = r" # Safety"] @@ -3820,37 +3825,33 @@ impl JsImportDefaultExtraClause { pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self { Self { syntax } } - pub fn as_fields(&self) -> JsImportDefaultExtraClauseFields { - JsImportDefaultExtraClauseFields { + pub fn as_fields(&self) -> JsImportDefaultClauseFields { + JsImportDefaultClauseFields { + type_token: self.type_token(), default_specifier: self.default_specifier(), - comma_token: self.comma_token(), - extra_specifier: self.extra_specifier(), from_token: self.from_token(), source: self.source(), assertion: self.assertion(), } } - pub fn default_specifier(&self) -> SyntaxResult { - support::required_node(&self.syntax, 0usize) - } - pub fn comma_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 1usize) + pub fn type_token(&self) -> Option { + support::token(&self.syntax, 0usize) } - pub fn extra_specifier(&self) -> SyntaxResult { - support::required_node(&self.syntax, 2usize) + pub fn default_specifier(&self) -> SyntaxResult { + support::required_node(&self.syntax, 1usize) } pub fn from_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 3usize) + support::required_token(&self.syntax, 2usize) } pub fn source(&self) -> SyntaxResult { - support::required_node(&self.syntax, 4usize) + support::required_node(&self.syntax, 3usize) } pub fn assertion(&self) -> Option { - support::node(&self.syntax, 5usize) + support::node(&self.syntax, 4usize) } } #[cfg(feature = "serde")] -impl Serialize for JsImportDefaultExtraClause { +impl Serialize for JsImportDefaultClause { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -3859,10 +3860,9 @@ impl Serialize for JsImportDefaultExtraClause { } } #[cfg_attr(feature = "serde", derive(Serialize))] -pub struct JsImportDefaultExtraClauseFields { +pub struct JsImportDefaultClauseFields { + pub type_token: Option, pub default_specifier: SyntaxResult, - pub comma_token: SyntaxResult, - pub extra_specifier: SyntaxResult, pub from_token: SyntaxResult, pub source: SyntaxResult, pub assertion: Option, @@ -13906,6 +13906,26 @@ impl AnyJsClassMemberName { } #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize))] +pub enum AnyJsCombinedSpecifier { + JsNamedImportSpecifiers(JsNamedImportSpecifiers), + JsNamespaceImportSpecifier(JsNamespaceImportSpecifier), +} +impl AnyJsCombinedSpecifier { + pub fn as_js_named_import_specifiers(&self) -> Option<&JsNamedImportSpecifiers> { + match &self { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(item) => Some(item), + _ => None, + } + } + pub fn as_js_namespace_import_specifier(&self) -> Option<&JsNamespaceImportSpecifier> { + match &self { + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(item) => Some(item), + _ => None, + } + } +} +#[derive(Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyJsConstructorParameter { AnyJsFormalParameter(AnyJsFormalParameter), JsRestParameter(JsRestParameter), @@ -14542,26 +14562,6 @@ impl AnyJsExpression { } #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize))] -pub enum AnyJsExtraImportSpecifier { - JsNamedImportSpecifiers(JsNamedImportSpecifiers), - JsNamespaceImportSpecifier(JsNamespaceImportSpecifier), -} -impl AnyJsExtraImportSpecifier { - pub fn as_js_named_import_specifiers(&self) -> Option<&JsNamedImportSpecifiers> { - match &self { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(item) => Some(item), - _ => None, - } - } - pub fn as_js_namespace_import_specifier(&self) -> Option<&JsNamespaceImportSpecifier> { - match &self { - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(item) => Some(item), - _ => None, - } - } -} -#[derive(Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyJsForInOrOfInitializer { AnyJsAssignmentPattern(AnyJsAssignmentPattern), JsForVariableDeclaration(JsForVariableDeclaration), @@ -14700,8 +14700,8 @@ impl AnyJsImportAssertionEntry { #[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyJsImportClause { JsImportBareClause(JsImportBareClause), + JsImportCombinedClause(JsImportCombinedClause), JsImportDefaultClause(JsImportDefaultClause), - JsImportDefaultExtraClause(JsImportDefaultExtraClause), JsImportNamedClause(JsImportNamedClause), JsImportNamespaceClause(JsImportNamespaceClause), } @@ -14712,15 +14712,15 @@ impl AnyJsImportClause { _ => None, } } - pub fn as_js_import_default_clause(&self) -> Option<&JsImportDefaultClause> { + pub fn as_js_import_combined_clause(&self) -> Option<&JsImportCombinedClause> { match &self { - AnyJsImportClause::JsImportDefaultClause(item) => Some(item), + AnyJsImportClause::JsImportCombinedClause(item) => Some(item), _ => None, } } - pub fn as_js_import_default_extra_clause(&self) -> Option<&JsImportDefaultExtraClause> { + pub fn as_js_import_default_clause(&self) -> Option<&JsImportDefaultClause> { match &self { - AnyJsImportClause::JsImportDefaultExtraClause(item) => Some(item), + AnyJsImportClause::JsImportDefaultClause(item) => Some(item), _ => None, } } @@ -19949,12 +19949,12 @@ impl From for SyntaxElement { n.syntax.into() } } -impl AstNode for JsImportDefaultClause { +impl AstNode for JsImportCombinedClause { type Language = Language; const KIND_SET: SyntaxKindSet = - SyntaxKindSet::from_raw(RawSyntaxKind(JS_IMPORT_DEFAULT_CLAUSE as u16)); + SyntaxKindSet::from_raw(RawSyntaxKind(JS_IMPORT_COMBINED_CLAUSE as u16)); fn can_cast(kind: SyntaxKind) -> bool { - kind == JS_IMPORT_DEFAULT_CLAUSE + kind == JS_IMPORT_COMBINED_CLAUSE } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { @@ -19970,17 +19970,18 @@ impl AstNode for JsImportDefaultClause { self.syntax } } -impl std::fmt::Debug for JsImportDefaultClause { +impl std::fmt::Debug for JsImportCombinedClause { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("JsImportDefaultClause") - .field( - "type_token", - &support::DebugOptionalElement(self.type_token()), - ) + f.debug_struct("JsImportCombinedClause") .field( "default_specifier", &support::DebugSyntaxResult(self.default_specifier()), ) + .field( + "comma_token", + &support::DebugSyntaxResult(self.comma_token()), + ) + .field("specifier", &support::DebugSyntaxResult(self.specifier())) .field("from_token", &support::DebugSyntaxResult(self.from_token())) .field("source", &support::DebugSyntaxResult(self.source())) .field( @@ -19990,22 +19991,22 @@ impl std::fmt::Debug for JsImportDefaultClause { .finish() } } -impl From for SyntaxNode { - fn from(n: JsImportDefaultClause) -> SyntaxNode { +impl From for SyntaxNode { + fn from(n: JsImportCombinedClause) -> SyntaxNode { n.syntax } } -impl From for SyntaxElement { - fn from(n: JsImportDefaultClause) -> SyntaxElement { +impl From for SyntaxElement { + fn from(n: JsImportCombinedClause) -> SyntaxElement { n.syntax.into() } } -impl AstNode for JsImportDefaultExtraClause { +impl AstNode for JsImportDefaultClause { type Language = Language; const KIND_SET: SyntaxKindSet = - SyntaxKindSet::from_raw(RawSyntaxKind(JS_IMPORT_DEFAULT_EXTRA_CLAUSE as u16)); + SyntaxKindSet::from_raw(RawSyntaxKind(JS_IMPORT_DEFAULT_CLAUSE as u16)); fn can_cast(kind: SyntaxKind) -> bool { - kind == JS_IMPORT_DEFAULT_EXTRA_CLAUSE + kind == JS_IMPORT_DEFAULT_CLAUSE } fn cast(syntax: SyntaxNode) -> Option { if Self::can_cast(syntax.kind()) { @@ -20021,20 +20022,16 @@ impl AstNode for JsImportDefaultExtraClause { self.syntax } } -impl std::fmt::Debug for JsImportDefaultExtraClause { +impl std::fmt::Debug for JsImportDefaultClause { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("JsImportDefaultExtraClause") - .field( - "default_specifier", - &support::DebugSyntaxResult(self.default_specifier()), - ) + f.debug_struct("JsImportDefaultClause") .field( - "comma_token", - &support::DebugSyntaxResult(self.comma_token()), + "type_token", + &support::DebugOptionalElement(self.type_token()), ) .field( - "extra_specifier", - &support::DebugSyntaxResult(self.extra_specifier()), + "default_specifier", + &support::DebugSyntaxResult(self.default_specifier()), ) .field("from_token", &support::DebugSyntaxResult(self.from_token())) .field("source", &support::DebugSyntaxResult(self.source())) @@ -20045,13 +20042,13 @@ impl std::fmt::Debug for JsImportDefaultExtraClause { .finish() } } -impl From for SyntaxNode { - fn from(n: JsImportDefaultExtraClause) -> SyntaxNode { +impl From for SyntaxNode { + fn from(n: JsImportDefaultClause) -> SyntaxNode { n.syntax } } -impl From for SyntaxElement { - fn from(n: JsImportDefaultExtraClause) -> SyntaxElement { +impl From for SyntaxElement { + fn from(n: JsImportDefaultClause) -> SyntaxElement { n.syntax.into() } } @@ -30683,6 +30680,75 @@ impl From for SyntaxElement { node.into() } } +impl From for AnyJsCombinedSpecifier { + fn from(node: JsNamedImportSpecifiers) -> AnyJsCombinedSpecifier { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(node) + } +} +impl From for AnyJsCombinedSpecifier { + fn from(node: JsNamespaceImportSpecifier) -> AnyJsCombinedSpecifier { + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(node) + } +} +impl AstNode for AnyJsCombinedSpecifier { + type Language = Language; + const KIND_SET: SyntaxKindSet = + JsNamedImportSpecifiers::KIND_SET.union(JsNamespaceImportSpecifier::KIND_SET); + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + JS_NAMED_IMPORT_SPECIFIERS | JS_NAMESPACE_IMPORT_SPECIFIER + ) + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + JS_NAMED_IMPORT_SPECIFIERS => { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(JsNamedImportSpecifiers { syntax }) + } + JS_NAMESPACE_IMPORT_SPECIFIER => { + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(JsNamespaceImportSpecifier { + syntax, + }) + } + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + match self { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(it) => &it.syntax, + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(it) => &it.syntax, + } + } + fn into_syntax(self) -> SyntaxNode { + match self { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(it) => it.syntax, + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(it) => it.syntax, + } + } +} +impl std::fmt::Debug for AnyJsCombinedSpecifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(it) => std::fmt::Debug::fmt(it, f), + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(it) => std::fmt::Debug::fmt(it, f), + } + } +} +impl From for SyntaxNode { + fn from(n: AnyJsCombinedSpecifier) -> SyntaxNode { + match n { + AnyJsCombinedSpecifier::JsNamedImportSpecifiers(it) => it.into(), + AnyJsCombinedSpecifier::JsNamespaceImportSpecifier(it) => it.into(), + } + } +} +impl From for SyntaxElement { + fn from(n: AnyJsCombinedSpecifier) -> SyntaxElement { + let node: SyntaxNode = n.into(); + node.into() + } +} impl From for AnyJsConstructorParameter { fn from(node: JsRestParameter) -> AnyJsConstructorParameter { AnyJsConstructorParameter::JsRestParameter(node) @@ -32160,79 +32226,6 @@ impl From for SyntaxElement { node.into() } } -impl From for AnyJsExtraImportSpecifier { - fn from(node: JsNamedImportSpecifiers) -> AnyJsExtraImportSpecifier { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(node) - } -} -impl From for AnyJsExtraImportSpecifier { - fn from(node: JsNamespaceImportSpecifier) -> AnyJsExtraImportSpecifier { - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(node) - } -} -impl AstNode for AnyJsExtraImportSpecifier { - type Language = Language; - const KIND_SET: SyntaxKindSet = - JsNamedImportSpecifiers::KIND_SET.union(JsNamespaceImportSpecifier::KIND_SET); - fn can_cast(kind: SyntaxKind) -> bool { - matches!( - kind, - JS_NAMED_IMPORT_SPECIFIERS | JS_NAMESPACE_IMPORT_SPECIFIER - ) - } - fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - JS_NAMED_IMPORT_SPECIFIERS => { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(JsNamedImportSpecifiers { - syntax, - }) - } - JS_NAMESPACE_IMPORT_SPECIFIER => { - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(JsNamespaceImportSpecifier { - syntax, - }) - } - _ => return None, - }; - Some(res) - } - fn syntax(&self) -> &SyntaxNode { - match self { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => &it.syntax, - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => &it.syntax, - } - } - fn into_syntax(self) -> SyntaxNode { - match self { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => it.syntax, - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => it.syntax, - } - } -} -impl std::fmt::Debug for AnyJsExtraImportSpecifier { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => std::fmt::Debug::fmt(it, f), - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => { - std::fmt::Debug::fmt(it, f) - } - } - } -} -impl From for SyntaxNode { - fn from(n: AnyJsExtraImportSpecifier) -> SyntaxNode { - match n { - AnyJsExtraImportSpecifier::JsNamedImportSpecifiers(it) => it.into(), - AnyJsExtraImportSpecifier::JsNamespaceImportSpecifier(it) => it.into(), - } - } -} -impl From for SyntaxElement { - fn from(n: AnyJsExtraImportSpecifier) -> SyntaxElement { - let node: SyntaxNode = n.into(); - node.into() - } -} impl From for AnyJsForInOrOfInitializer { fn from(node: JsForVariableDeclaration) -> AnyJsForInOrOfInitializer { AnyJsForInOrOfInitializer::JsForVariableDeclaration(node) @@ -32668,16 +32661,16 @@ impl From for AnyJsImportClause { AnyJsImportClause::JsImportBareClause(node) } } +impl From for AnyJsImportClause { + fn from(node: JsImportCombinedClause) -> AnyJsImportClause { + AnyJsImportClause::JsImportCombinedClause(node) + } +} impl From for AnyJsImportClause { fn from(node: JsImportDefaultClause) -> AnyJsImportClause { AnyJsImportClause::JsImportDefaultClause(node) } } -impl From for AnyJsImportClause { - fn from(node: JsImportDefaultExtraClause) -> AnyJsImportClause { - AnyJsImportClause::JsImportDefaultExtraClause(node) - } -} impl From for AnyJsImportClause { fn from(node: JsImportNamedClause) -> AnyJsImportClause { AnyJsImportClause::JsImportNamedClause(node) @@ -32691,16 +32684,16 @@ impl From for AnyJsImportClause { impl AstNode for AnyJsImportClause { type Language = Language; const KIND_SET: SyntaxKindSet = JsImportBareClause::KIND_SET + .union(JsImportCombinedClause::KIND_SET) .union(JsImportDefaultClause::KIND_SET) - .union(JsImportDefaultExtraClause::KIND_SET) .union(JsImportNamedClause::KIND_SET) .union(JsImportNamespaceClause::KIND_SET); fn can_cast(kind: SyntaxKind) -> bool { matches!( kind, JS_IMPORT_BARE_CLAUSE + | JS_IMPORT_COMBINED_CLAUSE | JS_IMPORT_DEFAULT_CLAUSE - | JS_IMPORT_DEFAULT_EXTRA_CLAUSE | JS_IMPORT_NAMED_CLAUSE | JS_IMPORT_NAMESPACE_CLAUSE ) @@ -32710,12 +32703,12 @@ impl AstNode for AnyJsImportClause { JS_IMPORT_BARE_CLAUSE => { AnyJsImportClause::JsImportBareClause(JsImportBareClause { syntax }) } + JS_IMPORT_COMBINED_CLAUSE => { + AnyJsImportClause::JsImportCombinedClause(JsImportCombinedClause { syntax }) + } JS_IMPORT_DEFAULT_CLAUSE => { AnyJsImportClause::JsImportDefaultClause(JsImportDefaultClause { syntax }) } - JS_IMPORT_DEFAULT_EXTRA_CLAUSE => { - AnyJsImportClause::JsImportDefaultExtraClause(JsImportDefaultExtraClause { syntax }) - } JS_IMPORT_NAMED_CLAUSE => { AnyJsImportClause::JsImportNamedClause(JsImportNamedClause { syntax }) } @@ -32729,8 +32722,8 @@ impl AstNode for AnyJsImportClause { fn syntax(&self) -> &SyntaxNode { match self { AnyJsImportClause::JsImportBareClause(it) => &it.syntax, + AnyJsImportClause::JsImportCombinedClause(it) => &it.syntax, AnyJsImportClause::JsImportDefaultClause(it) => &it.syntax, - AnyJsImportClause::JsImportDefaultExtraClause(it) => &it.syntax, AnyJsImportClause::JsImportNamedClause(it) => &it.syntax, AnyJsImportClause::JsImportNamespaceClause(it) => &it.syntax, } @@ -32738,8 +32731,8 @@ impl AstNode for AnyJsImportClause { fn into_syntax(self) -> SyntaxNode { match self { AnyJsImportClause::JsImportBareClause(it) => it.syntax, + AnyJsImportClause::JsImportCombinedClause(it) => it.syntax, AnyJsImportClause::JsImportDefaultClause(it) => it.syntax, - AnyJsImportClause::JsImportDefaultExtraClause(it) => it.syntax, AnyJsImportClause::JsImportNamedClause(it) => it.syntax, AnyJsImportClause::JsImportNamespaceClause(it) => it.syntax, } @@ -32749,8 +32742,8 @@ impl std::fmt::Debug for AnyJsImportClause { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { AnyJsImportClause::JsImportBareClause(it) => std::fmt::Debug::fmt(it, f), + AnyJsImportClause::JsImportCombinedClause(it) => std::fmt::Debug::fmt(it, f), AnyJsImportClause::JsImportDefaultClause(it) => std::fmt::Debug::fmt(it, f), - AnyJsImportClause::JsImportDefaultExtraClause(it) => std::fmt::Debug::fmt(it, f), AnyJsImportClause::JsImportNamedClause(it) => std::fmt::Debug::fmt(it, f), AnyJsImportClause::JsImportNamespaceClause(it) => std::fmt::Debug::fmt(it, f), } @@ -32760,8 +32753,8 @@ impl From for SyntaxNode { fn from(n: AnyJsImportClause) -> SyntaxNode { match n { AnyJsImportClause::JsImportBareClause(it) => it.into(), + AnyJsImportClause::JsImportCombinedClause(it) => it.into(), AnyJsImportClause::JsImportDefaultClause(it) => it.into(), - AnyJsImportClause::JsImportDefaultExtraClause(it) => it.into(), AnyJsImportClause::JsImportNamedClause(it) => it.into(), AnyJsImportClause::JsImportNamespaceClause(it) => it.into(), } @@ -37149,6 +37142,11 @@ impl std::fmt::Display for AnyJsClassMemberName { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for AnyJsCombinedSpecifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for AnyJsConstructorParameter { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -37189,11 +37187,6 @@ impl std::fmt::Display for AnyJsExpression { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for AnyJsExtraImportSpecifier { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} impl std::fmt::Display for AnyJsForInOrOfInitializer { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -37814,12 +37807,12 @@ impl std::fmt::Display for JsImportCallExpression { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for JsImportDefaultClause { +impl std::fmt::Display for JsImportCombinedClause { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for JsImportDefaultExtraClause { +impl std::fmt::Display for JsImportDefaultClause { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } diff --git a/crates/biome_js_syntax/src/generated/nodes_mut.rs b/crates/biome_js_syntax/src/generated/nodes_mut.rs index bd17a52366bd..fa18f5be9f32 100644 --- a/crates/biome_js_syntax/src/generated/nodes_mut.rs +++ b/crates/biome_js_syntax/src/generated/nodes_mut.rs @@ -1844,72 +1844,72 @@ impl JsImportCallExpression { ) } } -impl JsImportDefaultClause { - pub fn with_type_token(self, element: Option) -> Self { +impl JsImportCombinedClause { + pub fn with_default_specifier(self, element: JsDefaultImportSpecifier) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))), + .splice_slots(0usize..=0usize, once(Some(element.into_syntax().into()))), ) } - pub fn with_default_specifier(self, element: JsDefaultImportSpecifier) -> Self { + pub fn with_comma_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))), + .splice_slots(1usize..=1usize, once(Some(element.into()))), + ) + } + pub fn with_specifier(self, element: AnyJsCombinedSpecifier) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(2usize..=2usize, once(Some(element.into_syntax().into()))), ) } pub fn with_from_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(2usize..=2usize, once(Some(element.into()))), + .splice_slots(3usize..=3usize, once(Some(element.into()))), ) } pub fn with_source(self, element: JsModuleSource) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(3usize..=3usize, once(Some(element.into_syntax().into()))), + .splice_slots(4usize..=4usize, once(Some(element.into_syntax().into()))), ) } pub fn with_assertion(self, element: Option) -> Self { Self::unwrap_cast(self.syntax.splice_slots( - 4usize..=4usize, + 5usize..=5usize, once(element.map(|element| element.into_syntax().into())), )) } } -impl JsImportDefaultExtraClause { - pub fn with_default_specifier(self, element: JsDefaultImportSpecifier) -> Self { - Self::unwrap_cast( - self.syntax - .splice_slots(0usize..=0usize, once(Some(element.into_syntax().into()))), - ) - } - pub fn with_comma_token(self, element: SyntaxToken) -> Self { +impl JsImportDefaultClause { + pub fn with_type_token(self, element: Option) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(1usize..=1usize, once(Some(element.into()))), + .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))), ) } - pub fn with_extra_specifier(self, element: AnyJsExtraImportSpecifier) -> Self { + pub fn with_default_specifier(self, element: JsDefaultImportSpecifier) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(2usize..=2usize, once(Some(element.into_syntax().into()))), + .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))), ) } pub fn with_from_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(3usize..=3usize, once(Some(element.into()))), + .splice_slots(2usize..=2usize, once(Some(element.into()))), ) } pub fn with_source(self, element: JsModuleSource) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(4usize..=4usize, once(Some(element.into_syntax().into()))), + .splice_slots(3usize..=3usize, once(Some(element.into_syntax().into()))), ) } pub fn with_assertion(self, element: Option) -> Self { Self::unwrap_cast(self.syntax.splice_slots( - 5usize..=5usize, + 4usize..=4usize, once(element.map(|element| element.into_syntax().into())), )) } diff --git a/crates/biome_js_syntax/src/import_ext.rs b/crates/biome_js_syntax/src/import_ext.rs index dd81e43868d8..57889413b7ec 100644 --- a/crates/biome_js_syntax/src/import_ext.rs +++ b/crates/biome_js_syntax/src/import_ext.rs @@ -39,7 +39,7 @@ impl AnyJsImportClause { Self::JsImportDefaultClause(clause) => clause.type_token(), Self::JsImportNamedClause(clause) => clause.type_token(), Self::JsImportNamespaceClause(clause) => clause.type_token(), - Self::JsImportDefaultExtraClause(_) => None, + Self::JsImportCombinedClause(_) => None, } } @@ -62,7 +62,7 @@ impl AnyJsImportClause { Self::JsImportDefaultClause(clause) => clause.source(), Self::JsImportNamedClause(clause) => clause.source(), Self::JsImportNamespaceClause(clause) => clause.source(), - Self::JsImportDefaultExtraClause(clause) => clause.source(), + Self::JsImportCombinedClause(clause) => clause.source(), } } } diff --git a/xtask/codegen/js.ungram b/xtask/codegen/js.ungram index 3a1a1f6b79b7..27421152661e 100644 --- a/xtask/codegen/js.ungram +++ b/xtask/codegen/js.ungram @@ -1228,7 +1228,7 @@ AnyJsImportClause = | JsImportNamedClause | JsImportDefaultClause | JsImportNamespaceClause - | JsImportDefaultExtraClause + | JsImportCombinedClause // import "abcd" // import "abcd" assert ... @@ -1273,15 +1273,15 @@ JsImportNamedClause = // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // import foo, * as bar from "mod"; // ^^^^^^^^^^^^^^^^^^^^^^^^ -JsImportDefaultExtraClause = +JsImportCombinedClause = default_specifier: JsDefaultImportSpecifier ',' - extra_specifier: AnyJsExtraImportSpecifier + specifier: AnyJsCombinedSpecifier 'from' source: JsModuleSource assertion: JsImportAssertion? -AnyJsExtraImportSpecifier = JsNamedImportSpecifiers | JsNamespaceImportSpecifier +AnyJsCombinedSpecifier = JsNamedImportSpecifiers | JsNamespaceImportSpecifier // import a, { b, c } from "d"; // ^^ diff --git a/xtask/codegen/src/kinds_src.rs b/xtask/codegen/src/kinds_src.rs index 5a2fe4a53bab..f72a13eda614 100644 --- a/xtask/codegen/src/kinds_src.rs +++ b/xtask/codegen/src/kinds_src.rs @@ -359,7 +359,7 @@ pub const JS_KINDS_SRC: KindsSrc = KindsSrc { "JS_IMPORT_DEFAULT_CLAUSE", "JS_IMPORT_NAMESPACE_CLAUSE", "JS_IMPORT_NAMED_CLAUSE", - "JS_IMPORT_DEFAULT_EXTRA_CLAUSE", + "JS_IMPORT_COMBINED_CLAUSE", "JS_NAMED_IMPORT_SPECIFIERS", "JS_NAMED_IMPORT_SPECIFIER_LIST", "JS_NAMESPACE_IMPORT_SPECIFIER",