File tree Expand file tree Collapse file tree
crates/biome_js_formatter
tests/specs/js/module/statement Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ ---
2+ " @biomejs/biome " : patch
3+ ---
4+
5+ Fixed [ #2786 ] ( https://github.com/biomejs/biome/issues/2786 ) : The formatter no longer produces different output on subsequent runs when a ` case ` clause has a trailing line comment followed by a single block statement.
Original file line number Diff line number Diff line change @@ -70,12 +70,22 @@ impl FormatNodeRule<JsCaseClause> for FormatJsCaseClause {
7070 // default:
7171 // break;
7272 // }
73+ // If the case clause has a trailing line comment after the colon
74+ // (e.g. `case 1337: // ELITE`), we must not hug the block statement on
75+ // the same line. Doing so produces `case 1337: { // ELITE`, and on the
76+ // next format pass the comment is reparsed as a leading comment inside
77+ // the block, causing it to move to its own line — an idempotence bug.
78+ // The comment is stored as a trailing comment of the `test` node.
79+ let has_trailing_comment = test
80+ . as_ref ( )
81+ . is_ok_and ( |test| f. comments ( ) . has_trailing_comments ( test. syntax ( ) ) ) ;
82+
7383 if consequent. is_empty ( ) {
7484 // Print nothing to ensure that trailing comments on the same line
7585 // are printed on the same line. The parent list formatter takes
7686 // care of inserting a hard line break between cases.
7787 Ok ( ( ) )
78- } else if is_single_block_statement {
88+ } else if is_single_block_statement && !has_trailing_comment {
7989 write ! [ f, [ space( ) , consequent. format( ) ] ]
8090 } else {
8191 // no line break needed after because it is added by the indent in the switch statement
Original file line number Diff line number Diff line change @@ -16,3 +16,21 @@ switch(x) {
1616 a ( ) ; // ab
1717 break ;
1818}
19+
20+ // Trailing comment on a case clause followed by a single block statement.
21+ // The comment must stay on the `case` line and not migrate into the block
22+ // on subsequent format passes (idempotence, issue #2786).
23+ function cool ( x ) {
24+ switch ( x ) {
25+ case 4 : // guaranteed to be random
26+ case 42 : // classic
27+ case 1337 : // ELITE
28+ {
29+ console . log ( "x is cool" ) ;
30+ break ;
31+ }
32+ default : {
33+ console . error ( "x is not cool" ) ;
34+ }
35+ }
36+ }
Original file line number Diff line number Diff line change @@ -25,6 +25,24 @@ switch(x) {
2525 break ;
2626}
2727
28+ // Trailing comment on a case clause followed by a single block statement.
29+ // The comment must stay on the ` case ` line and not migrate into the block
30+ // on subsequent format passes (idempotence, issue #2786).
31+ function cool(x) {
32+ switch (x ) {
33+ case 4: // guaranteed to be random
34+ case 42: // classic
35+ case 1337: // ELITE
36+ {
37+ console.log("x is cool ");
38+ break;
39+ }
40+ default : {
41+ console.error("x is not cool ");
42+ }
43+ }
44+ }
45+
2846` ` `
2947
3048
@@ -75,4 +93,22 @@ switch (x) {
7593 break ;
7694}
7795
96+ // Trailing comment on a case clause followed by a single block statement.
97+ // The comment must stay on the ` case ` line and not migrate into the block
98+ // on subsequent format passes (idempotence, issue #2786).
99+ function cool(x) {
100+ switch (x ) {
101+ case 4: // guaranteed to be random
102+ case 42: // classic
103+ case 1337: // ELITE
104+ {
105+ console.log("x is cool ");
106+ break;
107+ }
108+ default : {
109+ console.error("x is not cool ");
110+ }
111+ }
112+ }
113+
78114` ` `
You can’t perform that action at this time.
0 commit comments