Skip to content

Commit b742832

Browse files
Fix/712 handle comments with static invocations (#713)
* refactor: use real boolean for predicates * fix: handle comments with static invocations * refactor: remove unecessary boolean calculation * refactor: extract getPrimarySuffixes method * refactor: move cast to boolean inside isCapitalizedIdentifier method * refactor: remove firstMethodInvocation presence check as countMethodInvocation > 1 * refactor: remove unecessary if as countMethodInvocation === 1 * refactor: extract handleStaticInvocations method * refactor: cast to boolean instead of undefined
1 parent b0027f0 commit b742832

File tree

5 files changed

+172
-53
lines changed

5 files changed

+172
-53
lines changed

packages/prettier-plugin-java/src/printers/expressions.ts

Lines changed: 87 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import {
22
ArgumentListCtx,
33
ArrayAccessSuffixCtx,
44
ArrayCreationExpressionCtx,
5-
ArrayCreationWithInitializerSuffixCtx,
65
ArrayCreationExpressionWithoutInitializerSuffixCtx,
6+
ArrayCreationWithInitializerSuffixCtx,
77
BinaryExpressionCtx,
88
CastExpressionCtx,
99
ClassLiteralSuffixCtx,
1010
ClassOrInterfaceTypeToInstantiateCtx,
11-
ComponentPatternListCtx,
1211
ComponentPatternCtx,
12+
ComponentPatternListCtx,
1313
ConciseLambdaParameterCtx,
1414
ConciseLambdaParameterListCtx,
1515
ConditionalExpressionCtx,
@@ -63,6 +63,7 @@ import { builders, utils } from "prettier/doc";
6363
import { BaseCstPrettierPrinter } from "../base-cst-printer.js";
6464
import { isAnnotationCstNode } from "../types/utils.js";
6565
import { printArgumentListWithBraces } from "../utils/index.js";
66+
import { hasLeadingComments } from "./comments/comments-utils.js";
6667
import { printTokenWithComments } from "./comments/format-comments.js";
6768
import {
6869
handleCommentsBinaryExpression,
@@ -359,72 +360,49 @@ export class ExpressionsPrettierVisitor extends BaseCstPrettierPrinter {
359360
const isBreakableNewExpression =
360361
countMethodInvocation <= 1 &&
361362
this.isBreakableNewExpression(newExpression);
362-
const fqnOrRefType =
363-
ctx.primaryPrefix[0].children.fqnOrRefType?.[0].children;
364363
const firstMethodInvocation = ctx.primarySuffix
365364
?.map(suffix => suffix.children.methodInvocationSuffix?.[0].children)
366365
.find(methodInvocationSuffix => methodInvocationSuffix);
367-
const isCapitalizedIdentifier = this.isCapitalizedIdentifier(fqnOrRefType);
366+
367+
const fqnOrRefType =
368+
ctx.primaryPrefix[0].children.fqnOrRefType?.[0].children;
369+
const hasFqnRefPart = fqnOrRefType?.fqnOrRefTypePartRest !== undefined;
370+
const {
371+
isCapitalizedIdentifier,
372+
isCapitalizedIdentifierWithoutTrailingComment
373+
} = this.handleStaticInvocations(fqnOrRefType);
374+
368375
const shouldBreakBeforeFirstMethodInvocation =
369376
countMethodInvocation > 1 &&
370-
!(isCapitalizedIdentifier ?? true) &&
371-
firstMethodInvocation !== undefined;
377+
hasFqnRefPart &&
378+
!isCapitalizedIdentifierWithoutTrailingComment;
379+
372380
const shouldBreakBeforeMethodInvocations =
373381
shouldBreakBeforeFirstMethodInvocation ||
374382
countMethodInvocation > 2 ||
375-
(countMethodInvocation > 1 && newExpression) ||
383+
(countMethodInvocation > 1 && !!newExpression) ||
376384
!firstMethodInvocation?.argumentList;
377385

378386
const primaryPrefix = this.visit(ctx.primaryPrefix, {
379387
...params,
380388
shouldBreakBeforeFirstMethodInvocation
381389
});
382390

383-
const suffixes = [];
384-
385-
if (ctx.primarySuffix !== undefined) {
386-
// edge case: https://github.com/jhipster/prettier-java/issues/381
387-
let hasFirstInvocationArg = true;
388-
389-
if (
390-
ctx.primarySuffix.length > 1 &&
391-
ctx.primarySuffix[1].children.methodInvocationSuffix &&
392-
Object.keys(
393-
ctx.primarySuffix[1].children.methodInvocationSuffix[0].children
394-
).length === 2
395-
) {
396-
hasFirstInvocationArg = false;
397-
}
398-
399-
if (
400-
newExpression &&
401-
!isBreakableNewExpression &&
402-
ctx.primarySuffix[0].children.Dot !== undefined
403-
) {
404-
suffixes.push(softline);
405-
}
406-
suffixes.push(this.visit(ctx.primarySuffix[0]));
407-
408-
for (let i = 1; i < ctx.primarySuffix.length; i++) {
409-
if (
410-
shouldBreakBeforeMethodInvocations &&
411-
ctx.primarySuffix[i].children.Dot !== undefined &&
412-
ctx.primarySuffix[i - 1].children.methodInvocationSuffix !== undefined
413-
) {
414-
suffixes.push(softline);
415-
}
416-
suffixes.push(this.visit(ctx.primarySuffix[i]));
417-
}
391+
const suffixes = this.getPrimarySuffixes(
392+
ctx,
393+
newExpression,
394+
isBreakableNewExpression,
395+
shouldBreakBeforeMethodInvocations
396+
);
418397

419-
if (!newExpression && countMethodInvocation === 1) {
420-
return group(
421-
rejectAndConcat([
422-
primaryPrefix,
423-
hasFirstInvocationArg ? suffixes[0] : indent(suffixes[0]),
424-
indent(rejectAndConcat(suffixes.slice(1)))
425-
])
426-
);
427-
}
398+
if (!newExpression && countMethodInvocation === 1) {
399+
return group(
400+
rejectAndConcat([
401+
primaryPrefix,
402+
suffixes[0],
403+
indent(rejectAndConcat(suffixes.slice(1)))
404+
])
405+
);
428406
}
429407

430408
const methodInvocation =
@@ -447,6 +425,20 @@ export class ExpressionsPrettierVisitor extends BaseCstPrettierPrinter {
447425
);
448426
}
449427

428+
private handleStaticInvocations(fqnOrRefType: FqnOrRefTypeCtx | undefined) {
429+
const lastFqnRefPartDot = this.lastFqnOrRefDot(fqnOrRefType);
430+
const isCapitalizedIdentifier = this.isCapitalizedIdentifier(fqnOrRefType);
431+
const isCapitalizedIdentifierWithoutTrailingComment =
432+
isCapitalizedIdentifier &&
433+
(lastFqnRefPartDot === undefined ||
434+
!hasLeadingComments(lastFqnRefPartDot));
435+
436+
return {
437+
isCapitalizedIdentifier,
438+
isCapitalizedIdentifierWithoutTrailingComment
439+
};
440+
}
441+
450442
primaryPrefix(ctx: PrimaryPrefixCtx, params: any) {
451443
if (ctx.This || ctx.Void) {
452444
return printTokenWithComments(this.getSingle(ctx) as IToken);
@@ -910,8 +902,50 @@ export class ExpressionsPrettierVisitor extends BaseCstPrettierPrinter {
910902
fqnOrRefTypeParts[fqnOrRefTypeParts.length - 2]?.children
911903
.fqnOrRefTypePartCommon[0].children.Identifier?.[0].image;
912904
return (
913-
nextToLastIdentifier &&
905+
!!nextToLastIdentifier &&
914906
/^\p{Uppercase_Letter}/u.test(nextToLastIdentifier)
915907
);
916908
}
909+
910+
private lastFqnOrRefDot(fqnOrRefType: FqnOrRefTypeCtx | undefined) {
911+
if (fqnOrRefType === undefined || fqnOrRefType.Dot === undefined) {
912+
return undefined;
913+
}
914+
915+
return fqnOrRefType.Dot[fqnOrRefType.Dot.length - 1];
916+
}
917+
918+
private getPrimarySuffixes(
919+
ctx: PrimaryCtx,
920+
newExpression: NewExpressionCtx | undefined,
921+
isBreakableNewExpression: boolean,
922+
shouldBreakBeforeMethodInvocations: NewExpressionCtx | boolean
923+
) {
924+
if (ctx.primarySuffix === undefined) {
925+
return [];
926+
}
927+
928+
const suffixes = [];
929+
930+
if (
931+
newExpression &&
932+
!isBreakableNewExpression &&
933+
ctx.primarySuffix[0].children.Dot !== undefined
934+
) {
935+
suffixes.push(softline);
936+
}
937+
suffixes.push(this.visit(ctx.primarySuffix[0]));
938+
939+
for (let i = 1; i < ctx.primarySuffix.length; i++) {
940+
if (
941+
shouldBreakBeforeMethodInvocations &&
942+
ctx.primarySuffix[i].children.Dot !== undefined &&
943+
ctx.primarySuffix[i - 1].children.methodInvocationSuffix !== undefined
944+
) {
945+
suffixes.push(softline);
946+
}
947+
suffixes.push(this.visit(ctx.primarySuffix[i]));
948+
}
949+
return suffixes;
950+
}
917951
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public boolean binaryOperationWithComments() {
5757
public void method() {
5858
new Foo(stuff, thing, "auaaaaaaaaa some very long stuff", "some more").bar(10);
5959
foo(stuff, thing, "some very longuuuuuuuuuuuuuu stuff", "some more").bar(10);
60+
61+
// Issue 381
62+
new MethodWrappingFollowingContstructor().aLongEnoughMethodNameToForceThingsToWrap();
6063
}
6164

6265
public void binaryExpressionWithCast() {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ public void method() {
8383
foo(stuff, thing, "some very longuuuuuuuuuuuuuu stuff", "some more").bar(
8484
10
8585
);
86+
87+
// Issue 381
88+
new MethodWrappingFollowingContstructor()
89+
.aLongEnoughMethodNameToForceThingsToWrap();
8690
}
8791

8892
public void binaryExpressionWithCast() {

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,42 @@ public void doSomething() {
44
return new Object().something().more();
55
}
66

7+
public void doSomethingNewWithComment() {
8+
return new Object()
9+
// comment
10+
.something().more();
11+
}
12+
13+
public void doSomethingWithComment() {
14+
return Object
15+
// comment
16+
.something().more();
17+
}
18+
19+
public void doSomethingWithComment() {
20+
return object
21+
// comment
22+
.something().more();
23+
}
24+
25+
public void doSomethingNewWithComment() {
26+
return new Object()
27+
/* comment */
28+
.something().more();
29+
}
30+
31+
public void doSomethingWithComment() {
32+
return Object
33+
/* comment */
34+
.something().more();
35+
}
36+
37+
public void doSomethingWithComment() {
38+
return object
39+
/* comment */
40+
.something().more();
41+
}
42+
743
public void doSomethingLongNew() {
844
return something().more().and().that().as().well().but().not().something().something();
945
}

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,48 @@ public void doSomething() {
44
return new Object().something().more();
55
}
66

7+
public void doSomethingNewWithComment() {
8+
return new Object()
9+
// comment
10+
.something()
11+
.more();
12+
}
13+
14+
public void doSomethingWithComment() {
15+
return Object
16+
// comment
17+
.something()
18+
.more();
19+
}
20+
21+
public void doSomethingWithComment() {
22+
return object
23+
// comment
24+
.something()
25+
.more();
26+
}
27+
28+
public void doSomethingNewWithComment() {
29+
return new Object()
30+
/* comment */
31+
.something()
32+
.more();
33+
}
34+
35+
public void doSomethingWithComment() {
36+
return Object
37+
/* comment */
38+
.something()
39+
.more();
40+
}
41+
42+
public void doSomethingWithComment() {
43+
return object
44+
/* comment */
45+
.something()
46+
.more();
47+
}
48+
749
public void doSomethingLongNew() {
850
return something()
951
.more()

0 commit comments

Comments
 (0)