Skip to content

Commit 17d39a0

Browse files
committed
fix: break long nested statements
1 parent 79c4d9f commit 17d39a0

File tree

8 files changed

+130
-113
lines changed

8 files changed

+130
-113
lines changed

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

Lines changed: 71 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
import { builders } from "prettier/doc";
2-
import { concat, dedent, group, indent, join } from "./prettier-builder.js";
3-
import { printTokenWithComments } from "./comments/format-comments.js";
4-
import {
5-
hasLeadingLineComments,
6-
hasTrailingLineComments
7-
} from "./comments/comments-utils.js";
8-
import {
9-
displaySemicolon,
10-
getBlankLinesSeparator,
11-
isStatementEmptyStatement,
12-
putIntoBraces,
13-
rejectAndConcat,
14-
rejectAndJoin,
15-
rejectAndJoinSeps,
16-
rejectSeparators,
17-
sortModifiers
18-
} from "./printer-utils.js";
19-
import { BaseCstPrettierPrinter } from "../base-cst-printer.js";
201
import {
212
AssertStatementCtx,
223
BasicForStatementCtx,
@@ -49,6 +30,7 @@ import {
4930
ResourceListCtx,
5031
ResourceSpecificationCtx,
5132
ReturnStatementCtx,
33+
StatementCstNode,
5234
StatementCtx,
5335
StatementExpressionCtx,
5436
StatementExpressionListCtx,
@@ -67,6 +49,25 @@ import {
6749
YieldStatementCtx
6850
} from "java-parser";
6951
import { Doc } from "prettier";
52+
import { builders } from "prettier/doc";
53+
import { BaseCstPrettierPrinter } from "../base-cst-printer.js";
54+
import {
55+
hasLeadingLineComments,
56+
hasTrailingLineComments
57+
} from "./comments/comments-utils.js";
58+
import { printTokenWithComments } from "./comments/format-comments.js";
59+
import { concat, group, indent, join } from "./prettier-builder.js";
60+
import {
61+
displaySemicolon,
62+
getBlankLinesSeparator,
63+
isStatementEmptyStatement,
64+
putIntoBraces,
65+
rejectAndConcat,
66+
rejectAndJoin,
67+
rejectAndJoinSeps,
68+
rejectSeparators,
69+
sortModifiers
70+
} from "./printer-utils.js";
7071

7172
const { line, softline, hardline } = builders;
7273

@@ -189,18 +190,11 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
189190

190191
ifStatement(ctx: IfStatementCtx) {
191192
const expression = this.visit(ctx.expression);
192-
193-
const ifStatement = this.visit(ctx.statement[0], {
194-
allowEmptyStatement: true
195-
});
196-
const ifSeparator = isStatementEmptyStatement(ifStatement) ? "" : " ";
193+
const ifStatement = this.subStatement(ctx.statement[0]);
197194

198195
let elsePart: Doc = "";
199196
if (ctx.Else !== undefined) {
200-
const elseStatement = this.visit(ctx.statement[1], {
201-
allowEmptyStatement: true
202-
});
203-
const elseSeparator = isStatementEmptyStatement(elseStatement) ? "" : " ";
197+
const elseStatement = this.subStatement(ctx.statement[1], true);
204198

205199
const elseOnSameLine =
206200
hasTrailingLineComments(ctx.statement[0]) ||
@@ -210,20 +204,13 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
210204
? hardline
211205
: " ";
212206

213-
elsePart = rejectAndJoin(elseSeparator, [
214-
concat([elseOnSameLine, ctx.Else[0]]),
215-
elseStatement
216-
]);
207+
elsePart = concat([elseOnSameLine, ctx.Else[0], elseStatement]);
217208
}
218209

219-
return rejectAndConcat([
220-
rejectAndJoin(" ", [
221-
ctx.If[0],
222-
concat([
223-
putIntoBraces(expression, softline, ctx.LBrace[0], ctx.RBrace[0]),
224-
ifSeparator
225-
])
226-
]),
210+
return concat([
211+
ctx.If[0],
212+
" ",
213+
putIntoBraces(expression, softline, ctx.LBrace[0], ctx.RBrace[0]),
227214
ifStatement,
228215
elsePart
229216
]);
@@ -337,32 +324,24 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
337324

338325
whileStatement(ctx: WhileStatementCtx) {
339326
const expression = this.visit(ctx.expression);
340-
const statement = this.visit(ctx.statement[0], {
341-
allowEmptyStatement: true
342-
});
343-
const statementSeparator = isStatementEmptyStatement(statement) ? "" : " ";
327+
const statement = this.subStatement(ctx.statement[0]);
344328

345-
return rejectAndJoin(" ", [
329+
return concat([
346330
ctx.While[0],
347-
rejectAndJoin(statementSeparator, [
348-
putIntoBraces(expression, softline, ctx.LBrace[0], ctx.RBrace[0]),
349-
statement
350-
])
331+
" ",
332+
putIntoBraces(expression, softline, ctx.LBrace[0], ctx.RBrace[0]),
333+
statement
351334
]);
352335
}
353336

354337
doStatement(ctx: DoStatementCtx) {
355-
const statement = this.visit(ctx.statement[0], {
356-
allowEmptyStatement: true
357-
});
358-
const statementSeparator = isStatementEmptyStatement(statement) ? "" : " ";
359-
338+
const statement = this.subStatement(ctx.statement[0]);
360339
const expression = this.visit(ctx.expression);
361340

362-
return rejectAndJoin(" ", [
363-
rejectAndJoin(statementSeparator, [ctx.Do[0], statement]),
341+
return join(" ", [
342+
concat([ctx.Do[0], statement]),
364343
ctx.While[0],
365-
rejectAndConcat([
344+
concat([
366345
putIntoBraces(expression, softline, ctx.LBrace[0], ctx.RBrace[0]),
367346
ctx.Semicolon[0]
368347
])
@@ -377,26 +356,21 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
377356
const forInit = this.visit(ctx.forInit);
378357
const expression = this.visit(ctx.expression);
379358
const forUpdate = this.visit(ctx.forUpdate);
380-
const statement = this.visit(ctx.statement[0], {
381-
allowEmptyStatement: true
382-
});
383-
const statementSeparator = isStatementEmptyStatement(statement) ? "" : " ";
359+
const statement = this.subStatement(ctx.statement[0]);
384360

385-
return rejectAndConcat([
386-
rejectAndJoin(" ", [
387-
ctx.For[0],
388-
putIntoBraces(
389-
rejectAndConcat([
390-
forInit,
391-
rejectAndJoin(line, [ctx.Semicolon[0], expression]),
392-
rejectAndJoin(line, [ctx.Semicolon[1], forUpdate])
393-
]),
394-
softline,
395-
ctx.LBrace[0],
396-
ctx.RBrace[0]
397-
)
398-
]),
399-
statementSeparator,
361+
return concat([
362+
ctx.For[0],
363+
" ",
364+
putIntoBraces(
365+
[
366+
forInit,
367+
rejectAndJoin(line, [ctx.Semicolon[0], expression]),
368+
rejectAndJoin(line, [ctx.Semicolon[1], forUpdate])
369+
],
370+
softline,
371+
ctx.LBrace[0],
372+
ctx.RBrace[0]
373+
),
400374
statement
401375
]);
402376
}
@@ -422,17 +396,14 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
422396
enhancedForStatement(ctx: EnhancedForStatementCtx) {
423397
const localVariableDeclaration = this.visit(ctx.localVariableDeclaration);
424398
const expression = this.visit(ctx.expression);
425-
const statement = this.visit(ctx.statement[0], {
426-
allowEmptyStatement: true
427-
});
428-
const statementSeparator = isStatementEmptyStatement(statement) ? "" : " ";
399+
const statement = this.subStatement(ctx.statement[0]);
429400

430-
return rejectAndConcat([
431-
rejectAndJoin(" ", [ctx.For[0], ctx.LBrace[0]]),
432-
localVariableDeclaration,
433-
concat([" ", ctx.Colon[0], " "]),
434-
expression,
435-
concat([ctx.RBrace[0], statementSeparator]),
401+
return concat([
402+
ctx.For[0],
403+
" ",
404+
ctx.LBrace[0],
405+
join(" ", [localVariableDeclaration, ctx.Colon[0], expression]),
406+
ctx.RBrace[0],
436407
statement
437408
]);
438409
}
@@ -615,4 +586,18 @@ export class BlocksAndStatementPrettierVisitor extends BaseCstPrettierPrinter {
615586
variableAccess(ctx: VariableAccessCtx) {
616587
return this.visitSingle(ctx);
617588
}
589+
590+
private subStatement(subStatement: StatementCstNode, isElse = false) {
591+
const statement = this.visit(subStatement, { allowEmptyStatement: true });
592+
const isBlock =
593+
subStatement.children.statementWithoutTrailingSubstatement?.[0].children
594+
.block !== undefined;
595+
const isElseIf = isElse && subStatement.children.ifStatement !== undefined;
596+
if (isBlock || isElseIf) {
597+
return [" ", statement];
598+
} else if (isStatementEmptyStatement(statement)) {
599+
return statement;
600+
}
601+
return indent([line, statement]);
602+
}
618603
}

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

Lines changed: 12 additions & 11 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) {
@@ -66,15 +65,17 @@ private void myFunction(
6665
}
6766

6867
private synchronized void myFunction(int arg1, int arg2/*overloading*/) {
69-
for (int i = 0; i < /*=*/arg1; i++) do /*dodododo*/{ //do whiles
70-
//asserting
71-
assert /*true*/true == true;
72-
continue;
73-
break/*dead code*/;
74-
return/*dead code*/;
75-
} /*at least one iteration !*/while (false);
68+
for (int i = 0; i < /*=*/arg1; i++)
69+
do /*dodododo*/{ //do whiles
70+
//asserting
71+
assert /*true*/true == true;
72+
continue;
73+
break/*dead code*/;
74+
return/*dead code*/;
75+
} /*at least one iteration !*/while (false);
7676
synchronized /*declares synchronizd statement*/(this) {
77-
while /*infinite*/(true) /*stop the program*/throw new RuntimeException();
77+
while /*infinite*/(true)
78+
/*stop the program*/throw new RuntimeException();
7879
}
7980
}
8081
}

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

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,32 @@ public void emptyStatementWithComment() {
1111
public void simpleForWithEmptyStatement() {
1212
for (;;);
1313

14-
for (;;) /*test*/;
14+
for (;;)
15+
/*test*/;
1516

1617
for (;;);/*test*/
1718

18-
for (;;) /*test*/;/*test*/
19+
for (;;)
20+
/*test*/;/*test*/
1921
}
2022

2123
public void simpleForWithEmptyStatement() {
2224
for (;;);
2325

24-
for (;;) /*test*/;
26+
for (;;)
27+
/*test*/;
2528

2629
for (;;);/*test*/
2730

28-
for (;;) /*test*/;/*test*/
31+
for (;;)
32+
/*test*/;/*test*/
2933
}
3034

3135
public void forEachWithEmptyStatement(List<String> list) {
3236
for (String str : list);
3337

34-
for (String str : list) /*test*/;
38+
for (String str : list)
39+
/*test*/;
3540

3641
for (String str : list);/*test*/
3742
}
@@ -51,7 +56,8 @@ public void ifElseWithEmptyStatements() {
5156
}
5257

5358
public void ifElseWithEmptyStatementsWithComments() {
54-
if (test) /*test*/;
59+
if (test)
60+
/*test*/;
5561
else {
5662
System.out.println("one");
5763
}
@@ -63,7 +69,8 @@ public void ifElseWithEmptyStatementsWithComments() {
6369

6470
if (test) {
6571
System.out.println("two");
66-
} else /*test*/;
72+
} else
73+
/*test*/;
6774

6875
if (test) {
6976
System.out.println("two");
@@ -72,21 +79,25 @@ public void ifElseWithEmptyStatementsWithComments() {
7279
if (test);
7380
/*test*/else;/*test*/
7481

75-
if (test) /*test*/;
76-
else /*test*/;
82+
if (test)
83+
/*test*/;
84+
else
85+
/*test*/;
7786
}
7887

7988
public void simpleWhileWithEmptyStatement(boolean one) {
8089
while (one);
8190

82-
while (one) /*test*/;
91+
while (one)
92+
/*test*/;
8393

8494
while (one);/*test*/
8595
}
8696

8797
public void doWhileWithEmptyStatement(boolean one) {
8898
do; while (one);
89-
do /*test*/; while (one);
99+
do
100+
/*test*/; while (one);
90101
do; /*test*/while (one);
91102
}
92103
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ public void printSwitch() {
122122
}
123123

124124
public void printWhile() {
125-
while /*infinite*/(true) /*stop the program*/throw new RuntimeException();
125+
while /*infinite*/(true)
126+
/*stop the program*/throw new RuntimeException();
126127

127128
while (
128129
myValue == 42 ||

packages/prettier-plugin-java/test/unit-test/for/_input.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,8 @@ public void continueWithIdentifier() {
3636
}
3737
}
3838

39+
void shouldBreakNested() {
40+
for (int d = 0; d < e; d++) for (int c = 0; c < d; c++) for (int b = 0; b < c; b++) a();
41+
for (D dddddddddd : eeeeeeeeee) for (C cccccccccc : dddddddddd) for (B bbbbbbbbbb : cccccccccc) aaaaaaaaaa();
42+
}
3943
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,15 @@ public void continueWithIdentifier() {
3535
System.out.println(i);
3636
}
3737
}
38+
39+
void shouldBreakNested() {
40+
for (int d = 0; d < e; d++)
41+
for (int c = 0; c < d; c++)
42+
for (int b = 0; b < c; b++)
43+
a();
44+
for (D dddddddddd : eeeeeeeeee)
45+
for (C cccccccccc : dddddddddd)
46+
for (B bbbbbbbbbb : cccccccccc)
47+
aaaaaaaaaa();
48+
}
3849
}

0 commit comments

Comments
 (0)