diff --git a/packages/prettier-plugin-java/src/printers/expressions.ts b/packages/prettier-plugin-java/src/printers/expressions.ts index c30ad086..2892f341 100644 --- a/packages/prettier-plugin-java/src/printers/expressions.ts +++ b/packages/prettier-plugin-java/src/printers/expressions.ts @@ -17,6 +17,7 @@ import { DimExprCtx, DimExprsCtx, EmbeddedExpressionCtx, + ExpressionCstNode, ExpressionCtx, FqnOrRefTypeCtx, FqnOrRefTypePartCommonCtx, @@ -57,6 +58,7 @@ import { } from "java-parser/api"; import forEach from "lodash/forEach.js"; +import type { Doc } from "prettier"; import { builders, utils } from "prettier/doc"; import { BaseCstPrettierPrinter } from "../base-cst-printer.js"; import { isAnnotationCstNode } from "../types/utils.js"; @@ -66,10 +68,17 @@ import { handleCommentsBinaryExpression, handleCommentsParameters } from "./comments/handle-comments.js"; -import { concat, dedent, group, indent } from "./prettier-builder.js"; +import { + concat, + dedent, + group, + indent, + indentIfBreak +} from "./prettier-builder.js"; import { binary, findDeepElementInPartsArray, + getOperators, isExplicitLambdaParameter, isUniqueMethodInvocation, putIntoBraces, @@ -247,20 +256,50 @@ export class ExpressionsPrettierVisitor extends BaseCstPrettierPrinter { ctx.expression, ctx.unaryExpression ]); - - const nodes = this.mapVisit( - sortedNodes, - sortedNodes.length === 1 ? params : undefined - ); - const tokens = sortTokens([ - ctx.Instanceof, - ctx.AssignmentOperator, - ctx.Less, - ctx.Greater, - ctx.BinaryOperator - ]); + const tokens = sortTokens(getOperators(ctx)); const hasTokens = tokens.length > 0; + const nodeParams = sortedNodes.length === 1 ? params : undefined; + const nodes: Doc[] = []; + for (let i = 0; i < sortedNodes.length; i++) { + const node = this.visit(sortedNodes[i], nodeParams); + const isAssignment = + tokens[i]?.tokenType.CATEGORIES?.find( + ({ name }) => name === "AssignmentOperator" + ) !== undefined; + if (!isAssignment) { + nodes.push(node); + continue; + } + const [equals] = tokens.splice(i, 1); + const expression = sortedNodes[++i] as ExpressionCstNode; + const nextNode = this.visit(expression); + const conditionalExpression = + expression.children.conditionalExpression?.[0].children; + const binaryExpression = + conditionalExpression?.binaryExpression?.[0].children; + const breakAfterOperator = + conditionalExpression?.QuestionMark === undefined && + binaryExpression !== undefined && + getOperators(binaryExpression).length > 0; + if (breakAfterOperator) { + nodes.push( + concat([node, " ", equals, group(indent([line, nextNode]))]) + ); + continue; + } + const groupId = Symbol("assignment"); + nodes.push( + concat([ + node, + " ", + equals, + indent(group(line, { id: groupId })), + indentIfBreak(nextNode, { groupId }) + ]) + ); + } + const content = binary(nodes, tokens, true); return hasTokens && params?.addParenthesisToWrapStatement diff --git a/packages/prettier-plugin-java/src/printers/printer-utils.ts b/packages/prettier-plugin-java/src/printers/printer-utils.ts index e2cd213f..bf63941d 100644 --- a/packages/prettier-plugin-java/src/printers/printer-utils.ts +++ b/packages/prettier-plugin-java/src/printers/printer-utils.ts @@ -1,5 +1,6 @@ import { AnnotationCstNode, + BinaryExpressionCtx, ClassBodyDeclarationCstNode, ConstantModifierCstNode, CstElement, @@ -31,13 +32,7 @@ import { getTokenLeadingComments, printTokenWithComments } from "./comments/format-comments.js"; -import { - concat, - group, - ifBreak, - indentIfBreak, - join -} from "./prettier-builder.js"; +import { concat, group, ifBreak, join } from "./prettier-builder.js"; const { indent, hardline, line, lineSuffixBoundary, softline } = builders; @@ -664,16 +659,17 @@ export function binary(nodes: Doc[], tokens: IToken[], isRoot = false): Doc { } } level.push(nodes.shift()!); - const lineGroupId = Symbol("line"); - return group( - levelOperator === "=" - ? [ - level[0], - indent(group(line, { id: lineGroupId })), - indentIfBreak(level[1], { groupId: lineGroupId }) - ] - : join(line, level) - ); + return group(join(line, level)); +} + +export function getOperators(ctx: BinaryExpressionCtx) { + return [ + ctx.AssignmentOperator, + ctx.BinaryOperator, + ctx.Greater, + ctx.Instanceof, + ctx.Less + ].filter(token => token !== undefined); } function getOperator(tokens: IToken[]) { diff --git a/packages/prettier-plugin-java/test/unit-test/binary_expressions/_input.java b/packages/prettier-plugin-java/test/unit-test/binary_expressions/_input.java index 05535dd1..94fc575a 100644 --- a/packages/prettier-plugin-java/test/unit-test/binary_expressions/_input.java +++ b/packages/prettier-plugin-java/test/unit-test/binary_expressions/_input.java @@ -60,7 +60,30 @@ public void method() { } public void binaryExpressionWithCast() { - double availability = (double) successfulCount / (successfulCount + failureCount); + double availability12 = (double) successfulCount / (successfulCount + failureCount); + availability12 = (double) successfulCount / (successfulCount + failureCount); + } + + void declarationVsAssignment() { + var lineLengthInAssignmentMoreThanPrintWidth = "1234567890" + "1234567890" + "1234567890" + "1234567890" + "1234567890" + "1234567890"; + lineLengthInAssignmentMoreThanPrintWidth = "1234567890" + "1234567890" + "1234567890" + "1234567890" + "1234567890" + "1234567890"; + + aaaaaaaaaa += bbbbbbbbbbb + ccccccccccc + ddddddddddd + eeeeeeeeee + ffffffffff + gggggggggg; + aaaaaaaaaa %= bbbbbbbbbbb + ccccccccccc + ddddddddddd + eeeeeeeeee + ffffffffff + gggggggggg; + aaaaaaaaaa <<= bbbbbbbbbbb + ccccccccccc + ddddddddddd + eeeeeeeeee + ffffffffff + gggggggggg; + aaaaaaaaaa &= bbbbbbbbbbb + ccccccccccc + ddddddddddd + eeeeeeeeee + ffffffffff + gggggggggg; + + var aaaaaaaaaa = bbbbbbbbbb || cccccccccc ? dddddddddd + eeeeeeeeee : ffffffffff + gggggggggg; + aaaaaaaaaa = bbbbbbbbbb || cccccccccc ? dddddddddd + eeeeeeeeee : ffffffffff + gggggggggg; + + var something = MyClass.staticFunction(aaaaaaaaaa, bbbbbbbbbbb, ccccccccccc, ddddddddddd); + something = MyClass.staticFunction(aaaaaaaaaa, bbbbbbbbbbb, ccccccccccc, ddddddddddd); + + var something = MyClass.staticFunction(aaaaaaaaaa, bbbbbbbbbbb, ccccccccccc, ddddddddddd) + 0; + something = MyClass.staticFunction(aaaaaaaaaa, bbbbbbbbbbb, ccccccccccc, ddddddddddd) + 0; + + var something12 = new MyClass(aaaaaaaaaa, bbbbbbbbbbb, ccccccccccc, ddddddddddd); + something12 = new MyClass(aaaaaaaaaa, bbbbbbbbbbb, ccccccccccc, ddddddddddd); } void parentheses() { diff --git a/packages/prettier-plugin-java/test/unit-test/binary_expressions/_output.java b/packages/prettier-plugin-java/test/unit-test/binary_expressions/_output.java index 52b3d265..40dd4775 100644 --- a/packages/prettier-plugin-java/test/unit-test/binary_expressions/_output.java +++ b/packages/prettier-plugin-java/test/unit-test/binary_expressions/_output.java @@ -86,8 +86,106 @@ public void method() { } public void binaryExpressionWithCast() { - double availability = + double availability12 = (double) successfulCount / (successfulCount + failureCount); + availability12 = + (double) successfulCount / (successfulCount + failureCount); + } + + void declarationVsAssignment() { + var lineLengthInAssignmentMoreThanPrintWidth = + "1234567890" + + "1234567890" + + "1234567890" + + "1234567890" + + "1234567890" + + "1234567890"; + lineLengthInAssignmentMoreThanPrintWidth = + "1234567890" + + "1234567890" + + "1234567890" + + "1234567890" + + "1234567890" + + "1234567890"; + + aaaaaaaaaa += + bbbbbbbbbbb + + ccccccccccc + + ddddddddddd + + eeeeeeeeee + + ffffffffff + + gggggggggg; + aaaaaaaaaa %= + bbbbbbbbbbb + + ccccccccccc + + ddddddddddd + + eeeeeeeeee + + ffffffffff + + gggggggggg; + aaaaaaaaaa <<= + bbbbbbbbbbb + + ccccccccccc + + ddddddddddd + + eeeeeeeeee + + ffffffffff + + gggggggggg; + aaaaaaaaaa &= + bbbbbbbbbbb + + ccccccccccc + + ddddddddddd + + eeeeeeeeee + + ffffffffff + + gggggggggg; + + var aaaaaaaaaa = bbbbbbbbbb || cccccccccc + ? dddddddddd + eeeeeeeeee + : ffffffffff + gggggggggg; + aaaaaaaaaa = bbbbbbbbbb || cccccccccc + ? dddddddddd + eeeeeeeeee + : ffffffffff + gggggggggg; + + var something = MyClass.staticFunction( + aaaaaaaaaa, + bbbbbbbbbbb, + ccccccccccc, + ddddddddddd + ); + something = MyClass.staticFunction( + aaaaaaaaaa, + bbbbbbbbbbb, + ccccccccccc, + ddddddddddd + ); + + var something = + MyClass.staticFunction( + aaaaaaaaaa, + bbbbbbbbbbb, + ccccccccccc, + ddddddddddd + ) + + 0; + something = + MyClass.staticFunction( + aaaaaaaaaa, + bbbbbbbbbbb, + ccccccccccc, + ddddddddddd + ) + + 0; + + var something12 = new MyClass( + aaaaaaaaaa, + bbbbbbbbbbb, + ccccccccccc, + ddddddddddd + ); + something12 = new MyClass( + aaaaaaaaaa, + bbbbbbbbbbb, + ccccccccccc, + ddddddddddd + ); } void parentheses() {