From b7926d34eb522cd8d4695f2965e957d7bf84065d Mon Sep 17 00:00:00 2001 From: Jordan Kiesel Date: Mon, 15 Dec 2025 00:27:13 -0700 Subject: [PATCH] fix: break empty switch/rule, try/catch/finally, and if blocks --- packages/prettier-plugin-java/src/comments.ts | 34 +++++++- .../src/printers/helpers.ts | 56 ++++++++++--- .../operator-position-end/_output.java | 12 ++- .../operator-position-start/_output.java | 12 ++- .../if-statement/_output.java | 42 +++++++--- .../test/unit-test/expressions/_output.java | 24 ++++-- .../test/unit-test/switch/_input.java | 10 +++ .../test/unit-test/switch/_output.java | 19 ++++- .../test/unit-test/try_catch/_input.java | 43 ++++++++++ .../test/unit-test/try_catch/_output.java | 81 +++++++++++++++++++ .../_output.java | 15 +++- 11 files changed, 301 insertions(+), 47 deletions(-) diff --git a/packages/prettier-plugin-java/src/comments.ts b/packages/prettier-plugin-java/src/comments.ts index a8376ea0..80a4a48b 100644 --- a/packages/prettier-plugin-java/src/comments.ts +++ b/packages/prettier-plugin-java/src/comments.ts @@ -99,7 +99,8 @@ export function handleLineComment( handleIfStatementComments, handleJumpStatementComments, handleLabeledStatementComments, - handleNameComments + handleNameComments, + handleTryStatementComments ].some(fn => fn(commentNode, options)); } @@ -247,6 +248,37 @@ function handleNameComments(commentNode: JavaComment) { return false; } +function handleTryStatementComments(commentNode: JavaComment) { + const { enclosingNode, followingNode } = commentNode; + if ( + enclosingNode && + ["catches", "tryStatement"].includes(enclosingNode.name) && + followingNode && + isNonTerminal(followingNode) + ) { + const block = ( + followingNode.name === "catches" + ? followingNode.children.catchClause[0] + : followingNode.name === "catchClause" || + followingNode.name === "finally" + ? followingNode + : null + )?.children.block[0]; + if (!block) { + return false; + } + const blockStatement = + block.children.blockStatements?.[0].children.blockStatement[0]; + if (blockStatement) { + util.addLeadingComment(blockStatement, commentNode); + } else { + util.addDanglingComment(block, commentNode, undefined); + } + return true; + } + return false; +} + function isBinaryOperator(node?: JavaNode) { return ( node !== undefined && diff --git a/packages/prettier-plugin-java/src/printers/helpers.ts b/packages/prettier-plugin-java/src/printers/helpers.ts index f91f7ed5..7b338ebe 100644 --- a/packages/prettier-plugin-java/src/printers/helpers.ts +++ b/packages/prettier-plugin-java/src/printers/helpers.ts @@ -263,18 +263,52 @@ export function printArrayInitializer< } export function printBlock(path: AstPath, contents: Doc[]) { - if (!contents.length) { - const danglingComments = printDanglingComments(path); - return danglingComments.length - ? ["{", indent([hardline, ...danglingComments]), hardline, "}"] - : "{}"; + if (contents.length) { + return group([ + "{", + indent([hardline, ...join(hardline, contents)]), + hardline, + "}" + ]); } - return group([ - "{", - indent([hardline, ...join(hardline, contents)]), - hardline, - "}" - ]); + const danglingComments = printDanglingComments(path); + if (danglingComments.length) { + return ["{", indent([hardline, ...danglingComments]), hardline, "}"]; + } + const parent = path.grandparent; + const grandparent = path.getNode(4); + const greatGrandparent = path.getNode(6); + return (grandparent?.name === "catches" && + grandparent.children.catchClause.length === 1 && + (greatGrandparent?.name === "tryStatement" || + greatGrandparent?.name === "tryWithResourcesStatement") && + !greatGrandparent.children.finally) || + (greatGrandparent && + [ + "basicForStatement", + "doStatement", + "enhancedForStatement", + "whileStatement" + ].includes(greatGrandparent.name)) || + [ + "annotationInterfaceBody", + "classBody", + "constructorBody", + "enumBody", + "interfaceBody", + "moduleDeclaration", + "recordBody" + ].includes(path.node.name) || + (parent && + [ + "instanceInitializer", + "lambdaBody", + "methodBody", + "staticInitializer", + "synchronizedStatement" + ].includes(parent.name)) + ? "{}" + : ["{", hardline, "}"]; } export function printName( diff --git a/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-end/_output.java b/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-end/_output.java index 698d345e..798e73da 100644 --- a/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-end/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-end/_output.java @@ -170,7 +170,8 @@ void parentheses() { var sizeIndex = ((index - 1) >>> level) & MASK; var from = offset > left ? 0 : (left - offset) >> level; var to = (right - offset) >> (level + 1); - if (rawIndex < 1 << (list._level + SHIFT)) {} + if (rawIndex < 1 << (list._level + SHIFT)) { + } var res = size < SIZE ? 0 : ((size - 1) >>> SHIFT) << SHIFT; sign = (1 - 2 * b[3]) >> 7; exponent = ((b[3] << 1) & 0xff) | (b[2] >> (7 - 127)); @@ -213,12 +214,14 @@ void parentheses() { (aaaaaaaaaa + bbbbbbbbbb == cccccccccc + dddddddddd && eeeeeeeeee + ffffffffff == gggggggggg + hhhhhhhhhh) || iiiiiiiiii - ) {} + ) { + } if ( (((((a * b + c) << d < e == f) & g) ^ h) | i && j) || (k && l | (m ^ (n & (o != p > q >> (r - s / t))))) - ) {} + ) { + } if ( (aaaaaaaaaa + bbbbbbbbbb == cccccccccc + dddddddddd && @@ -227,7 +230,8 @@ void parentheses() { mmmmmmmmmm + nnnnnnnnnn == oooooooooo + pppppppppp) || (qqqqqqqqqq + rrrrrrrrrr == ssssssssss + tttttttttt && uuuuuuuuuu + vvvvvvvvvv == wwwwwwwwww + xxxxxxxxxxx) - ) {} + ) { + } } void instanceOf() { diff --git a/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-start/_output.java b/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-start/_output.java index 7af43c22..f07cff4e 100644 --- a/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-start/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/binary_expressions/operator-position-start/_output.java @@ -163,7 +163,8 @@ void parentheses() { var sizeIndex = ((index - 1) >>> level) & MASK; var from = offset > left ? 0 : (left - offset) >> level; var to = (right - offset) >> (level + 1); - if (rawIndex < 1 << (list._level + SHIFT)) {} + if (rawIndex < 1 << (list._level + SHIFT)) { + } var res = size < SIZE ? 0 : ((size - 1) >>> SHIFT) << SHIFT; sign = (1 - 2 * b[3]) >> 7; exponent = ((b[3] << 1) & 0xff) | (b[2] >> (7 - 127)); @@ -206,12 +207,14 @@ void parentheses() { (aaaaaaaaaa + bbbbbbbbbb == cccccccccc + dddddddddd && eeeeeeeeee + ffffffffff == gggggggggg + hhhhhhhhhh) || iiiiiiiiii - ) {} + ) { + } if ( (((((a * b + c) << d < e == f) & g) ^ h) | i && j) || (k && l | (m ^ (n & (o != p > q >> (r - s / t))))) - ) {} + ) { + } if ( (aaaaaaaaaa + bbbbbbbbbb == cccccccccc + dddddddddd @@ -220,7 +223,8 @@ void parentheses() { && mmmmmmmmmm + nnnnnnnnnn == oooooooooo + pppppppppp) || (qqqqqqqqqq + rrrrrrrrrr == ssssssssss + tttttttttt && uuuuuuuuuu + vvvvvvvvvv == wwwwwwwwww + xxxxxxxxxxx) - ) {} + ) { + } } void instanceOf() { diff --git a/packages/prettier-plugin-java/test/unit-test/comments/comments-blocks-and-statements/if-statement/_output.java b/packages/prettier-plugin-java/test/unit-test/comments/comments-blocks-and-statements/if-statement/_output.java index d70daf12..837723ab 100644 --- a/packages/prettier-plugin-java/test/unit-test/comments/comments-blocks-and-statements/if-statement/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/comments/comments-blocks-and-statements/if-statement/_output.java @@ -4,18 +4,22 @@ void commentsIfLineComment() { if ( // test t - ) {} + ) { + } if ( t // test - ) {} + ) { + } - if (t) {} // test + if (t) { + } // test if ( // test t - ) {} + ) { + } if ( true // comment @@ -25,26 +29,38 @@ void commentsIfLineComment() { } void commentsIfBlockComment() { - if (/* test */ t) {} + if (/* test */ t) { + } - if (t /* test */) {} + if (t /* test */) { + } - if (t) /* test */ {} + if (t) /* test */ { + } - if (/* test */ t) {} + if (/* test */ t) { + } } void commentsElseLineComment() { - if (t) {} + if (t) { + } // test - else {} + else { + } - if (t) {} else {} // test + if (t) { + } else { + } // test } void commentsElseBlockComment() { - if (t) {} /* test */ else {} + if (t) { + } /* test */ else { + } - if (t) {} else /* test */ {} + if (t) { + } else /* test */ { + } } } diff --git a/packages/prettier-plugin-java/test/unit-test/expressions/_output.java b/packages/prettier-plugin-java/test/unit-test/expressions/_output.java index a42b67cf..e4290d72 100644 --- a/packages/prettier-plugin-java/test/unit-test/expressions/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/expressions/_output.java @@ -73,7 +73,8 @@ public void instanceOf() { } public void printSimple() { - if (myValue == 42) {} + if (myValue == 42) { + } if (myValue != 42) { System.out.println("Why not 42 !"); @@ -92,15 +93,18 @@ public void printIf() { myValue == 42 || (myValue == 42 && myValue == 42 && myValue == 42) || (myValue == 42 && myValue == 42) - ) {} + ) { + } if ( (myValue != 42 && 42 / 42) || (myValue & 42 && myValue > 42) || (myValue < 42 && myValue == 42) - ) {} + ) { + } - if (myValue != 42 && myValue == 42) {} + if (myValue != 42 && myValue == 42) { + } } public void printSwitch() { @@ -108,17 +112,21 @@ public void printSwitch() { myValue == 42 || (myValue == 42 && myValue == 42 && myValue == 42) || (myValue == 42 && myValue == 42) - ) {} + ) { + } switch ( (myValue != 42 && 42 / 42) || (myValue & 42 && myValue > 42) || (myValue < 42 && myValue == 42) - ) {} + ) { + } - switch (myValue != 42) {} + switch (myValue != 42) { + } - switch (myValue != 42 && myValue == 42) {} + switch (myValue != 42 && myValue == 42) { + } } public void printWhile() { diff --git a/packages/prettier-plugin-java/test/unit-test/switch/_input.java b/packages/prettier-plugin-java/test/unit-test/switch/_input.java index a1e7aa30..13cb5e2d 100644 --- a/packages/prettier-plugin-java/test/unit-test/switch/_input.java +++ b/packages/prettier-plugin-java/test/unit-test/switch/_input.java @@ -185,4 +185,14 @@ void switchRulesWithComments() { throw new RuntimeException(); } } + + void emptyBlocks() { + switch (a) {} + switch (a) { + case 1: {} + } + switch (a) { + case 1 -> {} + } + } } diff --git a/packages/prettier-plugin-java/test/unit-test/switch/_output.java b/packages/prettier-plugin-java/test/unit-test/switch/_output.java index effc8d4c..89ea15a2 100644 --- a/packages/prettier-plugin-java/test/unit-test/switch/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/switch/_output.java @@ -55,8 +55,10 @@ public String shouldWrapEvenForSmallSwitchCases() { void switchCaseWithBlock1() { switch (a) { - case 0: {} - default: {} + case 0: { + } + default: { + } } } @@ -233,4 +235,17 @@ void switchRulesWithComments() { throw new RuntimeException(); } } + + void emptyBlocks() { + switch (a) { + } + switch (a) { + case 1: { + } + } + switch (a) { + case 1 -> { + } + } + } } diff --git a/packages/prettier-plugin-java/test/unit-test/try_catch/_input.java b/packages/prettier-plugin-java/test/unit-test/try_catch/_input.java index d0ad1abf..91577220 100644 --- a/packages/prettier-plugin-java/test/unit-test/try_catch/_input.java +++ b/packages/prettier-plugin-java/test/unit-test/try_catch/_input.java @@ -72,4 +72,47 @@ void multiResourceTryWithTrailingSemi() { System.out.println("Warning: Not breaking multi exceptions"); } } + + void emptyBlocks() { + try {} catch (Exception e) {} + try (var a = new A()) {} catch (Exception e) {} + try {} finally {} + try (var a = new A()) {} finally {} + try {} catch (Exception e) {} finally {} + try (var a = new A()) {} catch (Exception e) {} finally {} + try {} catch (Exception e) {} catch (Exception e) {} + try (var a = new A()) {} catch (Exception e) {} catch (Exception e) {} + try {} catch (Exception e) {} catch (Exception e) {} finally {} + try (var a = new A()) {} catch (Exception e) {} catch (Exception e) {} finally {} + } + + void lineComments() { + try {} // a + finally {} // b + + try {} // a + catch (Exception b) {} // b + catch (Exception c) {} // c + finally {} // d + + try { // a1 + a; + } // a2 + finally { // b1 + b; + } // b2 + + try { // a1 + a; + } // a2 + catch (Exception b) { // b1 + b; + } // b2 + catch (Exception c) { // c1 + c; + } // c2 + finally { // d1 + d; + } // d2 + } } diff --git a/packages/prettier-plugin-java/test/unit-test/try_catch/_output.java b/packages/prettier-plugin-java/test/unit-test/try_catch/_output.java index 6a192dd8..9bbff074 100644 --- a/packages/prettier-plugin-java/test/unit-test/try_catch/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/try_catch/_output.java @@ -79,4 +79,85 @@ void multiResourceTryWithTrailingSemi() { System.out.println("Warning: Not breaking multi exceptions"); } } + + void emptyBlocks() { + try { + } catch (Exception e) {} + try (var a = new A()) { + } catch (Exception e) {} + try { + } finally { + } + try (var a = new A()) { + } finally { + } + try { + } catch (Exception e) { + } finally { + } + try (var a = new A()) { + } catch (Exception e) { + } finally { + } + try { + } catch (Exception e) { + } catch (Exception e) { + } + try (var a = new A()) { + } catch (Exception e) { + } catch (Exception e) { + } + try { + } catch (Exception e) { + } catch (Exception e) { + } finally { + } + try (var a = new A()) { + } catch (Exception e) { + } catch (Exception e) { + } finally { + } + } + + void lineComments() { + try { + } finally { + // a + } // b + + try { + } catch (Exception b) { + // a + } catch (Exception c) { + // b + } finally { + // c + } // d + + try { + // a1 + a; + } finally { + // a2 + // b1 + b; + } // b2 + + try { + // a1 + a; + } catch (Exception b) { + // a2 + // b1 + b; + } catch (Exception c) { + // b2 + // c1 + c; + } finally { + // c2 + // d1 + d; + } // d2 + } } diff --git a/packages/prettier-plugin-java/test/unit-test/unnamed-variables-and-patterns/_output.java b/packages/prettier-plugin-java/test/unit-test/unnamed-variables-and-patterns/_output.java index 04fb2eac..7d1a28af 100644 --- a/packages/prettier-plugin-java/test/unit-test/unnamed-variables-and-patterns/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/unnamed-variables-and-patterns/_output.java @@ -37,7 +37,11 @@ void catchClause() { } void multipleCatchClauses() { - try {} catch (Exception _) {} catch (Throwable _) {} // Unnamed variable // Unnamed variable + try { + } catch (Exception _) { + } catch (Throwable _) { + // Unnamed variable + } // Unnamed variable } void tryWithResources() { @@ -82,9 +86,12 @@ void multipleSwitchPatternsWithGuard() { } void instanceofExpressions() { - if (r instanceof ColoredPoint(Point(int x, int y), _)) {} - if (r instanceof ColoredPoint(_, Color c)) {} - if (r instanceof ColoredPoint(Point(int x, _), _)) {} + if (r instanceof ColoredPoint(Point(int x, int y), _)) { + } + if (r instanceof ColoredPoint(_, Color c)) { + } + if (r instanceof ColoredPoint(Point(int x, _), _)) { + } } void switchLabelWithMatchAllPattern() {