diff --git a/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.grit b/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.grit index 66b8afc5caee..6582c97bd651 100644 --- a/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.grit +++ b/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.grit @@ -1,4 +1,4 @@ -`function $name ($args) {}` as $func where { - $func => `const $name = ($args) => {}`, +`function $name ($args) { $body }` as $func where { + $func => `const $name = ($args) => { $body }`, $args <: contains `apple` => `mango` } diff --git a/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.snap b/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.snap index f78dfc18d9ad..0ed5c4abee45 100644 --- a/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.snap +++ b/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.snap @@ -6,7 +6,7 @@ SnapshotResult { messages: [], matched_ranges: [ "1:1-2:2", - "4:1-5:2", + "4:1-6:2", ], rewritten_files: [], created_files: [], diff --git a/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.ts b/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.ts index 2c5bcbfa28bf..5cee9e8cd851 100644 --- a/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.ts +++ b/crates/biome_grit_patterns/tests/specs/ts/functionToArrow.ts @@ -2,7 +2,8 @@ function foo(apple) { } function bar(apple, pear) { + console.log("fruits"); } -function baz() { +function baz(pear) { } diff --git a/crates/biome_js_formatter/src/js/any/statement.rs b/crates/biome_js_formatter/src/js/any/statement.rs index 1f3e6eb222fa..3f6387aa1abf 100644 --- a/crates/biome_js_formatter/src/js/any/statement.rs +++ b/crates/biome_js_formatter/src/js/any/statement.rs @@ -23,6 +23,7 @@ impl FormatRule for FormatAnyJsStatement { AnyJsStatement::JsFunctionDeclaration(node) => node.format().fmt(f), AnyJsStatement::JsIfStatement(node) => node.format().fmt(f), AnyJsStatement::JsLabeledStatement(node) => node.format().fmt(f), + AnyJsStatement::JsMetavariable(node) => node.format().fmt(f), AnyJsStatement::JsReturnStatement(node) => node.format().fmt(f), AnyJsStatement::JsSwitchStatement(node) => node.format().fmt(f), AnyJsStatement::JsThrowStatement(node) => node.format().fmt(f), diff --git a/crates/biome_js_parser/src/syntax/function.rs b/crates/biome_js_parser/src/syntax/function.rs index 7b09dff95178..b55020b84c99 100644 --- a/crates/biome_js_parser/src/syntax/function.rs +++ b/crates/biome_js_parser/src/syntax/function.rs @@ -1371,7 +1371,7 @@ pub(super) fn parse_parameters_list( progress.assert_progressing(p); if parse_metavariable(p).is_present() { - break; + continue; } let parameter = parse_parameter( diff --git a/crates/biome_js_parser/src/syntax/stmt.rs b/crates/biome_js_parser/src/syntax/stmt.rs index cff86341a8a3..df9231590a96 100644 --- a/crates/biome_js_parser/src/syntax/stmt.rs +++ b/crates/biome_js_parser/src/syntax/stmt.rs @@ -5,7 +5,7 @@ use super::binding::*; use super::class::is_at_ts_abstract_class_declaration; use super::expr::parse_expression; -use super::metavariable::{is_at_metavariable, is_nth_at_metavariable}; +use super::metavariable::{is_at_metavariable, is_nth_at_metavariable, parse_metavariable}; use super::module::parse_export; use super::typescript::*; use crate::parser::RecoveryResult; @@ -909,6 +909,10 @@ pub(crate) fn parse_statements(p: &mut JsParser, stop_on_r_curly: bool, statemen break; } + if parse_metavariable(p).is_present() { + continue; + } + if parse_statement(p, StatementContext::StatementList) .or_recover_with_token_set( p, diff --git a/crates/biome_js_parser/test_data/inline/ok/metavar.rast b/crates/biome_js_parser/test_data/inline/ok/metavar.rast index 8ac314759a3e..57ed61f31eaa 100644 --- a/crates/biome_js_parser/test_data/inline/ok/metavar.rast +++ b/crates/biome_js_parser/test_data/inline/ok/metavar.rast @@ -75,10 +75,10 @@ JsModule { l_curly_token: L_CURLY@126..127 "{" [] [], directives: JsDirectiveList [], statements: JsStatementList [ - JsExpressionStatement { - expression: JsMetavariable { - value_token: GRIT_METAVARIABLE@127..143 "µstatement" [Newline("\n"), Whitespace(" ")] [], - }, + JsMetavariable { + value_token: GRIT_METAVARIABLE@127..143 "µstatement" [Newline("\n"), Whitespace(" ")] [], + }, + JsEmptyStatement { semicolon_token: SEMICOLON@143..144 ";" [] [], }, JsVariableStatement { @@ -269,11 +269,11 @@ JsModule { 0: L_CURLY@126..127 "{" [] [] 1: JS_DIRECTIVE_LIST@127..127 2: JS_STATEMENT_LIST@127..174 - 0: JS_EXPRESSION_STATEMENT@127..144 - 0: JS_METAVARIABLE@127..143 - 0: GRIT_METAVARIABLE@127..143 "µstatement" [Newline("\n"), Whitespace(" ")] [] - 1: SEMICOLON@143..144 ";" [] [] - 1: JS_VARIABLE_STATEMENT@144..174 + 0: JS_METAVARIABLE@127..143 + 0: GRIT_METAVARIABLE@127..143 "µstatement" [Newline("\n"), Whitespace(" ")] [] + 1: JS_EMPTY_STATEMENT@143..144 + 0: SEMICOLON@143..144 ";" [] [] + 2: JS_VARIABLE_STATEMENT@144..174 0: JS_VARIABLE_DECLARATION@144..173 0: (empty) 1: CONST_KW@144..155 "const" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] diff --git a/crates/biome_js_syntax/src/generated/nodes.rs b/crates/biome_js_syntax/src/generated/nodes.rs index d1331bc270fc..7486a3b58eb5 100644 --- a/crates/biome_js_syntax/src/generated/nodes.rs +++ b/crates/biome_js_syntax/src/generated/nodes.rs @@ -14950,6 +14950,7 @@ pub enum AnyJsStatement { JsFunctionDeclaration(JsFunctionDeclaration), JsIfStatement(JsIfStatement), JsLabeledStatement(JsLabeledStatement), + JsMetavariable(JsMetavariable), JsReturnStatement(JsReturnStatement), JsSwitchStatement(JsSwitchStatement), JsThrowStatement(JsThrowStatement), @@ -15059,6 +15060,12 @@ impl AnyJsStatement { _ => None, } } + pub fn as_js_metavariable(&self) -> Option<&JsMetavariable> { + match &self { + AnyJsStatement::JsMetavariable(item) => Some(item), + _ => None, + } + } pub fn as_js_return_statement(&self) -> Option<&JsReturnStatement> { match &self { AnyJsStatement::JsReturnStatement(item) => Some(item), @@ -34001,6 +34008,11 @@ impl From for AnyJsStatement { AnyJsStatement::JsLabeledStatement(node) } } +impl From for AnyJsStatement { + fn from(node: JsMetavariable) -> AnyJsStatement { + AnyJsStatement::JsMetavariable(node) + } +} impl From for AnyJsStatement { fn from(node: JsReturnStatement) -> AnyJsStatement { AnyJsStatement::JsReturnStatement(node) @@ -34103,6 +34115,7 @@ impl AstNode for AnyJsStatement { .union(JsFunctionDeclaration::KIND_SET) .union(JsIfStatement::KIND_SET) .union(JsLabeledStatement::KIND_SET) + .union(JsMetavariable::KIND_SET) .union(JsReturnStatement::KIND_SET) .union(JsSwitchStatement::KIND_SET) .union(JsThrowStatement::KIND_SET) @@ -34138,6 +34151,7 @@ impl AstNode for AnyJsStatement { | JS_FUNCTION_DECLARATION | JS_IF_STATEMENT | JS_LABELED_STATEMENT + | JS_METAVARIABLE | JS_RETURN_STATEMENT | JS_SWITCH_STATEMENT | JS_THROW_STATEMENT @@ -34188,6 +34202,7 @@ impl AstNode for AnyJsStatement { JS_LABELED_STATEMENT => { AnyJsStatement::JsLabeledStatement(JsLabeledStatement { syntax }) } + JS_METAVARIABLE => AnyJsStatement::JsMetavariable(JsMetavariable { syntax }), JS_RETURN_STATEMENT => AnyJsStatement::JsReturnStatement(JsReturnStatement { syntax }), JS_SWITCH_STATEMENT => AnyJsStatement::JsSwitchStatement(JsSwitchStatement { syntax }), JS_THROW_STATEMENT => AnyJsStatement::JsThrowStatement(JsThrowStatement { syntax }), @@ -34248,6 +34263,7 @@ impl AstNode for AnyJsStatement { AnyJsStatement::JsFunctionDeclaration(it) => &it.syntax, AnyJsStatement::JsIfStatement(it) => &it.syntax, AnyJsStatement::JsLabeledStatement(it) => &it.syntax, + AnyJsStatement::JsMetavariable(it) => &it.syntax, AnyJsStatement::JsReturnStatement(it) => &it.syntax, AnyJsStatement::JsSwitchStatement(it) => &it.syntax, AnyJsStatement::JsThrowStatement(it) => &it.syntax, @@ -34284,6 +34300,7 @@ impl AstNode for AnyJsStatement { AnyJsStatement::JsFunctionDeclaration(it) => it.syntax, AnyJsStatement::JsIfStatement(it) => it.syntax, AnyJsStatement::JsLabeledStatement(it) => it.syntax, + AnyJsStatement::JsMetavariable(it) => it.syntax, AnyJsStatement::JsReturnStatement(it) => it.syntax, AnyJsStatement::JsSwitchStatement(it) => it.syntax, AnyJsStatement::JsThrowStatement(it) => it.syntax, @@ -34322,6 +34339,7 @@ impl std::fmt::Debug for AnyJsStatement { AnyJsStatement::JsFunctionDeclaration(it) => std::fmt::Debug::fmt(it, f), AnyJsStatement::JsIfStatement(it) => std::fmt::Debug::fmt(it, f), AnyJsStatement::JsLabeledStatement(it) => std::fmt::Debug::fmt(it, f), + AnyJsStatement::JsMetavariable(it) => std::fmt::Debug::fmt(it, f), AnyJsStatement::JsReturnStatement(it) => std::fmt::Debug::fmt(it, f), AnyJsStatement::JsSwitchStatement(it) => std::fmt::Debug::fmt(it, f), AnyJsStatement::JsThrowStatement(it) => std::fmt::Debug::fmt(it, f), @@ -34360,6 +34378,7 @@ impl From for SyntaxNode { AnyJsStatement::JsFunctionDeclaration(it) => it.into(), AnyJsStatement::JsIfStatement(it) => it.into(), AnyJsStatement::JsLabeledStatement(it) => it.into(), + AnyJsStatement::JsMetavariable(it) => it.into(), AnyJsStatement::JsReturnStatement(it) => it.into(), AnyJsStatement::JsSwitchStatement(it) => it.into(), AnyJsStatement::JsThrowStatement(it) => it.into(), diff --git a/xtask/codegen/js.ungram b/xtask/codegen/js.ungram index 3abf31cadf5e..d91649f3b712 100644 --- a/xtask/codegen/js.ungram +++ b/xtask/codegen/js.ungram @@ -113,6 +113,7 @@ AnyJsStatement = | TsExternalModuleDeclaration | TsGlobalDeclaration | TsImportEqualsDeclaration + | JsMetavariable JsBlockStatement = '{'