From 32d574d8c7e4d964de75ff88038f104ff3ad044d Mon Sep 17 00:00:00 2001 From: Jon Egeland Date: Mon, 11 Dec 2023 20:52:02 +0000 Subject: [PATCH] fix(js_formatter): match default clause block handling with case clauses --- .../src/js/auxiliary/case_clause.rs | 4 +-- .../src/js/auxiliary/default_clause.rs | 15 ++++++-- .../tests/specs/js/module/statement/switch.js | 17 ++++++++++ .../specs/js/module/statement/switch.js.snap | 34 +++++++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/crates/biome_js_formatter/src/js/auxiliary/case_clause.rs b/crates/biome_js_formatter/src/js/auxiliary/case_clause.rs index 8e9996f74e79..b5d169f388fd 100644 --- a/crates/biome_js_formatter/src/js/auxiliary/case_clause.rs +++ b/crates/biome_js_formatter/src/js/auxiliary/case_clause.rs @@ -28,8 +28,8 @@ impl FormatNodeRule for FormatJsCaseClause { )?; // Whether the first statement in the clause is a BlockStatement, and - // there are no other non-empty statements. Empties may show up - // depending on whether the input code includes certain newlines. + // there are no other non-empty statements. Empties may show up when + // parsing depending on if the input code includes certain newlines. let is_single_block_statement = matches!( consequent.iter().next(), Some(AnyJsStatement::JsBlockStatement(_)) diff --git a/crates/biome_js_formatter/src/js/auxiliary/default_clause.rs b/crates/biome_js_formatter/src/js/auxiliary/default_clause.rs index 74718f5ee583..ede1b99eafbb 100644 --- a/crates/biome_js_formatter/src/js/auxiliary/default_clause.rs +++ b/crates/biome_js_formatter/src/js/auxiliary/default_clause.rs @@ -15,10 +15,19 @@ impl FormatNodeRule for FormatJsDefaultClause { consequent, } = node.as_fields(); - let first_child_is_block_stmt = matches!( + // Whether the first statement in the clause is a BlockStatement, and + // there are no other non-empty statements. Empties may show up when + // parsing depending on if the input code includes certain newlines. + // + // See the comments in `case_clause.rs` for a detailed example. + let is_single_block_statement = matches!( consequent.iter().next(), Some(AnyJsStatement::JsBlockStatement(_)) - ); + ) && consequent + .iter() + .filter(|statement| !matches!(statement, AnyJsStatement::JsEmptyStatement(_))) + .count() + == 1; write!(f, [default_token.format(), colon_token.format()])?; @@ -30,7 +39,7 @@ impl FormatNodeRule for FormatJsDefaultClause { return Ok(()); } - if first_child_is_block_stmt { + if is_single_block_statement { write!(f, [space(), consequent.format()]) } else { // no line break needed after because it is added by the indent in the switch statement diff --git a/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js b/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js index cc78b4c492ea..8a03d791dae2 100644 --- a/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js +++ b/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js @@ -32,4 +32,21 @@ switch (key) { const a = 1; } break; +} + + +switch (key) { + default: { + const a = 1; + break; + } +} + +switch (key) { + // The block is not the only statement in the case body, + // so it doesn't hug the same line as the case here. + default: { + const a = 1; + } + break; } \ No newline at end of file diff --git a/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js.snap b/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js.snap index 6341ed0c71e4..27465c0cd8e0 100644 --- a/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js.snap +++ b/crates/biome_js_formatter/tests/specs/js/module/statement/switch.js.snap @@ -41,6 +41,23 @@ switch (key) { } break; } + + +switch (key) { + default: { + const a = 1; + break; + } +} + +switch (key) { + // The block is not the only statement in the case body, + // so it doesn't hug the same line as the case here. + default: { + const a = 1; + } + break; +} ``` @@ -101,6 +118,23 @@ switch (key) { } break; } + +switch (key) { + default: { + const a = 1; + break; + } +} + +switch (key) { + // The block is not the only statement in the case body, + // so it doesn't hug the same line as the case here. + default: + { + const a = 1; + } + break; +} ```