Skip to content

Commit

Permalink
fix(js_formatter): don't hug blocks in case clauses with multiple sta…
Browse files Browse the repository at this point in the history
…tements (#1035)
  • Loading branch information
faultyserver authored Dec 4, 2023
1 parent 14a45a1 commit 3317660
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 7 deletions.
52 changes: 45 additions & 7 deletions crates/biome_js_formatter/src/js/auxiliary/case_clause.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,55 @@ impl FormatNodeRule<JsCaseClause> for FormatJsCaseClause {
]
)?;

let is_first_child_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
// depending on whether the input code includes certain newlines.
let is_single_block_statement = matches!(
consequent.iter().next(),
Some(AnyJsStatement::JsBlockStatement(_))
);
) && consequent
.iter()
.filter(|statement| !matches!(statement, AnyJsStatement::JsEmptyStatement(_)))
.count()
== 1;

// When the case block is empty, the case becomes a fallthrough, so it
// is collapsed directly on top of the next case (just a single
// hardline).
// When the block is a single statement _and_ it's a block statement,
// then the opening brace of the block can hug the same line as the
// case. But, if there's more than one statement, then the block
// _cannot_ hug. This distinction helps clarify that the case continues
// past the end of the block statement, despite the braces making it
// seem like it might end.
// Lastly, the default case is just to break and indent the body.
//
// switch (key) {
// case fallthrough: // trailing comment
// case normalBody:
// someWork();
// break;
//
// case blockBody: {
// const a = 1;
// break;
// }
//
// case separateBlockBody:
// {
// breakIsNotInsideTheBlock();
// }
// break;
//
// default:
// break;
// }
if consequent.is_empty() {
// Skip inserting an indent block is the consequent is empty to print
// the trailing comments for the case clause inline if there is no
// block to push them into
write!(f, [hard_line_break()])
} else if is_first_child_block_stmt {
// Print nothing to ensure that trailing comments on the same line
// are printed on the same line. The parent list formatter takes
// care of inserting a hard line break between cases.
Ok(())
} else 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ switch (key) {
case // comment
value:

case value: // fallthrough same-line
case value:
// fallthrough

case fallthrough:
case value:
break;

Expand All @@ -17,3 +19,17 @@ switch (key) {
switch ("test") {
case "test": {}
}

switch (key) {
case blockBody: {
const a = 1;
break;
}

// The block is not the only statement in the case body,
// so it doesn't hug the same line as the case here.
case separateBlockBody: {
const a = 1;
}
break;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ switch (key) {
case // comment
value:

case value: // fallthrough same-line
case value:
// fallthrough

case fallthrough:
case value:
break;

Expand All @@ -26,6 +28,19 @@ switch ("test") {
case "test": {}
}

switch (key) {
case blockBody: {
const a = 1;
break;
}

// The block is not the only statement in the case body,
// so it doesn't hug the same line as the case here.
case separateBlockBody: {
const a = 1;
}
break;
}
```


Expand Down Expand Up @@ -55,9 +70,11 @@ switch (key) {
case // comment
value:

case value: // fallthrough same-line
case value:
// fallthrough

case fallthrough:
case value:
break;

Expand All @@ -69,6 +86,21 @@ switch ("test") {
case "test": {
}
}

switch (key) {
case blockBody: {
const a = 1;
break;
}

// The block is not the only statement in the case body,
// so it doesn't hug the same line as the case here.
case separateBlockBody:
{
const a = 1;
}
break;
}
```


0 comments on commit 3317660

Please sign in to comment.