diff --git a/src/printers/classes.ts b/src/printers/classes.ts index b622033e..9f75b543 100644 --- a/src/printers/classes.ts +++ b/src/printers/classes.ts @@ -4,8 +4,8 @@ import { SyntaxType, type NamedNode } from "../node-types.ts"; import { definedKeys, hasChild, - hasLeadingComments, indentInParentheses, + printAssignment, printBlock, printBlockStatements, printBodyDeclarations, @@ -16,7 +16,7 @@ import { type NamedNodePrinters } from "./helpers.ts"; -const { group, hardline, indent, indentIfBreak, join, line } = builders; +const { group, hardline, indent, join, line } = builders; export default { class_declaration(path, print) { @@ -96,31 +96,16 @@ export default { field_declaration: printVariableDeclaration, variable_declarator(path, print) { - const declarator = [path.call(print, "nameNode")]; + const leftDoc = [path.call(print, "nameNode")]; if (hasChild(path, "dimensionsNode")) { - declarator.push(path.call(print, "dimensionsNode")); + leftDoc.push(path.call(print, "dimensionsNode")); } - if (!hasChild(path, "valueNode")) { - return declarator; - } - declarator.push(" ="); - const value = path.call(print, "valueNode"); - if ( - path.node.valueNode.type === SyntaxType.BinaryExpression || - (path.node.valueNode.type === SyntaxType.TernaryExpression && - path.node.valueNode.conditionNode.type === - SyntaxType.BinaryExpression) || - hasLeadingComments(path.node.valueNode) - ) { - declarator.push(group(indent([line, value]))); - } else { - const groupId = Symbol("assignment"); - declarator.push( - group(indent(line), { id: groupId }), - indentIfBreak(value, { groupId }) - ); - } - return group(declarator); + return printAssignment( + leftDoc, + " =", + hasChild(path, "valueNode") ? path.call(print, "valueNode") : undefined, + path.node.valueNode + ); }, method_declaration(path, print) { diff --git a/src/printers/expressions.ts b/src/printers/expressions.ts index 2ebf22fc..d599daca 100644 --- a/src/printers/expressions.ts +++ b/src/printers/expressions.ts @@ -8,10 +8,10 @@ import { } from "../node-types.ts"; import { hasChild, - hasLeadingComments, hasType, indentInParentheses, isReturnOrThrowStatement, + printAssignment, printDanglingComments, shouldFlatten, type JavaParserOptions, @@ -232,26 +232,13 @@ export default { }, assignment_expression(path, print) { - const { operatorNode, rightNode } = path.node; - const parts = [path.call(print, "leftNode"), " ", operatorNode.type]; - const right = path.call(print, "rightNode"); - - if ( - rightNode.type === SyntaxType.BinaryExpression || - (rightNode.type === SyntaxType.TernaryExpression && - rightNode.conditionNode.type === SyntaxType.BinaryExpression) || - hasLeadingComments(rightNode) - ) { - parts.push(group(indent([line, right]))); - } else { - const groupId = Symbol("assignment"); - parts.push( - group(indent(line), { id: groupId }), - indentIfBreak(right, { groupId }) - ); - } - - return parts; + const { node } = path; + return printAssignment( + path.call(print, "leftNode"), + [" ", node.operatorNode.type], + path.call(print, "rightNode"), + node.rightNode + ); }, binary_expression(path, print, options) { diff --git a/src/printers/helpers.ts b/src/printers/helpers.ts index f726c1e1..0892777c 100644 --- a/src/printers/helpers.ts +++ b/src/printers/helpers.ts @@ -2,14 +2,26 @@ import type { AstPath, Doc, Options, ParserOptions } from "prettier"; import { builders, utils } from "prettier/doc"; import { SyntaxType, + type ArrayInitializerNode, type CommentNode, + type ExpressionNode, type NamedNode, type NamedType, type SyntaxNode, type TypeString } from "../node-types.ts"; -const { group, hardline, ifBreak, indent, join, line, softline } = builders; +const { + group, + hardline, + ifBreak, + indent, + indentIfBreak, + join, + line, + lineSuffixBoundary, + softline +} = builders; const { mapDoc } = utils; export function hasType( @@ -347,6 +359,40 @@ export function printVariableDeclaration( return declaration; } +export function printAssignment( + leftDoc: Doc, + operator: Doc, + rightDoc?: Doc, + rightNode?: ArrayInitializerNode | ExpressionNode +) { + if (!rightDoc || !rightNode) { + return leftDoc; + } + + const breakAfterOperator = + rightNode.type === SyntaxType.BinaryExpression || + rightNode.type === SyntaxType.InstanceofExpression || + (rightNode.type === SyntaxType.TernaryExpression && + (rightNode.conditionNode.type === SyntaxType.BinaryExpression || + rightNode.conditionNode.type === SyntaxType.InstanceofExpression)) || + hasLeadingComments(rightNode); + + if (breakAfterOperator) { + // First break after operator, then right-hand side + return group([leftDoc, operator, group(indent([line, rightDoc]))]); + } + + // First break right-hand side, then after operator + const groupId = Symbol("assignment"); + return group([ + leftDoc, + operator, + group(indent(line), { id: groupId }), + lineSuffixBoundary, + indentIfBreak(rightDoc, { groupId }) + ]); +} + export function printTextBlock( path: NamedNodePath, contents: Doc diff --git a/test/unit-test/binary_expressions/operator-position-end/_input.java b/test/unit-test/binary_expressions/operator-position-end/_input.java index 4bf5a64e..8dac159b 100644 --- a/test/unit-test/binary_expressions/operator-position-end/_input.java +++ b/test/unit-test/binary_expressions/operator-position-end/_input.java @@ -132,6 +132,12 @@ void instanceOf() { e instanceof @Ann final E baz; f instanceof final @Ann E qux; + + aaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + aaaaaaaaaa = bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; + + var aaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + var aaaaaaaaaa = bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; } void unaryExpression() { diff --git a/test/unit-test/binary_expressions/operator-position-end/_output.java b/test/unit-test/binary_expressions/operator-position-end/_output.java index 90edb840..bdb04dc4 100644 --- a/test/unit-test/binary_expressions/operator-position-end/_output.java +++ b/test/unit-test/binary_expressions/operator-position-end/_output.java @@ -247,6 +247,16 @@ void instanceOf() { e instanceof @Ann final E baz; f instanceof final @Ann E qux; + + aaaaaaaaaaaaaaaaaaaa = + bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + aaaaaaaaaa = + bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; + + var aaaaaaaaaaaaaaaaaaaa = + bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + var aaaaaaaaaa = + bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; } void unaryExpression() { diff --git a/test/unit-test/binary_expressions/operator-position-start/_input.java b/test/unit-test/binary_expressions/operator-position-start/_input.java index 4bf5a64e..8dac159b 100644 --- a/test/unit-test/binary_expressions/operator-position-start/_input.java +++ b/test/unit-test/binary_expressions/operator-position-start/_input.java @@ -132,6 +132,12 @@ void instanceOf() { e instanceof @Ann final E baz; f instanceof final @Ann E qux; + + aaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + aaaaaaaaaa = bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; + + var aaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + var aaaaaaaaaa = bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; } void unaryExpression() { diff --git a/test/unit-test/binary_expressions/operator-position-start/_output.java b/test/unit-test/binary_expressions/operator-position-start/_output.java index a3f99087..37711958 100644 --- a/test/unit-test/binary_expressions/operator-position-start/_output.java +++ b/test/unit-test/binary_expressions/operator-position-start/_output.java @@ -242,6 +242,16 @@ void instanceOf() { e instanceof @Ann final E baz; f instanceof final @Ann E qux; + + aaaaaaaaaaaaaaaaaaaa = + bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + aaaaaaaaaa = + bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; + + var aaaaaaaaaaaaaaaaaaaa = + bbbbbbbbbbbbbbbbbbbb instanceof Cccccccccccccccccccc cccccccccccccccccccc; + var aaaaaaaaaa = + bbbbbbbbbb instanceof Cccccccccc cccccccccc ? dddddddddd : eeeeeeeeee; } void unaryExpression() {