Skip to content

Commit 01ee02b

Browse files
committed
fix: stable format for if expression with trailing comment
closes #592
1 parent b1b9e7c commit 01ee02b

File tree

7 files changed

+101
-19
lines changed

7 files changed

+101
-19
lines changed

packages/prettier-plugin-java/src/printers/blocks-and-statements.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { builders } from "prettier/doc";
44
import { concat, dedent, group, indent, join } from "./prettier-builder";
55
import { printTokenWithComments } from "./comments/format-comments";
6+
import { handleCommentsIfStatement } from "./comments/handle-comments";
67
import {
78
hasLeadingLineComments,
89
hasTrailingLineComments
@@ -192,12 +193,17 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
192193
}
193194

194195
ifStatement(ctx: IfStatementCtx) {
196+
handleCommentsIfStatement(ctx);
197+
195198
const expression = this.visit(ctx.expression);
196199

197200
const ifStatement = this.visit(ctx.statement[0], {
198201
allowEmptyStatement: true
199202
});
200-
const ifSeparator = isStatementEmptyStatement(ifStatement) ? "" : " ";
203+
const ifStatementCtx = ctx.statement[0].children.statementWithoutTrailingSubstatement?.[0].children;
204+
const emptyIfStatement = ifStatementCtx?.emptyStatement !== undefined;
205+
const hasIfBlock = ifStatementCtx?.block !== undefined;
206+
const ifSeparator = emptyIfStatement ? "" : hasIfBlock ? " " : indent(line);
201207

202208
let elsePart: Doc = "";
203209
if (ctx.Else !== undefined) {
@@ -208,7 +214,9 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
208214

209215
const elseOnSameLine =
210216
hasTrailingLineComments(ctx.statement[0]) ||
211-
hasLeadingLineComments(ctx.Else[0])
217+
hasLeadingLineComments(ctx.Else[0]) ||
218+
emptyIfStatement ||
219+
!hasIfBlock
212220
? hardline
213221
: " ";
214222

@@ -226,7 +234,7 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
226234
ifSeparator
227235
])
228236
]),
229-
ifStatement,
237+
hasIfBlock ? ifStatement : indent(ifStatement),
230238
elsePart
231239
]);
232240
}

packages/prettier-plugin-java/src/printers/comments/handle-comments.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { hasLeadingComments } from "./comments-utils";
2-
import { BinaryExpressionCtx, IToken } from "java-parser";
1+
import { hasLeadingComments, hasTrailingComments } from "./comments-utils";
2+
import { BinaryExpressionCtx, IToken, IfStatementCtx } from "java-parser";
33

44
export function handleCommentsBinaryExpression(ctx: BinaryExpressionCtx) {
55
let unaryExpressionIndex = 1;
@@ -43,3 +43,29 @@ export function handleCommentsBinaryExpression(ctx: BinaryExpressionCtx) {
4343
});
4444
}
4545
}
46+
47+
export function handleCommentsIfStatement(ctx: IfStatementCtx) {
48+
const rBrace = ctx.RBrace[0];
49+
if (!hasTrailingComments(rBrace)) {
50+
return;
51+
}
52+
const statement = ctx.statement[0].children.statementWithoutTrailingSubstatement?.[0].children;
53+
if (!statement) {
54+
return;
55+
}
56+
const inner = [statement.assertStatement, statement.breakStatement, statement.continueStatement, statement.doStatement, statement.emptyStatement, statement.expressionStatement, statement.expressionStatement, statement.returnStatement, statement.switchStatement, statement.synchronizedStatement, statement.throwStatement, statement.tryStatement, statement.yieldStatement].find(s => s)?.[0];
57+
const block = statement.block?.[0].children.blockStatements?.[0];
58+
const rCurly = statement.block?.[0].children.RCurly[0];
59+
const target = inner ?? block ?? rCurly;
60+
if (!target) {
61+
return;
62+
}
63+
if (block) {
64+
block.location.startLine--;
65+
}
66+
if (!target.leadingComments) {
67+
target.leadingComments = [];
68+
}
69+
target.leadingComments.unshift(...rBrace.trailingComments);
70+
delete ctx.RBrace[0].trailingComments;
71+
}

packages/prettier-plugin-java/test/unit-test/comments/comments-blocks-and-statements/complex/_output.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ private void myFunction(
2323
/* axis y */int arg2,
2424
/* axis z */int arg3
2525
) {
26-
if (arg1 == 0 && arg2 == 0 && arg == 3) throw new RuntimeException(
27-
"X Y Z cannot be all 0"
28-
);
26+
if (arg1 == 0 && arg2 == 0 && arg == 3)
27+
throw new RuntimeException("X Y Z cannot be all 0");
2928

3029
int /*variable name is of value var */var = arg1 + arg2 + arg3;
3130
if /*true*/(var == 0) {

packages/prettier-plugin-java/test/unit-test/comments/comments-blocks-and-statements/if-statement/_input.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@ void commentsIfLineComment() {
1515
if ( // test
1616
t) {
1717
}
18+
19+
if (true) // comment
20+
System.out.println("Oops");
21+
22+
if (true) {
23+
// comment
24+
}
25+
26+
if (true) // comment
27+
{}
28+
29+
if (true) // comment
30+
{
31+
System.out.println("Oops");
32+
}
33+
34+
if (true) // comment
35+
{
36+
if (true) {}
37+
}
1838
}
1939

2040
void commentsIfBlockComment() {

packages/prettier-plugin-java/test/unit-test/comments/comments-blocks-and-statements/if-statement/_output.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@ void commentsIfLineComment() {
1414
if ( // test
1515
t
1616
) {}
17+
18+
if (true)
19+
// comment
20+
System.out.println("Oops");
21+
22+
if (true) {
23+
// comment
24+
}
25+
26+
if (true) {
27+
// comment
28+
}
29+
30+
if (true) {
31+
// comment
32+
System.out.println("Oops");
33+
}
34+
35+
if (true) {
36+
// comment
37+
if (true) {}
38+
}
1739
}
1840

1941
void commentsIfBlockComment() {

packages/prettier-plugin-java/test/unit-test/empty_statement/_output.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,27 @@ public void forEachWithEmptyStatement(List<String> list) {
3737
}
3838

3939
public void ifElseWithEmptyStatements() {
40-
if (test); else {
40+
if (test);
41+
else {
4142
System.out.println("one");
4243
}
4344

4445
if (test) {
4546
System.out.println("two");
4647
} else;
4748

48-
if (test); else;
49+
if (test);
50+
else;
4951
}
5052

5153
public void ifElseWithEmptyStatementsWithComments() {
52-
if (test) /*test*/; else {
54+
if (test)/*test*/;
55+
else {
5356
System.out.println("one");
5457
}
5558

56-
if (test); /*test*/else {
59+
if (test);
60+
/*test*/else {
5761
System.out.println("one");
5862
}
5963

@@ -65,9 +69,11 @@ public void ifElseWithEmptyStatementsWithComments() {
6569
System.out.println("two");
6670
} else;/*test*/
6771

68-
if (test); /*test*/else;/*test*/
72+
if (test);
73+
/*test*/else;/*test*/
6974

70-
if (test) /*test*/; else /*test*/;
75+
if (test)/*test*/;
76+
else /*test*/;
7177
}
7278

7379
public void simpleWhileWithEmptyStatement(boolean one) {

packages/prettier-plugin-java/test/unit-test/sealed/_output.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ default Shape rotate(double angle) {
4646
}
4747

4848
default String areaMessage() {
49-
if (this instanceof Circle) return "Circle: " + area(); else if (
50-
this instanceof Rectangle
51-
) return "Rectangle: " + area(); else if (
52-
this instanceof RightTriangle
53-
) return "Triangle: " + area();
49+
if (this instanceof Circle)
50+
return "Circle: " + area();
51+
else if (this instanceof Rectangle)
52+
return "Rectangle: " + area();
53+
else if (this instanceof RightTriangle)
54+
return "Triangle: " + area();
5455
// :(
5556
throw new IllegalArgumentException();
5657
}

0 commit comments

Comments
 (0)