From 3a211eaed4773d0d57dd5d8dff747737a4f90497 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 17 Feb 2025 14:02:45 +1300 Subject: [PATCH 01/13] Matching Prettier's binary operation grouping and indentation --- src/binary-operator-printers/addition.js | 8 ++ src/binary-operator-printers/arithmetic.js | 51 ---------- src/binary-operator-printers/bit.js | 4 +- .../exponentiation.js | 31 +++--- src/binary-operator-printers/index.js | 3 +- .../multiplication.js | 20 ++++ .../create-binary-operation-printer.js | 64 +++++++++++++ src/binary-operator-printers/shift.js | 6 +- .../__snapshots__/jsfmt.spec.js.snap | 96 ++++++++----------- .../__snapshots__/jsfmt.spec.js.snap | 20 ++-- .../strings/__snapshots__/jsfmt.spec.js.snap | 3 +- .../__snapshots__/index.test.js.snap | 3 +- 12 files changed, 169 insertions(+), 140 deletions(-) create mode 100644 src/binary-operator-printers/addition.js delete mode 100644 src/binary-operator-printers/arithmetic.js create mode 100644 src/binary-operator-printers/multiplication.js create mode 100644 src/binary-operator-printers/printers/create-binary-operation-printer.js diff --git a/src/binary-operator-printers/addition.js b/src/binary-operator-printers/addition.js new file mode 100644 index 000000000..72b8ee9f3 --- /dev/null +++ b/src/binary-operator-printers/addition.js @@ -0,0 +1,8 @@ +import { defaultBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; + +export const addition = { + match: (op) => ['+', '-'].includes(op), + print: defaultBinaryOperationPrinter + // grouping and indenting before `bit` and `shift` should technically be here + // but they are properly parenthesised before reaching this point. +}; diff --git a/src/binary-operator-printers/arithmetic.js b/src/binary-operator-printers/arithmetic.js deleted file mode 100644 index b7b4b1240..000000000 --- a/src/binary-operator-printers/arithmetic.js +++ /dev/null @@ -1,51 +0,0 @@ -import { doc } from 'prettier'; -import { comparison } from './comparison.js'; - -const { group, line, indent } = doc.builders; - -const groupIfNecessaryBuilder = (path) => (document) => { - const parentNode = path.getParentNode(); - if ( - parentNode.type === 'BinaryOperation' && - !comparison.match(parentNode.operator) - ) { - return document; - } - return group(document); -}; - -const indentIfNecessaryBuilder = (path) => (document) => { - let node = path.getNode(); - for (let i = 0; ; i += 1) { - const parentNode = path.getParentNode(i); - if (parentNode.type === 'ReturnStatement') return document; - if ( - parentNode.type !== 'BinaryOperation' || - comparison.match(parentNode.operator) - ) { - return indent(document); - } - if (node === parentNode.right) return document; - node = parentNode; - } -}; - -export const arithmetic = { - match: (op) => ['+', '-', '*', '/', '%'].includes(op), - print: (node, path, print) => { - const groupIfNecessary = groupIfNecessaryBuilder(path); - const indentIfNecessary = indentIfNecessaryBuilder(path); - - const right = [node.operator, line, path.call(print, 'right')]; - // If it's a single binary operation, avoid having a small right - // operand like - 1 on its own line - const shouldGroup = - node.left.type !== 'BinaryOperation' && - path.getParentNode().type !== 'BinaryOperation'; - return groupIfNecessary([ - path.call(print, 'left'), - ' ', - indentIfNecessary(shouldGroup ? group(right) : right) - ]); - } -}; diff --git a/src/binary-operator-printers/bit.js b/src/binary-operator-printers/bit.js index 761a182f8..6664a3a5f 100644 --- a/src/binary-operator-printers/bit.js +++ b/src/binary-operator-printers/bit.js @@ -1,6 +1,6 @@ -import { arithmetic } from './arithmetic.js'; +import { defaultBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; export const bit = { match: (op) => ['&', '|', '^'].includes(op), - print: arithmetic.print + print: defaultBinaryOperationPrinter }; diff --git a/src/binary-operator-printers/exponentiation.js b/src/binary-operator-printers/exponentiation.js index 637f68075..b06632bc2 100644 --- a/src/binary-operator-printers/exponentiation.js +++ b/src/binary-operator-printers/exponentiation.js @@ -1,19 +1,24 @@ import { doc } from 'prettier'; +import { + createBinaryOperationPrinter, + createIndentIfNecessaryBuilder +} from './printers/create-binary-operation-printer.js'; +import { addition } from './addition.js'; +import { multiplication } from './multiplication.js'; -const { group, indent, line } = doc.builders; +const { group } = doc.builders; + +const exponentiationPrinter = createBinaryOperationPrinter( + () => (document) => group(document), // always group + createIndentIfNecessaryBuilder([ + addition, + multiplication + // `bit` and `shift` should technically be here but they are properly + // parenthesised before reaching this point. + ]) +); export const exponentiation = { match: (op) => op === '**', - print: (node, path, print) => { - const right = [' ', node.operator, line, path.call(print, 'right')]; - // If it's a single binary operation, avoid having a small right - // operand like - 1 on its own line - const shouldGroup = - node.left.type !== 'BinaryOperation' && - path.getParentNode().type !== 'BinaryOperation'; - return group([ - path.call(print, 'left'), - indent(shouldGroup ? group(right) : right) - ]); - } + print: exponentiationPrinter }; diff --git a/src/binary-operator-printers/index.js b/src/binary-operator-printers/index.js index e65a4f1e9..50871f42a 100644 --- a/src/binary-operator-printers/index.js +++ b/src/binary-operator-printers/index.js @@ -1,7 +1,8 @@ -export * from './arithmetic.js'; +export * from './addition.js'; export * from './assignment.js'; export * from './bit.js'; export * from './comparison.js'; export * from './exponentiation.js'; export * from './logical.js'; +export * from './multiplication.js'; export * from './shift.js'; diff --git a/src/binary-operator-printers/multiplication.js b/src/binary-operator-printers/multiplication.js new file mode 100644 index 000000000..f08cd1d1d --- /dev/null +++ b/src/binary-operator-printers/multiplication.js @@ -0,0 +1,20 @@ +import { + createBinaryOperationPrinter, + createGroupIfNecessaryBuilder, + createIndentIfNecessaryBuilder +} from './printers/create-binary-operation-printer.js'; +import { addition } from './addition.js'; +import { bit } from './bit.js'; +import { shift } from './shift.js'; + +const matchers = [addition, bit, shift]; + +const multiplicationPrinter = createBinaryOperationPrinter( + createGroupIfNecessaryBuilder(matchers), + createIndentIfNecessaryBuilder(matchers) +); + +export const multiplication = { + match: (op) => ['*', '/', '%'].includes(op), + print: multiplicationPrinter +}; diff --git a/src/binary-operator-printers/printers/create-binary-operation-printer.js b/src/binary-operator-printers/printers/create-binary-operation-printer.js new file mode 100644 index 000000000..5d7380d6c --- /dev/null +++ b/src/binary-operator-printers/printers/create-binary-operation-printer.js @@ -0,0 +1,64 @@ +import { doc } from 'prettier'; +import { assignment } from '../assignment.js'; +import { comparison } from '../comparison.js'; + +const { group, indent, line } = doc.builders; + +const shouldGroupOrIndent = (node, matchers) => + matchers.some((matcher) => matcher.match(node.operator)); + +export const createGroupIfNecessaryBuilder = + (matchers) => (path) => (document) => { + const parentNode = path.getParentNode(); + if ( + parentNode.type === 'BinaryOperation' && + !comparison.match(parentNode.operator) + ) { + return shouldGroupOrIndent(parentNode, matchers) + ? group(document) + : document; + } + return group(document); + }; + +export const createIndentIfNecessaryBuilder = + (matchers) => (path) => (document) => { + let node = path.getNode(); + for (let i = 0; ; i += 1) { + const parentNode = path.getParentNode(i); + if (parentNode.type === 'ReturnStatement') return document; + if ( + parentNode.type !== 'BinaryOperation' || + comparison.match(parentNode.operator) || + shouldGroupOrIndent(parentNode, matchers) + ) { + return indent(document); + } + if (node === parentNode.right) return document; + node = parentNode; + } + }; + +export const createBinaryOperationPrinter = + (groupIfNecessaryBuilder, indentIfNecessaryBuilder) => + (node, path, print) => { + const groupIfNecessary = groupIfNecessaryBuilder(path); + const indentIfNecessary = indentIfNecessaryBuilder(path); + + const right = [' ', node.operator, line, path.call(print, 'right')]; + // If it's a single binary operation, avoid having a small right + // operand like - 1 on its own line + const parent = path.getParentNode(); + const shouldGroup = + node.left.type !== 'BinaryOperation' && + (parent.type !== 'BinaryOperation' || assignment.match(parent.operator)); + return groupIfNecessary([ + path.call(print, 'left'), + indentIfNecessary(shouldGroup ? group(right) : right) + ]); + }; + +export const defaultBinaryOperationPrinter = createBinaryOperationPrinter( + createGroupIfNecessaryBuilder([]), + createIndentIfNecessaryBuilder([]) +); diff --git a/src/binary-operator-printers/shift.js b/src/binary-operator-printers/shift.js index 026747cca..7ea0ca436 100644 --- a/src/binary-operator-printers/shift.js +++ b/src/binary-operator-printers/shift.js @@ -1,6 +1,8 @@ -import { arithmetic } from './arithmetic.js'; +import { defaultBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; export const shift = { match: (op) => ['<<', '>>'].includes(op), - print: arithmetic.print + print: defaultBinaryOperationPrinter + // grouping and indenting before `bit` should technically be here but they + // are properly parenthesised before reaching this point. }; diff --git a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap index 7c2655ccc..33647ae31 100644 --- a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap @@ -376,7 +376,7 @@ contract Group { function exp() public { resultUint256 = veryVeryVeryLongUint256A ** - veryVeryVeryLongUint256B ** veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B ** veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A ** veryVeryVeryLongUint256B * veryVeryVeryLongUint256C; @@ -442,12 +442,10 @@ contract Group { (veryVeryVeryLongUint256A * veryVeryVeryLongUint256B) % veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A * - veryVeryVeryLongUint256B + + veryVeryVeryLongUint256A * veryVeryVeryLongUint256B + veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A * - veryVeryVeryLongUint256B - + veryVeryVeryLongUint256A * veryVeryVeryLongUint256B - veryVeryVeryLongUint256C; resultUint256 = (veryVeryVeryLongUint256A * veryVeryVeryLongUint256B) << @@ -499,12 +497,10 @@ contract Group { (veryVeryVeryLongUint256A / veryVeryVeryLongUint256B) % veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A / - veryVeryVeryLongUint256B + + veryVeryVeryLongUint256A / veryVeryVeryLongUint256B + veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A / - veryVeryVeryLongUint256B - + veryVeryVeryLongUint256A / veryVeryVeryLongUint256B - veryVeryVeryLongUint256C; resultUint256 = (veryVeryVeryLongUint256A / veryVeryVeryLongUint256B) << @@ -561,24 +557,19 @@ contract Group { (veryVeryVeryLongUint256A % veryVeryVeryLongUint256B) - veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A % - veryVeryVeryLongUint256B << + veryVeryVeryLongUint256A % veryVeryVeryLongUint256B << veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A % - veryVeryVeryLongUint256B >> + veryVeryVeryLongUint256A % veryVeryVeryLongUint256B >> veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A % - veryVeryVeryLongUint256B & + veryVeryVeryLongUint256A % veryVeryVeryLongUint256B & veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A % - veryVeryVeryLongUint256B | + veryVeryVeryLongUint256A % veryVeryVeryLongUint256B | veryVeryVeryLongUint256C; resultUint256 = - veryVeryVeryLongUint256A % - veryVeryVeryLongUint256B ^ + veryVeryVeryLongUint256A % veryVeryVeryLongUint256B ^ veryVeryVeryLongUint256C; resultBoolean = veryVeryVeryLongUint256A % veryVeryVeryLongUint256B == @@ -606,12 +597,10 @@ contract Group { veryVeryVeryLongUint256B ** veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A + - veryVeryVeryLongUint256B * - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B * veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A + - veryVeryVeryLongUint256B / - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B / veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A + (veryVeryVeryLongUint256B % veryVeryVeryLongUint256C); @@ -664,12 +653,10 @@ contract Group { veryVeryVeryLongUint256B ** veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A - - veryVeryVeryLongUint256B * - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B * veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A - - veryVeryVeryLongUint256B / - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B / veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A - (veryVeryVeryLongUint256B % veryVeryVeryLongUint256C); @@ -728,8 +715,7 @@ contract Group { (veryVeryVeryLongUint256B / veryVeryVeryLongUint256C); resultUint256 = veryVeryVeryLongUint256A << - veryVeryVeryLongUint256B % - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B % veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A << (veryVeryVeryLongUint256B + veryVeryVeryLongUint256C); @@ -783,8 +769,7 @@ contract Group { (veryVeryVeryLongUint256B / veryVeryVeryLongUint256C); resultUint256 = veryVeryVeryLongUint256A >> - veryVeryVeryLongUint256B % - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B % veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A >> (veryVeryVeryLongUint256B + veryVeryVeryLongUint256C); @@ -838,8 +823,7 @@ contract Group { (veryVeryVeryLongUint256B / veryVeryVeryLongUint256C); resultUint256 = veryVeryVeryLongUint256A & - veryVeryVeryLongUint256B % - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B % veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A & (veryVeryVeryLongUint256B + veryVeryVeryLongUint256C); @@ -894,8 +878,7 @@ contract Group { (veryVeryVeryLongUint256B / veryVeryVeryLongUint256C); resultUint256 = veryVeryVeryLongUint256A | - veryVeryVeryLongUint256B % - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B % veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A | (veryVeryVeryLongUint256B + veryVeryVeryLongUint256C); @@ -950,8 +933,7 @@ contract Group { (veryVeryVeryLongUint256B / veryVeryVeryLongUint256C); resultUint256 = veryVeryVeryLongUint256A ^ - veryVeryVeryLongUint256B % - veryVeryVeryLongUint256C; + veryVeryVeryLongUint256B % veryVeryVeryLongUint256C; resultUint256 = veryVeryVeryLongUint256A ^ (veryVeryVeryLongUint256B + veryVeryVeryLongUint256C); @@ -1691,8 +1673,8 @@ contract Indent { function exp() public { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A ** - veryVeryVeryExtremelyExtremelyLongUint256B ** - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256B ** + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A ** veryVeryVeryExtremelyExtremelyLongUint256B * @@ -1778,11 +1760,11 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A * - veryVeryVeryExtremelyExtremelyLongUint256B + + veryVeryVeryExtremelyExtremelyLongUint256B + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A * - veryVeryVeryExtremelyExtremelyLongUint256B - + veryVeryVeryExtremelyExtremelyLongUint256B - veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = (veryVeryVeryExtremelyExtremelyLongUint256A * @@ -1849,11 +1831,11 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A / - veryVeryVeryExtremelyExtremelyLongUint256B + + veryVeryVeryExtremelyExtremelyLongUint256B + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A / - veryVeryVeryExtremelyExtremelyLongUint256B - + veryVeryVeryExtremelyExtremelyLongUint256B - veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = (veryVeryVeryExtremelyExtremelyLongUint256A / @@ -1928,23 +1910,23 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A % - veryVeryVeryExtremelyExtremelyLongUint256B << + veryVeryVeryExtremelyExtremelyLongUint256B << veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A % - veryVeryVeryExtremelyExtremelyLongUint256B >> + veryVeryVeryExtremelyExtremelyLongUint256B >> veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A % - veryVeryVeryExtremelyExtremelyLongUint256B & + veryVeryVeryExtremelyExtremelyLongUint256B & veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A % - veryVeryVeryExtremelyExtremelyLongUint256B | + veryVeryVeryExtremelyExtremelyLongUint256B | veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A % - veryVeryVeryExtremelyExtremelyLongUint256B ^ + veryVeryVeryExtremelyExtremelyLongUint256B ^ veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A % @@ -1980,11 +1962,11 @@ contract Indent { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A + veryVeryVeryExtremelyExtremelyLongUint256B * - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A + veryVeryVeryExtremelyExtremelyLongUint256B / - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A + (veryVeryVeryExtremelyExtremelyLongUint256B % @@ -2051,11 +2033,11 @@ contract Indent { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A - veryVeryVeryExtremelyExtremelyLongUint256B * - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A - veryVeryVeryExtremelyExtremelyLongUint256B / - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A - (veryVeryVeryExtremelyExtremelyLongUint256B % @@ -2130,7 +2112,7 @@ contract Indent { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A << veryVeryVeryExtremelyExtremelyLongUint256B % - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A << (veryVeryVeryExtremelyExtremelyLongUint256B + @@ -2201,7 +2183,7 @@ contract Indent { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A >> veryVeryVeryExtremelyExtremelyLongUint256B % - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A >> (veryVeryVeryExtremelyExtremelyLongUint256B + @@ -2272,7 +2254,7 @@ contract Indent { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A & veryVeryVeryExtremelyExtremelyLongUint256B % - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A & (veryVeryVeryExtremelyExtremelyLongUint256B + @@ -2343,7 +2325,7 @@ contract Indent { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A | veryVeryVeryExtremelyExtremelyLongUint256B % - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A | (veryVeryVeryExtremelyExtremelyLongUint256B + @@ -2414,7 +2396,7 @@ contract Indent { resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A ^ veryVeryVeryExtremelyExtremelyLongUint256B % - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultUint256 = veryVeryVeryExtremelyExtremelyLongUint256A ^ (veryVeryVeryExtremelyExtremelyLongUint256B + diff --git a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap index f3c990af5..c9ff49f7c 100644 --- a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap @@ -258,15 +258,14 @@ contract ArithmeticOperators { veryVeryVeryVeryVeryLongVariableCalledB ) + c * - veryVeryVeryVeryVeryLongFunctionCalledA( - veryVeryVeryVeryVeryLongVariableCalledB - ) - + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) - d; a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) + - c; + ) + c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -307,7 +306,7 @@ contract ArithmeticOperators { veryVeryVeryVeryVeryLongVariableCalledB; a = veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledB; a = veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB * @@ -325,13 +324,13 @@ contract ArithmeticOperators { for ( a = veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledB; a <= veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB; a += veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledB ) {} a( veryVeryVeryVeryVeryLongVariableCalledA ** @@ -339,7 +338,7 @@ contract ArithmeticOperators { ); return veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledB; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB ) ** c; @@ -354,8 +353,7 @@ contract ArithmeticOperators { a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) ** - c; + ) ** c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB diff --git a/tests/format/strings/__snapshots__/jsfmt.spec.js.snap b/tests/format/strings/__snapshots__/jsfmt.spec.js.snap index 2ec8073d9..b087b7a43 100644 --- a/tests/format/strings/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/strings/__snapshots__/jsfmt.spec.js.snap @@ -1475,8 +1475,7 @@ library strings { ptr, needle._len, needle._ptr - ) + - needle._len; + ) + needle._len; } } diff --git a/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap b/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap index 8f92fd9c2..d626cc27b 100644 --- a/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap +++ b/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap @@ -2,12 +2,13 @@ exports[`binary operators printers to match snapshot 1`] = ` [ - "arithmetic", + "addition", "assignment", "bit", "comparison", "exponentiation", "logical", + "multiplication", "shift", ] `; From 573748a92c7941e80f0fad6230b4da346cbc7ee6 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 10 Mar 2025 21:36:11 +1300 Subject: [PATCH 02/13] Adding Parentheses on consecutive equality operators --- src/parser.js | 4 +++ .../__snapshots__/jsfmt.spec.js.snap | 24 ++++++------- .../format/Parentheses/LogicNoParentheses.sol | 16 +++++++++ .../__snapshots__/jsfmt.spec.js.snap | 36 +++++++++++++++++++ 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/parser.js b/src/parser.js index e2a119245..a305c9d3b 100644 --- a/src/parser.js +++ b/src/parser.js @@ -176,6 +176,10 @@ function parse(text, _parsers, options = _parsers) { '&' ]); break; + case '==': + case '!=': + ctx.left = tryHug(ctx.left, ['==', '!=']); + break; case '||': ctx.left = tryHug(ctx.left, ['&&']); ctx.right = tryHug(ctx.right, ['&&']); diff --git a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap index 33647ae31..5c51a301f 100644 --- a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap @@ -1011,10 +1011,10 @@ contract Group { veryVeryVeryLongUint256A == veryVeryVeryLongUint256B ^ veryVeryVeryLongUint256C; resultBoolean = - veryVeryVeryLongUint256A == veryVeryVeryLongUint256B == + (veryVeryVeryLongUint256A == veryVeryVeryLongUint256B) == veryVeryVeryLongBooleanC; resultBoolean = - veryVeryVeryLongUint256A == veryVeryVeryLongUint256B != + (veryVeryVeryLongUint256A == veryVeryVeryLongUint256B) != veryVeryVeryLongBooleanC; resultBoolean = veryVeryVeryLongBooleanA == @@ -1065,10 +1065,10 @@ contract Group { veryVeryVeryLongUint256A != veryVeryVeryLongUint256B ^ veryVeryVeryLongUint256C; resultBoolean = - veryVeryVeryLongUint256A != veryVeryVeryLongUint256B == + (veryVeryVeryLongUint256A != veryVeryVeryLongUint256B) == veryVeryVeryLongBooleanC; resultBoolean = - veryVeryVeryLongUint256A != veryVeryVeryLongUint256B != + (veryVeryVeryLongUint256A != veryVeryVeryLongUint256B) != veryVeryVeryLongBooleanC; resultBoolean = veryVeryVeryLongBooleanA != @@ -2497,12 +2497,12 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256B ^ veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A == - veryVeryVeryExtremelyExtremelyLongUint256B == + (veryVeryVeryExtremelyExtremelyLongUint256A == + veryVeryVeryExtremelyExtremelyLongUint256B) == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A == - veryVeryVeryExtremelyExtremelyLongUint256B != + (veryVeryVeryExtremelyExtremelyLongUint256A == + veryVeryVeryExtremelyExtremelyLongUint256B) != veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == @@ -2568,12 +2568,12 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256B ^ veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A != - veryVeryVeryExtremelyExtremelyLongUint256B == + (veryVeryVeryExtremelyExtremelyLongUint256A != + veryVeryVeryExtremelyExtremelyLongUint256B) == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A != - veryVeryVeryExtremelyExtremelyLongUint256B != + (veryVeryVeryExtremelyExtremelyLongUint256A != + veryVeryVeryExtremelyExtremelyLongUint256B) != veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != diff --git a/tests/format/Parentheses/LogicNoParentheses.sol b/tests/format/Parentheses/LogicNoParentheses.sol index 2345f549f..c2414f4bf 100644 --- a/tests/format/Parentheses/LogicNoParentheses.sol +++ b/tests/format/Parentheses/LogicNoParentheses.sol @@ -17,4 +17,20 @@ contract LogicNoParentheses { function andAnd(bool a, bool b, bool c) public pure returns (bool) { return a && b && c; } + + function equalEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b == c; + } + + function equalNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b != c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b != c; + } } diff --git a/tests/format/Parentheses/__snapshots__/jsfmt.spec.js.snap b/tests/format/Parentheses/__snapshots__/jsfmt.spec.js.snap index e51bd2d48..408639764 100644 --- a/tests/format/Parentheses/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/Parentheses/__snapshots__/jsfmt.spec.js.snap @@ -1208,6 +1208,22 @@ contract LogicNoParentheses { function andAnd(bool a, bool b, bool c) public pure returns (bool) { return a && b && c; } + + function equalEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b == c; + } + + function equalNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b != c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b != c; + } } =====================================output===================================== @@ -1230,6 +1246,26 @@ contract LogicNoParentheses { function andAnd(bool a, bool b, bool c) public pure returns (bool) { return a && b && c; } + + function equalEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a == b) == c; + } + + function equalNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a == b) != c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a != b) == c; + } + + function notEqualNotEqual( + bool a, + bool b, + bool c + ) public pure returns (bool) { + return (a != b) != c; + } } ================================================================================ From 0177e69bf956f6d61da69cf6276cb3f782b6ad20 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 10 Mar 2025 22:04:23 +1300 Subject: [PATCH 03/13] indenting `comparison` over `logical` operators --- src/binary-operator-printers/comparison.js | 2 ++ .../__snapshots__/jsfmt.spec.js.snap | 16 +++++------ .../__snapshots__/jsfmt.spec.js.snap | 2 +- .../__snapshots__/jsfmt.spec.js.snap | 28 +++++++++---------- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/binary-operator-printers/comparison.js b/src/binary-operator-printers/comparison.js index 56e3a3acb..efcf3f9b4 100644 --- a/src/binary-operator-printers/comparison.js +++ b/src/binary-operator-printers/comparison.js @@ -1,4 +1,5 @@ import { doc } from 'prettier'; +import { logical } from './logical.js'; const { group, indent, line } = doc.builders; @@ -11,6 +12,7 @@ const indentIfNecessaryBuilder = (path) => (document) => { if (parentNode.type === 'ForStatement') return document; if (parentNode.type === 'WhileStatement') return document; if (parentNode.type !== 'BinaryOperation') return indent(document); + if (logical.match(parentNode.operator)) return indent(document); if (node === parentNode.right) return document; node = parentNode; } diff --git a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap index 5c51a301f..15dd20e47 100644 --- a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap @@ -2825,11 +2825,11 @@ contract Indent { resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA || veryVeryVeryExtremelyExtremelyLongBooleanB == - veryVeryVeryExtremelyExtremelyLongBooleanC; + veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA || veryVeryVeryExtremelyExtremelyLongBooleanB != - veryVeryVeryExtremelyExtremelyLongBooleanC; + veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = (veryVeryVeryExtremelyExtremelyLongBooleanA && veryVeryVeryExtremelyExtremelyLongBooleanB) || @@ -2841,26 +2841,26 @@ contract Indent { resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA && veryVeryVeryExtremelyExtremelyLongBooleanB == - veryVeryVeryExtremelyExtremelyLongBooleanC; + veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA && veryVeryVeryExtremelyExtremelyLongBooleanB != - veryVeryVeryExtremelyExtremelyLongBooleanC; + veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == - veryVeryVeryExtremelyExtremelyLongBooleanB || + veryVeryVeryExtremelyExtremelyLongBooleanB || veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == - veryVeryVeryExtremelyExtremelyLongBooleanB && + veryVeryVeryExtremelyExtremelyLongBooleanB && veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != - veryVeryVeryExtremelyExtremelyLongBooleanB || + veryVeryVeryExtremelyExtremelyLongBooleanB || veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != - veryVeryVeryExtremelyExtremelyLongBooleanB && + veryVeryVeryExtremelyExtremelyLongBooleanB && veryVeryVeryExtremelyExtremelyLongBooleanC; } } diff --git a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap index c9ff49f7c..16b9b50f8 100644 --- a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap @@ -504,7 +504,7 @@ contract ComparisonOperators { veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB ) > - d; + d; a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB diff --git a/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap b/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap index a290e72ad..e1d06fedd 100644 --- a/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap @@ -409,7 +409,7 @@ contract Conditional { ( bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() + averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() ) ? "foo" : "bar"; @@ -420,7 +420,7 @@ contract Conditional { ( bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() + averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() ) ? "foo" : anotherCondition ? "bar" @@ -920,8 +920,8 @@ contract Conditional { bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl() - .anodyneCondosMalateOverateRetinol() + averredBathersBoxroomBuggyNurl() + .anodyneCondosMalateOverateRetinol() ) ? "foo" : "bar"; @@ -933,8 +933,8 @@ contract Conditional { bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl() - .anodyneCondosMalateOverateRetinol() + averredBathersBoxroomBuggyNurl() + .anodyneCondosMalateOverateRetinol() ) ? "foo" : anotherCondition ? "bar" @@ -1433,8 +1433,8 @@ contract Conditional { bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl() - .anodyneCondosMalateOverateRetinol() + averredBathersBoxroomBuggyNurl() + .anodyneCondosMalateOverateRetinol() ) ? "foo" : "bar"; @@ -1446,8 +1446,8 @@ contract Conditional { bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl() - .anodyneCondosMalateOverateRetinol() + averredBathersBoxroomBuggyNurl() + .anodyneCondosMalateOverateRetinol() ) ? "foo" : anotherCondition ? "bar" @@ -1945,8 +1945,8 @@ contract Conditional { string storage longConditional = (bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl() - .anodyneCondosMalateOverateRetinol()) + averredBathersBoxroomBuggyNurl() + .anodyneCondosMalateOverateRetinol()) ? "foo" : "bar"; @@ -1956,8 +1956,8 @@ contract Conditional { storage longConditionalChained = (bifornCringerMoshedPerplexSawder == 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= - averredBathersBoxroomBuggyNurl() - .anodyneCondosMalateOverateRetinol()) + averredBathersBoxroomBuggyNurl() + .anodyneCondosMalateOverateRetinol()) ? "foo" : anotherCondition ? "bar" From 987e288e51736022ec38b2f77ceb12224c85541e Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 17 Feb 2025 15:37:18 +1300 Subject: [PATCH 04/13] support for experimentalOperatorPosition --- src/binary-operator-printers/comparison.js | 8 +- src/binary-operator-printers/logical.js | 6 +- .../create-binary-operation-printer.js | 7 +- .../printers/right-operand-printer.js | 8 + src/options.js | 16 + .../__snapshots__/jsfmt.spec.js.snap | 1398 ++++++++++++++--- tests/format/BinaryOperators/jsfmt.spec.js | 4 + 7 files changed, 1219 insertions(+), 228 deletions(-) create mode 100644 src/binary-operator-printers/printers/right-operand-printer.js diff --git a/src/binary-operator-printers/comparison.js b/src/binary-operator-printers/comparison.js index efcf3f9b4..f27d1a060 100644 --- a/src/binary-operator-printers/comparison.js +++ b/src/binary-operator-printers/comparison.js @@ -1,7 +1,8 @@ import { doc } from 'prettier'; +import { rightOperandPrinter } from './printers/right-operand-printer.js'; import { logical } from './logical.js'; -const { group, indent, line } = doc.builders; +const { group, indent } = doc.builders; const indentIfNecessaryBuilder = (path) => (document) => { let node = path.getNode(); @@ -20,10 +21,10 @@ const indentIfNecessaryBuilder = (path) => (document) => { export const comparison = { match: (op) => ['<', '>', '<=', '>=', '==', '!='].includes(op), - print: (node, path, print) => { + print: (node, path, print, options) => { const indentIfNecessary = indentIfNecessaryBuilder(path); - const right = [node.operator, line, path.call(print, 'right')]; + const right = rightOperandPrinter(node, path, print, options); // If it's a single binary operation, avoid having a small right // operand like - 1 on its own line const shouldGroup = @@ -31,7 +32,6 @@ export const comparison = { path.getParentNode().type !== 'BinaryOperation'; return group([ path.call(print, 'left'), - ' ', indentIfNecessary(shouldGroup ? group(right) : right) ]); } diff --git a/src/binary-operator-printers/logical.js b/src/binary-operator-printers/logical.js index e787cb7ce..3a73c2e3c 100644 --- a/src/binary-operator-printers/logical.js +++ b/src/binary-operator-printers/logical.js @@ -1,6 +1,7 @@ import { doc } from 'prettier'; +import { rightOperandPrinter } from './printers/right-operand-printer.js'; -const { group, line, indent } = doc.builders; +const { group, indent } = doc.builders; const groupIfNecessaryBuilder = (path) => (document) => path.getParentNode().type === 'BinaryOperation' ? document : group(document); @@ -30,7 +31,7 @@ export const logical = { const groupIfNecessary = groupIfNecessaryBuilder(path); const indentIfNecessary = indentIfNecessaryBuilder(path, options); - const right = [node.operator, line, path.call(print, 'right')]; + const right = rightOperandPrinter(node, path, print, options); // If it's a single binary operation, avoid having a small right // operand like - 1 on its own line const shouldGroup = @@ -38,7 +39,6 @@ export const logical = { path.getParentNode().type !== 'BinaryOperation'; return groupIfNecessary([ path.call(print, 'left'), - ' ', indentIfNecessary(shouldGroup ? group(right) : right) ]); } diff --git a/src/binary-operator-printers/printers/create-binary-operation-printer.js b/src/binary-operator-printers/printers/create-binary-operation-printer.js index 5d7380d6c..6e31720c5 100644 --- a/src/binary-operator-printers/printers/create-binary-operation-printer.js +++ b/src/binary-operator-printers/printers/create-binary-operation-printer.js @@ -1,8 +1,9 @@ import { doc } from 'prettier'; import { assignment } from '../assignment.js'; import { comparison } from '../comparison.js'; +import { rightOperandPrinter } from './right-operand-printer.js'; -const { group, indent, line } = doc.builders; +const { group, indent } = doc.builders; const shouldGroupOrIndent = (node, matchers) => matchers.some((matcher) => matcher.match(node.operator)); @@ -41,11 +42,11 @@ export const createIndentIfNecessaryBuilder = export const createBinaryOperationPrinter = (groupIfNecessaryBuilder, indentIfNecessaryBuilder) => - (node, path, print) => { + (node, path, print, options) => { const groupIfNecessary = groupIfNecessaryBuilder(path); const indentIfNecessary = indentIfNecessaryBuilder(path); - const right = [' ', node.operator, line, path.call(print, 'right')]; + const right = rightOperandPrinter(node, path, print, options); // If it's a single binary operation, avoid having a small right // operand like - 1 on its own line const parent = path.getParentNode(); diff --git a/src/binary-operator-printers/printers/right-operand-printer.js b/src/binary-operator-printers/printers/right-operand-printer.js new file mode 100644 index 000000000..551e39132 --- /dev/null +++ b/src/binary-operator-printers/printers/right-operand-printer.js @@ -0,0 +1,8 @@ +import { doc } from 'prettier'; + +const { line } = doc.builders; + +export const rightOperandPrinter = (node, path, print, options) => + options.experimentalOperatorPosition === 'end' + ? [' ', node.operator, line, path.call(print, 'right')] + : [line, node.operator, ' ', path.call(print, 'right')]; diff --git a/src/options.js b/src/options.js index 34fa5a44d..f4bb65781 100644 --- a/src/options.js +++ b/src/options.js @@ -50,6 +50,22 @@ const options = { oppositeDescription: 'Default behavior of ternaries; keep question marks on the same line as the consequent.' }, + experimentalOperatorPosition: { + category: CATEGORY_JAVASCRIPT, + type: 'choice', + default: 'end', + description: 'Where to print operators when binary expressions wrap lines.', + choices: [ + { + value: 'start', + description: 'Print operators at the start of new lines.' + }, + { + value: 'end', + description: 'Print operators at the end of previous lines.' + } + ] + }, compiler: { category: CATEGORY_SOLIDITY, type: 'string', diff --git a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap index 16b9b50f8..032b0f698 100644 --- a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap @@ -1,8 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`BinaryOperators.sol - {"compiler":"0.5.8"} format 1`] = ` +exports[`BinaryOperators.sol - {"compiler":"0.5.8","experimentalOperatorPosition":"start"} format 1`] = ` ====================================options===================================== compiler: "0.5.8" +experimentalOperatorPosition: "start" parsers: ["solidity-parse"] printWidth: 80 | printWidth @@ -205,63 +206,63 @@ contract ArithmeticOperators { a % b; a ** b; (a % b) + c - (d * e) / f ** g; - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA - - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA * - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA / - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA % - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB - - (((c * d) / e) % f ** g); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + * veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + / veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + % veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB + - (((c * d) / e) % f ** g); a = - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; if ( - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB == - a() + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB + == a() ) {} if ( - a() == - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB + a() + == veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB ) {} for ( a = - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB; - a <= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; + a + <= veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; a += - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB ) {} a( - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB ); return - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB ) + c; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) + - c * - veryVeryVeryVeryVeryLongFunctionCalledA( + ) + + c + * veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) - - d; + ) + - d; a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -288,68 +289,68 @@ contract ArithmeticOperators { function someFunction() { a ** b; a ** c * d ** e; - a ** c * - d ** e * - a ** c * - d ** e * - a ** c * - d ** e * - a ** c * - d ** e * - a ** c * - d ** e; - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA * - veryVeryVeryVeryVeryLongVariableCalledB ** c; - c ** veryVeryVeryVeryVeryLongVariableCalledA * - veryVeryVeryVeryVeryLongVariableCalledB; + a ** c + * d ** e + * a ** c + * d ** e + * a ** c + * d ** e + * a ** c + * d ** e + * a ** c + * d ** e; + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + * veryVeryVeryVeryVeryLongVariableCalledB ** c; + c ** veryVeryVeryVeryVeryLongVariableCalledA + * veryVeryVeryVeryVeryLongVariableCalledB; a = - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB; a = - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB * - c; + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB + * c; if ( - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB == - a() + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB + == a() ) {} if ( - a() == - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB + a() + == veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB ) {} for ( a = - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; - a <= - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB; + a + <= veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB; a += - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB ) {} a( - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB ); return - veryVeryVeryVeryVeryLongVariableCalledA ** - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + ** veryVeryVeryVeryVeryLongVariableCalledB; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB ) ** c; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) ** - c * - veryVeryVeryVeryVeryLongFunctionCalledA( + ) + ** c + * veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) ** - d; + ) + ** d; a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -376,30 +377,30 @@ contract ShiftOperators { function someFunction() { a << b; a >> b; - veryVeryVeryVeryVeryLongVariableCalledA << - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA >> - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + << veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + >> veryVeryVeryVeryVeryLongVariableCalledB; a = - veryVeryVeryVeryVeryLongVariableCalledA << - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + << veryVeryVeryVeryVeryLongVariableCalledB; if ( - veryVeryVeryVeryVeryLongVariableCalledA << - veryVeryVeryVeryVeryLongVariableCalledB == - a() + veryVeryVeryVeryVeryLongVariableCalledA + << veryVeryVeryVeryVeryLongVariableCalledB + == a() ) {} if ( - a() == - veryVeryVeryVeryVeryLongVariableCalledA << - veryVeryVeryVeryVeryLongVariableCalledB + a() + == veryVeryVeryVeryVeryLongVariableCalledA + << veryVeryVeryVeryVeryLongVariableCalledB ) {} a( - veryVeryVeryVeryVeryLongVariableCalledA << - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + << veryVeryVeryVeryVeryLongVariableCalledB ); return - veryVeryVeryVeryVeryLongVariableCalledA << - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + << veryVeryVeryVeryVeryLongVariableCalledB; } } @@ -409,32 +410,32 @@ contract BitOperators { a & b; a | b; a ^ b; - veryVeryVeryVeryVeryLongVariableCalledA & - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA | - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA ^ - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + & veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + | veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + ^ veryVeryVeryVeryVeryLongVariableCalledB; a = - veryVeryVeryVeryVeryLongVariableCalledA & - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + & veryVeryVeryVeryVeryLongVariableCalledB; if ( - veryVeryVeryVeryVeryLongVariableCalledA & - veryVeryVeryVeryVeryLongVariableCalledB == - a() + veryVeryVeryVeryVeryLongVariableCalledA + & veryVeryVeryVeryVeryLongVariableCalledB + == a() ) {} if ( - a() == - veryVeryVeryVeryVeryLongVariableCalledA & - veryVeryVeryVeryVeryLongVariableCalledB + a() + == veryVeryVeryVeryVeryLongVariableCalledA + & veryVeryVeryVeryVeryLongVariableCalledB ) {} a( - veryVeryVeryVeryVeryLongVariableCalledA & - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + & veryVeryVeryVeryVeryLongVariableCalledB ); return - veryVeryVeryVeryVeryLongVariableCalledA & - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + & veryVeryVeryVeryVeryLongVariableCalledB; } } @@ -447,69 +448,69 @@ contract ComparisonOperators { a >= b; a == b; a != b; - veryVeryVeryVeryVeryLongVariableCalledA < - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA > - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA <= - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA >= - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA == - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA != - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + < veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + > veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + <= veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + >= veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + == veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + != veryVeryVeryVeryVeryLongVariableCalledB; a = - veryVeryVeryVeryVeryLongVariableCalledA < - veryVeryVeryVeryVeryLongVariableCalledB; - if ( - veryVeryVeryVeryVeryLongVariableCalledA > - veryVeryVeryVeryVeryLongFunctionB() - ) {} + veryVeryVeryVeryVeryLongVariableCalledA + < veryVeryVeryVeryVeryLongVariableCalledB; if ( - veryVeryVeryVeryVeryLongFunctionB() <= veryVeryVeryVeryVeryLongVariableCalledA + > veryVeryVeryVeryVeryLongFunctionB() ) {} - while ( - veryVeryVeryVeryVeryLongVariableCalledA != + if ( veryVeryVeryVeryVeryLongFunctionB() + <= veryVeryVeryVeryVeryLongVariableCalledA ) {} while ( - veryVeryVeryVeryVeryLongFunctionB() == veryVeryVeryVeryVeryLongVariableCalledA + != veryVeryVeryVeryVeryLongFunctionB() + ) {} + while ( + veryVeryVeryVeryVeryLongFunctionB() + == veryVeryVeryVeryVeryLongVariableCalledA ) {} for ( a = veryVeryVeryVeryVeryLongVariableCalledA; - veryVeryVeryVeryVeryLongVariableCalledB >= - veryVeryVeryVeryVeryLongVariableCalledA; - a += veryVeryVeryVeryVeryLongVariableCalledA || - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledB + >= veryVeryVeryVeryVeryLongVariableCalledA; + a += veryVeryVeryVeryVeryLongVariableCalledA + || veryVeryVeryVeryVeryLongVariableCalledB ? 1 : 2 ) {} a( - veryVeryVeryVeryVeryLongVariableCalledA == - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + == veryVeryVeryVeryVeryLongVariableCalledB ); return - veryVeryVeryVeryVeryLongVariableCalledA == - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + == veryVeryVeryVeryVeryLongVariableCalledB; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB ) == c; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) < - c || - veryVeryVeryVeryVeryLongFunctionCalledA( + ) + < c + || veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) > - d; + ) + > d; a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) == - c; + ) + == c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -542,38 +543,38 @@ contract AssignmentOperators { a /= veryVeryVeryVeryVeryLongVariableCalledA; a %= veryVeryVeryVeryVeryLongVariableCalledA; a = - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a |= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a ^= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a &= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a <<= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a >>= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a += - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a -= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a *= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a /= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); a %= - veryVeryVeryVeryVeryLongVariableCalledA + - veryVeryVeryVeryVeryLongFunctionCalledB(c); + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); } } @@ -583,87 +584,87 @@ contract LogicalOperators { a && b; a || b; a || (b && c) || (d && e); - veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA || - veryVeryVeryVeryVeryLongVariableCalledB; - veryVeryVeryVeryVeryLongVariableCalledA || - (veryVeryVeryVeryVeryLongVariableCalledB && c) || - (d && e); + veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + || veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + || (veryVeryVeryVeryVeryLongVariableCalledB && c) + || (d && e); a = - veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB; if ( - veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB == a() + veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB == a() ) {} if ( - a() == veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB + a() == veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB ) {} if ( - veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB ) {} if ( - (veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB) || c + (veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB) || c ) {} if ( - veryVeryVeryVeryVeryLongVariableCalledA || - (veryVeryVeryVeryVeryLongVariableCalledB && c) + veryVeryVeryVeryVeryLongVariableCalledA + || (veryVeryVeryVeryVeryLongVariableCalledB && c) ) {} while ( - veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB == a() + veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB == a() ) {} while ( - a() == veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB + a() == veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB ) {} while ( - veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB ) {} while ( - (veryVeryVeryVeryVeryLongVariableCalledA && - veryVeryVeryVeryVeryLongVariableCalledB) || c + (veryVeryVeryVeryVeryLongVariableCalledA + && veryVeryVeryVeryVeryLongVariableCalledB) || c ) {} while ( - veryVeryVeryVeryVeryLongVariableCalledA || - (veryVeryVeryVeryVeryLongVariableCalledB && c) + veryVeryVeryVeryVeryLongVariableCalledA + || (veryVeryVeryVeryVeryLongVariableCalledB && c) ) {} for ( a = veryVeryVeryVeryVeryLongVariableCalledA; a <= veryVeryVeryVeryVeryLongVariableCalledA; - a += veryVeryVeryVeryVeryLongVariableCalledA || - veryVeryVeryVeryVeryLongVariableCalledB + a += veryVeryVeryVeryVeryLongVariableCalledA + || veryVeryVeryVeryVeryLongVariableCalledB ? 1 : 2 ) {} a( - veryVeryVeryVeryVeryLongVariableCalledA || - veryVeryVeryVeryVeryLongVariableCalledB + veryVeryVeryVeryVeryLongVariableCalledA + || veryVeryVeryVeryVeryLongVariableCalledB ); return - veryVeryVeryVeryVeryLongVariableCalledA || - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + || veryVeryVeryVeryVeryLongVariableCalledB; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB ) || c; veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) || - (c && - veryVeryVeryVeryVeryLongFunctionCalledA( + ) + || (c + && veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - )) || - d; + )) + || d; a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) || - c; + ) + || c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -684,6 +685,967 @@ contract LogicalOperators { ================================================================================ `; +exports[`BinaryOperators.sol - {"compiler":"0.5.8"} format 1`] = ` +====================================options===================================== +compiler: "0.5.8" +parsers: ["solidity-parse"] +printWidth: 80 + | printWidth +=====================================input====================================== +contract ArithmeticOperators { + // ['+', '-', '*', '/', '%'] + function someFunction() { + a + b; + a - b; + a * b; + a / b; + a % b; + a ** b; + a % b + c - d * e / f ** g; + veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA - veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA * veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA / veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA % veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB - c * d / e % f ** g; + a = veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB; + if (veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB == a()) {} + if (a() == veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB) {} + for (a = veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB; a <= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB; a += veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB) {} + a(veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB); + return veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) + c; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) + c * veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) - d; + a = veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) + c; + if (veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) + c) {} + a(veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) + c); + return veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) + c; + } +} + + +contract ArithmeticOperators { + // ['**'] + function someFunction() { + a ** b; + a ** c * d ** e; + a ** c * d ** e * a ** c * d ** e * a ** c * d ** e * a ** c * d ** e * a ** c * d ** e; + veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA * veryVeryVeryVeryVeryLongVariableCalledB ** c; + c ** veryVeryVeryVeryVeryLongVariableCalledA * veryVeryVeryVeryVeryLongVariableCalledB; + a = veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB; + a = veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB * c; + if (veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB == a()) {} + if (a() == veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB) {} + for (a = veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB; a <= veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB; a += veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB) {} + a(veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB); + return veryVeryVeryVeryVeryLongVariableCalledA ** veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) ** c; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) ** c * veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) ** d; + a = veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) ** c; + if (veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) ** c) {} + a(veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) ** c); + return veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) ** c; + } +} + + +contract ShiftOperators { + // ['<<', '>>'] + function someFunction() { + a << b; + a >> b; + veryVeryVeryVeryVeryLongVariableCalledA << veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA >> veryVeryVeryVeryVeryLongVariableCalledB; + a = veryVeryVeryVeryVeryLongVariableCalledA << veryVeryVeryVeryVeryLongVariableCalledB; + if (veryVeryVeryVeryVeryLongVariableCalledA << veryVeryVeryVeryVeryLongVariableCalledB == a()) {} + if (a() == veryVeryVeryVeryVeryLongVariableCalledA << veryVeryVeryVeryVeryLongVariableCalledB) {} + a(veryVeryVeryVeryVeryLongVariableCalledA << veryVeryVeryVeryVeryLongVariableCalledB); + return veryVeryVeryVeryVeryLongVariableCalledA << veryVeryVeryVeryVeryLongVariableCalledB; + } +} + + +contract BitOperators { + // ['&', '|', '^'] + function someFunction() { + a & b; + a | b; + a ^ b; + veryVeryVeryVeryVeryLongVariableCalledA & veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA | veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA ^ veryVeryVeryVeryVeryLongVariableCalledB; + a = veryVeryVeryVeryVeryLongVariableCalledA & veryVeryVeryVeryVeryLongVariableCalledB; + if (veryVeryVeryVeryVeryLongVariableCalledA & veryVeryVeryVeryVeryLongVariableCalledB == a()) {} + if (a() == veryVeryVeryVeryVeryLongVariableCalledA & veryVeryVeryVeryVeryLongVariableCalledB) {} + a(veryVeryVeryVeryVeryLongVariableCalledA & veryVeryVeryVeryVeryLongVariableCalledB); + return veryVeryVeryVeryVeryLongVariableCalledA & veryVeryVeryVeryVeryLongVariableCalledB; + } +} + + +contract ComparisonOperators { + // ['<', '>', '<=', '>=', '==', '!='] + function someFunction() { + a < b; + a > b; + a <= b; + a >= b; + a == b; + a != b; + veryVeryVeryVeryVeryLongVariableCalledA < veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA > veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA <= veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA >= veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA == veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA != veryVeryVeryVeryVeryLongVariableCalledB; + a = veryVeryVeryVeryVeryLongVariableCalledA < veryVeryVeryVeryVeryLongVariableCalledB; + if (veryVeryVeryVeryVeryLongVariableCalledA > veryVeryVeryVeryVeryLongFunctionB()) {} + if (veryVeryVeryVeryVeryLongFunctionB() <= veryVeryVeryVeryVeryLongVariableCalledA) {} + while (veryVeryVeryVeryVeryLongVariableCalledA != veryVeryVeryVeryVeryLongFunctionB()) {} + while (veryVeryVeryVeryVeryLongFunctionB() == veryVeryVeryVeryVeryLongVariableCalledA) {} + for (a = veryVeryVeryVeryVeryLongVariableCalledA; veryVeryVeryVeryVeryLongVariableCalledB >= veryVeryVeryVeryVeryLongVariableCalledA; a += veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB ? 1:2) {} + a(veryVeryVeryVeryVeryLongVariableCalledA == veryVeryVeryVeryVeryLongVariableCalledB); + return veryVeryVeryVeryVeryLongVariableCalledA == veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) == c; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) < c || veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) > d; + a = veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) == c; + if (veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) == c) {} + a(veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) == c); + return veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) == c; + } +} + + +contract AssignmentOperators { + // ['=', '|=', '^=', '&=', '<<=', '>>=', '+=', '-=', '*=', '/=', '%='] + function someFunction() { + a = veryVeryVeryVeryVeryLongVariableCalledA; + a |= veryVeryVeryVeryVeryLongVariableCalledA; + a ^= veryVeryVeryVeryVeryLongVariableCalledA; + a &= veryVeryVeryVeryVeryLongVariableCalledA; + a <<= veryVeryVeryVeryVeryLongVariableCalledA; + a >>= veryVeryVeryVeryVeryLongVariableCalledA; + a += veryVeryVeryVeryVeryLongVariableCalledA; + a -= veryVeryVeryVeryVeryLongVariableCalledA; + a *= veryVeryVeryVeryVeryLongVariableCalledA; + a /= veryVeryVeryVeryVeryLongVariableCalledA; + a %= veryVeryVeryVeryVeryLongVariableCalledA; + a = veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a |= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a ^= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a &= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a <<= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a >>= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a += veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a -= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a *= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a /= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a %= veryVeryVeryVeryVeryLongVariableCalledA + veryVeryVeryVeryVeryLongFunctionCalledB(c); + } +} + + +contract LogicalOperators { + // ['&&', '||'] + function someFunction() { + a && b; + a || b; + a || b && c || d && e; + veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB && c || d && e; + a = veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB; + if (veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB == a()) {} + if (a() == veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB) {} + if (veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB) {} + if (veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB || c) {} + if (veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB && c) {} + while (veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB == a()) {} + while (a() == veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB) {} + while (veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB) {} + while (veryVeryVeryVeryVeryLongVariableCalledA && veryVeryVeryVeryVeryLongVariableCalledB || c) {} + while (veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB && c) {} + for (a = veryVeryVeryVeryVeryLongVariableCalledA; a <= veryVeryVeryVeryVeryLongVariableCalledA; a += veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB ? 1:2) {} + a(veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB); + return veryVeryVeryVeryVeryLongVariableCalledA || veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) || c; + veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) || c && veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) || d; + a = veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) || c; + if (veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) || c) {} + a(veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) || c); + return veryVeryVeryVeryVeryLongFunctionCalledA(veryVeryVeryVeryVeryLongVariableCalledB) || c; + } +} + +=====================================output===================================== +contract ArithmeticOperators { + // ['+', '-', '*', '/', '%'] + function someFunction() { + a + b; + a - b; + a * b; + a / b; + a % b; + a ** b; + (a % b) + c - (d * e) / f ** g; + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA - + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA * + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA / + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA % + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB - + (((c * d) / e) % f ** g); + a = + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; + if ( + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB == + a() + ) {} + if ( + a() == + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + for ( + a = + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; + a <= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; + a += + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + a( + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB + ); + return + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) + c; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) + + c * + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) - + d; + a = + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) + c; + if ( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) + c + ) {} + a( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) + c + ); + return + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) + c; + } +} + +contract ArithmeticOperators { + // ['**'] + function someFunction() { + a ** b; + a ** c * d ** e; + a ** c * + d ** e * + a ** c * + d ** e * + a ** c * + d ** e * + a ** c * + d ** e * + a ** c * + d ** e; + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA * + veryVeryVeryVeryVeryLongVariableCalledB ** c; + c ** veryVeryVeryVeryVeryLongVariableCalledA * + veryVeryVeryVeryVeryLongVariableCalledB; + a = + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB; + a = + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB * + c; + if ( + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB == + a() + ) {} + if ( + a() == + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + for ( + a = + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB; + a <= + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB; + a += + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + a( + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB + ); + return + veryVeryVeryVeryVeryLongVariableCalledA ** + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) ** c; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) ** + c * + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) ** + d; + a = + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) ** c; + if ( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) ** c + ) {} + a( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) ** c + ); + return + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) ** c; + } +} + +contract ShiftOperators { + // ['<<', '>>'] + function someFunction() { + a << b; + a >> b; + veryVeryVeryVeryVeryLongVariableCalledA << + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA >> + veryVeryVeryVeryVeryLongVariableCalledB; + a = + veryVeryVeryVeryVeryLongVariableCalledA << + veryVeryVeryVeryVeryLongVariableCalledB; + if ( + veryVeryVeryVeryVeryLongVariableCalledA << + veryVeryVeryVeryVeryLongVariableCalledB == + a() + ) {} + if ( + a() == + veryVeryVeryVeryVeryLongVariableCalledA << + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + a( + veryVeryVeryVeryVeryLongVariableCalledA << + veryVeryVeryVeryVeryLongVariableCalledB + ); + return + veryVeryVeryVeryVeryLongVariableCalledA << + veryVeryVeryVeryVeryLongVariableCalledB; + } +} + +contract BitOperators { + // ['&', '|', '^'] + function someFunction() { + a & b; + a | b; + a ^ b; + veryVeryVeryVeryVeryLongVariableCalledA & + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA | + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA ^ + veryVeryVeryVeryVeryLongVariableCalledB; + a = + veryVeryVeryVeryVeryLongVariableCalledA & + veryVeryVeryVeryVeryLongVariableCalledB; + if ( + veryVeryVeryVeryVeryLongVariableCalledA & + veryVeryVeryVeryVeryLongVariableCalledB == + a() + ) {} + if ( + a() == + veryVeryVeryVeryVeryLongVariableCalledA & + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + a( + veryVeryVeryVeryVeryLongVariableCalledA & + veryVeryVeryVeryVeryLongVariableCalledB + ); + return + veryVeryVeryVeryVeryLongVariableCalledA & + veryVeryVeryVeryVeryLongVariableCalledB; + } +} + +contract ComparisonOperators { + // ['<', '>', '<=', '>=', '==', '!='] + function someFunction() { + a < b; + a > b; + a <= b; + a >= b; + a == b; + a != b; + veryVeryVeryVeryVeryLongVariableCalledA < + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA > + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA <= + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA >= + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA == + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA != + veryVeryVeryVeryVeryLongVariableCalledB; + a = + veryVeryVeryVeryVeryLongVariableCalledA < + veryVeryVeryVeryVeryLongVariableCalledB; + if ( + veryVeryVeryVeryVeryLongVariableCalledA > + veryVeryVeryVeryVeryLongFunctionB() + ) {} + if ( + veryVeryVeryVeryVeryLongFunctionB() <= + veryVeryVeryVeryVeryLongVariableCalledA + ) {} + while ( + veryVeryVeryVeryVeryLongVariableCalledA != + veryVeryVeryVeryVeryLongFunctionB() + ) {} + while ( + veryVeryVeryVeryVeryLongFunctionB() == + veryVeryVeryVeryVeryLongVariableCalledA + ) {} + for ( + a = veryVeryVeryVeryVeryLongVariableCalledA; + veryVeryVeryVeryVeryLongVariableCalledB >= + veryVeryVeryVeryVeryLongVariableCalledA; + a += veryVeryVeryVeryVeryLongVariableCalledA || + veryVeryVeryVeryVeryLongVariableCalledB + ? 1 + : 2 + ) {} + a( + veryVeryVeryVeryVeryLongVariableCalledA == + veryVeryVeryVeryVeryLongVariableCalledB + ); + return + veryVeryVeryVeryVeryLongVariableCalledA == + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) == c; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) < + c || + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) > + d; + a = + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) == + c; + if ( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) == c + ) {} + a( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) == c + ); + return + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) == c; + } +} + +contract AssignmentOperators { + // ['=', '|=', '^=', '&=', '<<=', '>>=', '+=', '-=', '*=', '/=', '%='] + function someFunction() { + a = veryVeryVeryVeryVeryLongVariableCalledA; + a |= veryVeryVeryVeryVeryLongVariableCalledA; + a ^= veryVeryVeryVeryVeryLongVariableCalledA; + a &= veryVeryVeryVeryVeryLongVariableCalledA; + a <<= veryVeryVeryVeryVeryLongVariableCalledA; + a >>= veryVeryVeryVeryVeryLongVariableCalledA; + a += veryVeryVeryVeryVeryLongVariableCalledA; + a -= veryVeryVeryVeryVeryLongVariableCalledA; + a *= veryVeryVeryVeryVeryLongVariableCalledA; + a /= veryVeryVeryVeryVeryLongVariableCalledA; + a %= veryVeryVeryVeryVeryLongVariableCalledA; + a = + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a |= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a ^= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a &= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a <<= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a >>= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a += + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a -= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a *= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a /= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + a %= + veryVeryVeryVeryVeryLongVariableCalledA + + veryVeryVeryVeryVeryLongFunctionCalledB(c); + } +} + +contract LogicalOperators { + // ['&&', '||'] + function someFunction() { + a && b; + a || b; + a || (b && c) || (d && e); + veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA || + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongVariableCalledA || + (veryVeryVeryVeryVeryLongVariableCalledB && c) || + (d && e); + a = + veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB; + if ( + veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB == a() + ) {} + if ( + a() == veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + if ( + veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + if ( + (veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB) || c + ) {} + if ( + veryVeryVeryVeryVeryLongVariableCalledA || + (veryVeryVeryVeryVeryLongVariableCalledB && c) + ) {} + while ( + veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB == a() + ) {} + while ( + a() == veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + while ( + veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB + ) {} + while ( + (veryVeryVeryVeryVeryLongVariableCalledA && + veryVeryVeryVeryVeryLongVariableCalledB) || c + ) {} + while ( + veryVeryVeryVeryVeryLongVariableCalledA || + (veryVeryVeryVeryVeryLongVariableCalledB && c) + ) {} + for ( + a = veryVeryVeryVeryVeryLongVariableCalledA; + a <= veryVeryVeryVeryVeryLongVariableCalledA; + a += veryVeryVeryVeryVeryLongVariableCalledA || + veryVeryVeryVeryVeryLongVariableCalledB + ? 1 + : 2 + ) {} + a( + veryVeryVeryVeryVeryLongVariableCalledA || + veryVeryVeryVeryVeryLongVariableCalledB + ); + return + veryVeryVeryVeryVeryLongVariableCalledA || + veryVeryVeryVeryVeryLongVariableCalledB; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) || c; + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) || + (c && + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + )) || + d; + a = + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) || + c; + if ( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) || c + ) {} + a( + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) || c + ); + return + veryVeryVeryVeryVeryLongFunctionCalledA( + veryVeryVeryVeryVeryLongVariableCalledB + ) || c; + } +} + +================================================================================ +`; + +exports[`Parentheses.sol - {"compiler":"0.5.8","experimentalOperatorPosition":"start"} format 1`] = ` +====================================options===================================== +compiler: "0.5.8" +experimentalOperatorPosition: "start" +parsers: ["solidity-parse"] +printWidth: 80 + | printWidth +=====================================input====================================== +pragma solidity 0.5.8; + + +contract Parentheses { + function() { + a + b + c; + a + b - c; + a + b * c; + a + b / c; + a + b % c; + a + b ** c; + a + b << c; + a + b >> c; + a + b & c; + a + b | c; + a + b ^ c; + a - b + c; + a - b - c; + a - b * c; + a - b / c; + a - b % c; + a - b ** c; + a - b << c; + a - b >> c; + a - b & c; + a - b | c; + a - b ^ c; + a * b + c; + a * b - c; + a * b * c; + a * b / c; + a * b % c; + a * b ** c; + a * b << c; + a * b >> c; + a * b & c; + a * b | c; + a * b ^ c; + a / b + c; + a / b - c; + a / b * c; + a / b / c; + a / b % c; + a / b ** c; + a / b << c; + a / b >> c; + a / b & c; + a / b | c; + a / b ^ c; + a % b + c; + a % b - c; + a % b * c; + a % b / c; + a % b % c; + a % b ** c; + a % b << c; + a % b >> c; + a % b & c; + a % b | c; + a % b ^ c; + a ** b + c; + a ** b - c; + a ** b * c; + a ** b / c; + a ** b % c; + a ** b ** c; + a ** b << c; + a ** b >> c; + a ** b & c; + a ** b | c; + a ** b ^ c; + a << b + c; + a << b - c; + a << b * c; + a << b / c; + a << b % c; + a << b ** c; + a << b << c; + a << b >> c; + a << b & c; + a << b | c; + a << b ^ c; + a >> b + c; + a >> b - c; + a >> b * c; + a >> b / c; + a >> b % c; + a >> b ** c; + a >> b << c; + a >> b >> c; + a >> b & c; + a >> b | c; + a >> b ^ c; + a & b + c; + a & b - c; + a & b * c; + a & b / c; + a & b % c; + a & b ** c; + a & b << c; + a & b >> c; + a & b & c; + a & b | c; + a & b ^ c; + a | b + c; + a | b - c; + a | b * c; + a | b / c; + a | b % c; + a | b ** c; + a | b << c; + a | b >> c; + a | b & c; + a | b | c; + a | b ^ c; + a ^ b + c; + a ^ b - c; + a ^ b * c; + a ^ b / c; + a ^ b % c; + a ^ b ** c; + a ^ b << c; + a ^ b >> c; + a ^ b & c; + a ^ b | c; + a ^ b ^ c; + a || b || c; + a || b && c; + a && b || c; + a && b && c; + } +} + +=====================================output===================================== +pragma solidity 0.5.8; + +contract Parentheses { + function() { + a + b + c; + a + b - c; + a + b * c; + a + b / c; + a + (b % c); + a + b ** c; + (a + b) << c; + (a + b) >> c; + (a + b) & c; + (a + b) | c; + (a + b) ^ c; + a - b + c; + a - b - c; + a - b * c; + a - b / c; + a - (b % c); + a - b ** c; + (a - b) << c; + (a - b) >> c; + (a - b) & c; + (a - b) | c; + (a - b) ^ c; + a * b + c; + a * b - c; + a * b * c; + (a * b) / c; + (a * b) % c; + a * b ** c; + (a * b) << c; + (a * b) >> c; + (a * b) & c; + (a * b) | c; + (a * b) ^ c; + a / b + c; + a / b - c; + (a / b) * c; + a / b / c; + (a / b) % c; + a / b ** c; + (a / b) << c; + (a / b) >> c; + (a / b) & c; + (a / b) | c; + (a / b) ^ c; + (a % b) + c; + (a % b) - c; + (a % b) * c; + (a % b) / c; + (a % b) % c; + a % b ** c; + a % b << c; + a % b >> c; + a % b & c; + a % b | c; + a % b ^ c; + a ** b + c; + a ** b - c; + a ** b * c; + a ** b / c; + a ** b % c; + (a ** b) ** c; + (a ** b) << c; + (a ** b) >> c; + (a ** b) & c; + (a ** b) | c; + (a ** b) ^ c; + a << (b + c); + a << (b - c); + a << (b * c); + a << (b / c); + a << b % c; + a << (b ** c); + (a << b) << c; + (a << b) >> c; + (a << b) & c; + (a << b) | c; + (a << b) ^ c; + a >> (b + c); + a >> (b - c); + a >> (b * c); + a >> (b / c); + a >> b % c; + a >> (b ** c); + (a >> b) << c; + (a >> b) >> c; + (a >> b) & c; + (a >> b) | c; + (a >> b) ^ c; + a & (b + c); + a & (b - c); + a & (b * c); + a & (b / c); + a & b % c; + a & (b ** c); + a & (b << c); + a & (b >> c); + a & b & c; + (a & b) | c; + (a & b) ^ c; + a | (b + c); + a | (b - c); + a | (b * c); + a | (b / c); + a | b % c; + a | (b ** c); + a | (b << c); + a | (b >> c); + a | (b & c); + a | b | c; + a | (b ^ c); + a ^ (b + c); + a ^ (b - c); + a ^ (b * c); + a ^ (b / c); + a ^ b % c; + a ^ (b ** c); + a ^ (b << c); + a ^ (b >> c); + a ^ (b & c); + (a ^ b) | c; + a ^ b ^ c; + a || b || c; + a || (b && c); + (a && b) || c; + a && b && c; + } +} + +================================================================================ +`; + exports[`Parentheses.sol - {"compiler":"0.5.8"} format 1`] = ` ====================================options===================================== compiler: "0.5.8" diff --git a/tests/format/BinaryOperators/jsfmt.spec.js b/tests/format/BinaryOperators/jsfmt.spec.js index 946858815..ec876ca43 100644 --- a/tests/format/BinaryOperators/jsfmt.spec.js +++ b/tests/format/BinaryOperators/jsfmt.spec.js @@ -1 +1,5 @@ run_spec(import.meta, ['solidity-parse'], { compiler: '0.5.8' }); +run_spec(import.meta, ['solidity-parse'], { + compiler: '0.5.8', + experimentalOperatorPosition: 'start' +}); From 4ee986d5cbc27c9efee561c40b7c40e100860a55 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 10 Mar 2025 22:19:19 +1300 Subject: [PATCH 05/13] use the same logic for grouping leftover operators in case of an assignment --- src/binary-operator-printers/comparison.js | 8 +------ src/binary-operator-printers/logical.js | 8 +------ .../create-binary-operation-printer.js | 10 +-------- .../printers/right-operand-printer.js | 21 ++++++++++++++----- .../__snapshots__/jsfmt.spec.js.snap | 12 ++++------- 5 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/binary-operator-printers/comparison.js b/src/binary-operator-printers/comparison.js index f27d1a060..7cf12163c 100644 --- a/src/binary-operator-printers/comparison.js +++ b/src/binary-operator-printers/comparison.js @@ -24,15 +24,9 @@ export const comparison = { print: (node, path, print, options) => { const indentIfNecessary = indentIfNecessaryBuilder(path); - const right = rightOperandPrinter(node, path, print, options); - // If it's a single binary operation, avoid having a small right - // operand like - 1 on its own line - const shouldGroup = - node.left.type !== 'BinaryOperation' && - path.getParentNode().type !== 'BinaryOperation'; return group([ path.call(print, 'left'), - indentIfNecessary(shouldGroup ? group(right) : right) + indentIfNecessary(rightOperandPrinter(node, path, print, options)) ]); } }; diff --git a/src/binary-operator-printers/logical.js b/src/binary-operator-printers/logical.js index 3a73c2e3c..18a3a2ede 100644 --- a/src/binary-operator-printers/logical.js +++ b/src/binary-operator-printers/logical.js @@ -31,15 +31,9 @@ export const logical = { const groupIfNecessary = groupIfNecessaryBuilder(path); const indentIfNecessary = indentIfNecessaryBuilder(path, options); - const right = rightOperandPrinter(node, path, print, options); - // If it's a single binary operation, avoid having a small right - // operand like - 1 on its own line - const shouldGroup = - node.left.type !== 'BinaryOperation' && - path.getParentNode().type !== 'BinaryOperation'; return groupIfNecessary([ path.call(print, 'left'), - indentIfNecessary(shouldGroup ? group(right) : right) + indentIfNecessary(rightOperandPrinter(node, path, print, options)) ]); } }; diff --git a/src/binary-operator-printers/printers/create-binary-operation-printer.js b/src/binary-operator-printers/printers/create-binary-operation-printer.js index 6e31720c5..f0206e195 100644 --- a/src/binary-operator-printers/printers/create-binary-operation-printer.js +++ b/src/binary-operator-printers/printers/create-binary-operation-printer.js @@ -1,5 +1,4 @@ import { doc } from 'prettier'; -import { assignment } from '../assignment.js'; import { comparison } from '../comparison.js'; import { rightOperandPrinter } from './right-operand-printer.js'; @@ -46,16 +45,9 @@ export const createBinaryOperationPrinter = const groupIfNecessary = groupIfNecessaryBuilder(path); const indentIfNecessary = indentIfNecessaryBuilder(path); - const right = rightOperandPrinter(node, path, print, options); - // If it's a single binary operation, avoid having a small right - // operand like - 1 on its own line - const parent = path.getParentNode(); - const shouldGroup = - node.left.type !== 'BinaryOperation' && - (parent.type !== 'BinaryOperation' || assignment.match(parent.operator)); return groupIfNecessary([ path.call(print, 'left'), - indentIfNecessary(shouldGroup ? group(right) : right) + indentIfNecessary(rightOperandPrinter(node, path, print, options)) ]); }; diff --git a/src/binary-operator-printers/printers/right-operand-printer.js b/src/binary-operator-printers/printers/right-operand-printer.js index 551e39132..8e21a16c3 100644 --- a/src/binary-operator-printers/printers/right-operand-printer.js +++ b/src/binary-operator-printers/printers/right-operand-printer.js @@ -1,8 +1,19 @@ import { doc } from 'prettier'; +import { assignment } from '../assignment.js'; -const { line } = doc.builders; +const { group, line } = doc.builders; -export const rightOperandPrinter = (node, path, print, options) => - options.experimentalOperatorPosition === 'end' - ? [' ', node.operator, line, path.call(print, 'right')] - : [line, node.operator, ' ', path.call(print, 'right')]; +export const rightOperandPrinter = (node, path, print, options) => { + const right = + options.experimentalOperatorPosition === 'end' + ? [' ', node.operator, line, path.call(print, 'right')] + : [line, node.operator, ' ', path.call(print, 'right')]; + + // If it's a single binary operation, avoid having a small right + // operand like - 1 on its own line + const parent = path.getParentNode(); + return node.left.type !== 'BinaryOperation' && + (parent.type !== 'BinaryOperation' || assignment.match(parent.operator)) + ? group(right) + : right; +}; diff --git a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap index 032b0f698..a44a77ee3 100644 --- a/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperators/__snapshots__/jsfmt.spec.js.snap @@ -509,8 +509,7 @@ contract ComparisonOperators { a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) - == c; + ) == c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -663,8 +662,7 @@ contract LogicalOperators { a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) - || c; + ) || c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -1193,8 +1191,7 @@ contract ComparisonOperators { a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) == - c; + ) == c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB @@ -1347,8 +1344,7 @@ contract LogicalOperators { a = veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB - ) || - c; + ) || c; if ( veryVeryVeryVeryVeryLongFunctionCalledA( veryVeryVeryVeryVeryLongVariableCalledB From 574787e61bf00122d0115b3ace8ac07fe30eb330 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 03:30:53 +1300 Subject: [PATCH 06/13] Separate comparison into `equality` and `inequality` since inequality has precedence over equality --- src/binary-operator-printers/comparison.js | 32 ------------------- src/binary-operator-printers/equality.js | 14 ++++++++ .../exponentiation.js | 4 +++ src/binary-operator-printers/index.js | 3 +- src/binary-operator-printers/inequality.js | 15 +++++++++ .../multiplication.js | 4 ++- .../create-binary-operation-printer.js | 30 ++++++----------- .../create-comparison-operation-printer.js | 30 +++++++++++++++++ .../utils/should-group-or-indent.js | 3 ++ .../__snapshots__/jsfmt.spec.js.snap | 32 +++++++++---------- .../__snapshots__/index.test.js.snap | 3 +- 11 files changed, 98 insertions(+), 72 deletions(-) delete mode 100644 src/binary-operator-printers/comparison.js create mode 100644 src/binary-operator-printers/equality.js create mode 100644 src/binary-operator-printers/inequality.js create mode 100644 src/binary-operator-printers/printers/create-comparison-operation-printer.js create mode 100644 src/binary-operator-printers/utils/should-group-or-indent.js diff --git a/src/binary-operator-printers/comparison.js b/src/binary-operator-printers/comparison.js deleted file mode 100644 index 7cf12163c..000000000 --- a/src/binary-operator-printers/comparison.js +++ /dev/null @@ -1,32 +0,0 @@ -import { doc } from 'prettier'; -import { rightOperandPrinter } from './printers/right-operand-printer.js'; -import { logical } from './logical.js'; - -const { group, indent } = doc.builders; - -const indentIfNecessaryBuilder = (path) => (document) => { - let node = path.getNode(); - for (let i = 0; ; i += 1) { - const parentNode = path.getParentNode(i); - if (parentNode.type === 'ReturnStatement') return document; - if (parentNode.type === 'IfStatement') return document; - if (parentNode.type === 'ForStatement') return document; - if (parentNode.type === 'WhileStatement') return document; - if (parentNode.type !== 'BinaryOperation') return indent(document); - if (logical.match(parentNode.operator)) return indent(document); - if (node === parentNode.right) return document; - node = parentNode; - } -}; - -export const comparison = { - match: (op) => ['<', '>', '<=', '>=', '==', '!='].includes(op), - print: (node, path, print, options) => { - const indentIfNecessary = indentIfNecessaryBuilder(path); - - return group([ - path.call(print, 'left'), - indentIfNecessary(rightOperandPrinter(node, path, print, options)) - ]); - } -}; diff --git a/src/binary-operator-printers/equality.js b/src/binary-operator-printers/equality.js new file mode 100644 index 000000000..acb607b47 --- /dev/null +++ b/src/binary-operator-printers/equality.js @@ -0,0 +1,14 @@ +import { + createComparisonOperationPrinter, + createIndentIfNecessaryBuilder +} from './printers/create-comparison-operation-printer.js'; +import { logical } from './logical.js'; + +const equalityPrinter = createComparisonOperationPrinter( + createIndentIfNecessaryBuilder([logical]) +); + +export const equality = { + match: (op) => ['==', '!='].includes(op), + print: equalityPrinter +}; diff --git a/src/binary-operator-printers/exponentiation.js b/src/binary-operator-printers/exponentiation.js index b06632bc2..9b7968970 100644 --- a/src/binary-operator-printers/exponentiation.js +++ b/src/binary-operator-printers/exponentiation.js @@ -4,6 +4,8 @@ import { createIndentIfNecessaryBuilder } from './printers/create-binary-operation-printer.js'; import { addition } from './addition.js'; +import { equality } from './equality.js'; +import { inequality } from './inequality.js'; import { multiplication } from './multiplication.js'; const { group } = doc.builders; @@ -12,6 +14,8 @@ const exponentiationPrinter = createBinaryOperationPrinter( () => (document) => group(document), // always group createIndentIfNecessaryBuilder([ addition, + equality, + inequality, multiplication // `bit` and `shift` should technically be here but they are properly // parenthesised before reaching this point. diff --git a/src/binary-operator-printers/index.js b/src/binary-operator-printers/index.js index 50871f42a..21f4b91d0 100644 --- a/src/binary-operator-printers/index.js +++ b/src/binary-operator-printers/index.js @@ -1,8 +1,9 @@ export * from './addition.js'; export * from './assignment.js'; export * from './bit.js'; -export * from './comparison.js'; +export * from './equality.js'; export * from './exponentiation.js'; +export * from './inequality.js'; export * from './logical.js'; export * from './multiplication.js'; export * from './shift.js'; diff --git a/src/binary-operator-printers/inequality.js b/src/binary-operator-printers/inequality.js new file mode 100644 index 000000000..244ad1f66 --- /dev/null +++ b/src/binary-operator-printers/inequality.js @@ -0,0 +1,15 @@ +import { + createComparisonOperationPrinter, + createIndentIfNecessaryBuilder +} from './printers/create-comparison-operation-printer.js'; +import { logical } from './logical.js'; +import { equality } from './equality.js'; + +const inequalityPrinter = createComparisonOperationPrinter( + createIndentIfNecessaryBuilder([logical, equality]) +); + +export const inequality = { + match: (op) => ['<', '>', '<=', '>='].includes(op), + print: inequalityPrinter +}; diff --git a/src/binary-operator-printers/multiplication.js b/src/binary-operator-printers/multiplication.js index f08cd1d1d..37e216c11 100644 --- a/src/binary-operator-printers/multiplication.js +++ b/src/binary-operator-printers/multiplication.js @@ -5,9 +5,11 @@ import { } from './printers/create-binary-operation-printer.js'; import { addition } from './addition.js'; import { bit } from './bit.js'; +import { equality } from './equality.js'; +import { inequality } from './inequality.js'; import { shift } from './shift.js'; -const matchers = [addition, bit, shift]; +const matchers = [addition, bit, equality, inequality, shift]; const multiplicationPrinter = createBinaryOperationPrinter( createGroupIfNecessaryBuilder(matchers), diff --git a/src/binary-operator-printers/printers/create-binary-operation-printer.js b/src/binary-operator-printers/printers/create-binary-operation-printer.js index f0206e195..5dfc40e01 100644 --- a/src/binary-operator-printers/printers/create-binary-operation-printer.js +++ b/src/binary-operator-printers/printers/create-binary-operation-printer.js @@ -1,24 +1,18 @@ import { doc } from 'prettier'; -import { comparison } from '../comparison.js'; +import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; +import { equality } from '../equality.js'; +import { inequality } from '../inequality.js'; import { rightOperandPrinter } from './right-operand-printer.js'; const { group, indent } = doc.builders; -const shouldGroupOrIndent = (node, matchers) => - matchers.some((matcher) => matcher.match(node.operator)); +const comparisonMatchers = [equality, inequality]; export const createGroupIfNecessaryBuilder = (matchers) => (path) => (document) => { const parentNode = path.getParentNode(); - if ( - parentNode.type === 'BinaryOperation' && - !comparison.match(parentNode.operator) - ) { - return shouldGroupOrIndent(parentNode, matchers) - ? group(document) - : document; - } - return group(document); + if (shouldGroupOrIndent(parentNode, matchers)) return group(document); + return document; }; export const createIndentIfNecessaryBuilder = @@ -27,13 +21,7 @@ export const createIndentIfNecessaryBuilder = for (let i = 0; ; i += 1) { const parentNode = path.getParentNode(i); if (parentNode.type === 'ReturnStatement') return document; - if ( - parentNode.type !== 'BinaryOperation' || - comparison.match(parentNode.operator) || - shouldGroupOrIndent(parentNode, matchers) - ) { - return indent(document); - } + if (shouldGroupOrIndent(parentNode, matchers)) return indent(document); if (node === parentNode.right) return document; node = parentNode; } @@ -52,6 +40,6 @@ export const createBinaryOperationPrinter = }; export const defaultBinaryOperationPrinter = createBinaryOperationPrinter( - createGroupIfNecessaryBuilder([]), - createIndentIfNecessaryBuilder([]) + createGroupIfNecessaryBuilder(comparisonMatchers), + createIndentIfNecessaryBuilder(comparisonMatchers) ); diff --git a/src/binary-operator-printers/printers/create-comparison-operation-printer.js b/src/binary-operator-printers/printers/create-comparison-operation-printer.js new file mode 100644 index 000000000..ae719ecd4 --- /dev/null +++ b/src/binary-operator-printers/printers/create-comparison-operation-printer.js @@ -0,0 +1,30 @@ +import { doc } from 'prettier'; +import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; +import { rightOperandPrinter } from './right-operand-printer.js'; + +const { group, indent } = doc.builders; + +export const createIndentIfNecessaryBuilder = + (matchers) => (path) => (document) => { + let node = path.getNode(); + for (let i = 0; ; i += 1) { + const parentNode = path.getParentNode(i); + if (parentNode.type === 'ReturnStatement') return document; + if (parentNode.type === 'IfStatement') return document; + if (parentNode.type === 'ForStatement') return document; + if (parentNode.type === 'WhileStatement') return document; + if (shouldGroupOrIndent(parentNode, matchers)) return indent(document); + if (node === parentNode.right) return document; + node = parentNode; + } + }; + +export const createComparisonOperationPrinter = + (indentIfNecessaryBuilder) => (node, path, print, options) => { + const indentIfNecessary = indentIfNecessaryBuilder(path); + + return group([ + path.call(print, 'left'), + indentIfNecessary(rightOperandPrinter(node, path, print, options)) + ]); + }; diff --git a/src/binary-operator-printers/utils/should-group-or-indent.js b/src/binary-operator-printers/utils/should-group-or-indent.js new file mode 100644 index 000000000..9a5c4d6db --- /dev/null +++ b/src/binary-operator-printers/utils/should-group-or-indent.js @@ -0,0 +1,3 @@ +export const shouldGroupOrIndent = ({ type, operator }, matchers) => + type !== 'BinaryOperation' || + matchers.some((matcher) => matcher.match(operator)); diff --git a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap index 15dd20e47..10a55638e 100644 --- a/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/BinaryOperationHierarchy/__snapshots__/jsfmt.spec.js.snap @@ -2507,19 +2507,19 @@ contract Indent { resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == veryVeryVeryExtremelyExtremelyLongUint256B < - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == veryVeryVeryExtremelyExtremelyLongUint256B <= - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == veryVeryVeryExtremelyExtremelyLongUint256B > - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == veryVeryVeryExtremelyExtremelyLongUint256B >= - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; } function notEqual() public { @@ -2578,19 +2578,19 @@ contract Indent { resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != veryVeryVeryExtremelyExtremelyLongUint256B < - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != veryVeryVeryExtremelyExtremelyLongUint256B <= - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != veryVeryVeryExtremelyExtremelyLongUint256B > - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != veryVeryVeryExtremelyExtremelyLongUint256B >= - veryVeryVeryExtremelyExtremelyLongUint256C; + veryVeryVeryExtremelyExtremelyLongUint256C; } function lessThan() public { @@ -2640,11 +2640,11 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A < - veryVeryVeryExtremelyExtremelyLongUint256B == + veryVeryVeryExtremelyExtremelyLongUint256B == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A < - veryVeryVeryExtremelyExtremelyLongUint256B != + veryVeryVeryExtremelyExtremelyLongUint256B != veryVeryVeryExtremelyExtremelyLongBooleanC; } @@ -2695,11 +2695,11 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A <= - veryVeryVeryExtremelyExtremelyLongUint256B == + veryVeryVeryExtremelyExtremelyLongUint256B == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A <= - veryVeryVeryExtremelyExtremelyLongUint256B != + veryVeryVeryExtremelyExtremelyLongUint256B != veryVeryVeryExtremelyExtremelyLongBooleanC; } @@ -2750,11 +2750,11 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A > - veryVeryVeryExtremelyExtremelyLongUint256B == + veryVeryVeryExtremelyExtremelyLongUint256B == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A > - veryVeryVeryExtremelyExtremelyLongUint256B != + veryVeryVeryExtremelyExtremelyLongUint256B != veryVeryVeryExtremelyExtremelyLongBooleanC; } @@ -2805,11 +2805,11 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A >= - veryVeryVeryExtremelyExtremelyLongUint256B == + veryVeryVeryExtremelyExtremelyLongUint256B == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongUint256A >= - veryVeryVeryExtremelyExtremelyLongUint256B != + veryVeryVeryExtremelyExtremelyLongUint256B != veryVeryVeryExtremelyExtremelyLongBooleanC; } diff --git a/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap b/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap index d626cc27b..e7286bd0a 100644 --- a/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap +++ b/tests/unit/binary-operator-printers/__snapshots__/index.test.js.snap @@ -5,8 +5,9 @@ exports[`binary operators printers to match snapshot 1`] = ` "addition", "assignment", "bit", - "comparison", + "equality", "exponentiation", + "inequality", "logical", "multiplication", "shift", From 2ca26f1aa0f582ec342733e8eb8db07ca3ad59a1 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 12:16:39 +1300 Subject: [PATCH 07/13] cleanup and passing tests --- src/binary-operator-printers/addition.js | 2 +- src/binary-operator-printers/bit.js | 2 +- src/binary-operator-printers/equality.js | 14 ++++---- .../exponentiation.js | 8 ++--- src/binary-operator-printers/inequality.js | 14 ++++---- .../multiplication.js | 12 +++---- .../create-binary-operation-printer.js | 32 ------------------- .../create-comparison-operation-printer.js | 30 ----------------- .../create-group-if-necessary-builder.js | 11 +++++++ .../create-indent-if-necessary-builder.js | 28 ++++++++++++++++ .../default-binary-operation-printer.js | 12 +++++++ src/binary-operator-printers/shift.js | 2 +- 12 files changed, 78 insertions(+), 89 deletions(-) delete mode 100644 src/binary-operator-printers/printers/create-comparison-operation-printer.js create mode 100644 src/binary-operator-printers/printers/create-group-if-necessary-builder.js create mode 100644 src/binary-operator-printers/printers/create-indent-if-necessary-builder.js create mode 100644 src/binary-operator-printers/printers/default-binary-operation-printer.js diff --git a/src/binary-operator-printers/addition.js b/src/binary-operator-printers/addition.js index 72b8ee9f3..457a3feb2 100644 --- a/src/binary-operator-printers/addition.js +++ b/src/binary-operator-printers/addition.js @@ -1,4 +1,4 @@ -import { defaultBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { defaultBinaryOperationPrinter } from './printers/default-binary-operation-printer.js'; export const addition = { match: (op) => ['+', '-'].includes(op), diff --git a/src/binary-operator-printers/bit.js b/src/binary-operator-printers/bit.js index 6664a3a5f..51e8958e4 100644 --- a/src/binary-operator-printers/bit.js +++ b/src/binary-operator-printers/bit.js @@ -1,4 +1,4 @@ -import { defaultBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { defaultBinaryOperationPrinter } from './printers/default-binary-operation-printer.js'; export const bit = { match: (op) => ['&', '|', '^'].includes(op), diff --git a/src/binary-operator-printers/equality.js b/src/binary-operator-printers/equality.js index acb607b47..c60c1ab9d 100644 --- a/src/binary-operator-printers/equality.js +++ b/src/binary-operator-printers/equality.js @@ -1,11 +1,13 @@ -import { - createComparisonOperationPrinter, - createIndentIfNecessaryBuilder -} from './printers/create-comparison-operation-printer.js'; +import { doc } from 'prettier'; +import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createComparisonIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { logical } from './logical.js'; -const equalityPrinter = createComparisonOperationPrinter( - createIndentIfNecessaryBuilder([logical]) +const { group } = doc.builders; + +const equalityPrinter = createBinaryOperationPrinter( + () => (document) => group(document), // always group + createComparisonIndentIfNecessaryBuilder([logical]) ); export const equality = { diff --git a/src/binary-operator-printers/exponentiation.js b/src/binary-operator-printers/exponentiation.js index 9b7968970..9ff2779e1 100644 --- a/src/binary-operator-printers/exponentiation.js +++ b/src/binary-operator-printers/exponentiation.js @@ -1,8 +1,6 @@ import { doc } from 'prettier'; -import { - createBinaryOperationPrinter, - createIndentIfNecessaryBuilder -} from './printers/create-binary-operation-printer.js'; +import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createArithmeticIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { addition } from './addition.js'; import { equality } from './equality.js'; import { inequality } from './inequality.js'; @@ -12,7 +10,7 @@ const { group } = doc.builders; const exponentiationPrinter = createBinaryOperationPrinter( () => (document) => group(document), // always group - createIndentIfNecessaryBuilder([ + createArithmeticIndentIfNecessaryBuilder([ addition, equality, inequality, diff --git a/src/binary-operator-printers/inequality.js b/src/binary-operator-printers/inequality.js index 244ad1f66..310c9812e 100644 --- a/src/binary-operator-printers/inequality.js +++ b/src/binary-operator-printers/inequality.js @@ -1,12 +1,14 @@ -import { - createComparisonOperationPrinter, - createIndentIfNecessaryBuilder -} from './printers/create-comparison-operation-printer.js'; +import { doc } from 'prettier'; +import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createComparisonIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { logical } from './logical.js'; import { equality } from './equality.js'; -const inequalityPrinter = createComparisonOperationPrinter( - createIndentIfNecessaryBuilder([logical, equality]) +const { group } = doc.builders; + +const inequalityPrinter = createBinaryOperationPrinter( + () => (document) => group(document), // always group + createComparisonIndentIfNecessaryBuilder([logical, equality]) ); export const inequality = { diff --git a/src/binary-operator-printers/multiplication.js b/src/binary-operator-printers/multiplication.js index 37e216c11..ddc2ef151 100644 --- a/src/binary-operator-printers/multiplication.js +++ b/src/binary-operator-printers/multiplication.js @@ -1,8 +1,6 @@ -import { - createBinaryOperationPrinter, - createGroupIfNecessaryBuilder, - createIndentIfNecessaryBuilder -} from './printers/create-binary-operation-printer.js'; +import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createArithmeticGroupIfNecessaryBuilder } from './printers/create-group-if-necessary-builder.js'; +import { createArithmeticIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { addition } from './addition.js'; import { bit } from './bit.js'; import { equality } from './equality.js'; @@ -12,8 +10,8 @@ import { shift } from './shift.js'; const matchers = [addition, bit, equality, inequality, shift]; const multiplicationPrinter = createBinaryOperationPrinter( - createGroupIfNecessaryBuilder(matchers), - createIndentIfNecessaryBuilder(matchers) + createArithmeticGroupIfNecessaryBuilder(matchers), + createArithmeticIndentIfNecessaryBuilder(matchers) ); export const multiplication = { diff --git a/src/binary-operator-printers/printers/create-binary-operation-printer.js b/src/binary-operator-printers/printers/create-binary-operation-printer.js index 5dfc40e01..0707d585d 100644 --- a/src/binary-operator-printers/printers/create-binary-operation-printer.js +++ b/src/binary-operator-printers/printers/create-binary-operation-printer.js @@ -1,32 +1,5 @@ -import { doc } from 'prettier'; -import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; -import { equality } from '../equality.js'; -import { inequality } from '../inequality.js'; import { rightOperandPrinter } from './right-operand-printer.js'; -const { group, indent } = doc.builders; - -const comparisonMatchers = [equality, inequality]; - -export const createGroupIfNecessaryBuilder = - (matchers) => (path) => (document) => { - const parentNode = path.getParentNode(); - if (shouldGroupOrIndent(parentNode, matchers)) return group(document); - return document; - }; - -export const createIndentIfNecessaryBuilder = - (matchers) => (path) => (document) => { - let node = path.getNode(); - for (let i = 0; ; i += 1) { - const parentNode = path.getParentNode(i); - if (parentNode.type === 'ReturnStatement') return document; - if (shouldGroupOrIndent(parentNode, matchers)) return indent(document); - if (node === parentNode.right) return document; - node = parentNode; - } - }; - export const createBinaryOperationPrinter = (groupIfNecessaryBuilder, indentIfNecessaryBuilder) => (node, path, print, options) => { @@ -38,8 +11,3 @@ export const createBinaryOperationPrinter = indentIfNecessary(rightOperandPrinter(node, path, print, options)) ]); }; - -export const defaultBinaryOperationPrinter = createBinaryOperationPrinter( - createGroupIfNecessaryBuilder(comparisonMatchers), - createIndentIfNecessaryBuilder(comparisonMatchers) -); diff --git a/src/binary-operator-printers/printers/create-comparison-operation-printer.js b/src/binary-operator-printers/printers/create-comparison-operation-printer.js deleted file mode 100644 index ae719ecd4..000000000 --- a/src/binary-operator-printers/printers/create-comparison-operation-printer.js +++ /dev/null @@ -1,30 +0,0 @@ -import { doc } from 'prettier'; -import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; -import { rightOperandPrinter } from './right-operand-printer.js'; - -const { group, indent } = doc.builders; - -export const createIndentIfNecessaryBuilder = - (matchers) => (path) => (document) => { - let node = path.getNode(); - for (let i = 0; ; i += 1) { - const parentNode = path.getParentNode(i); - if (parentNode.type === 'ReturnStatement') return document; - if (parentNode.type === 'IfStatement') return document; - if (parentNode.type === 'ForStatement') return document; - if (parentNode.type === 'WhileStatement') return document; - if (shouldGroupOrIndent(parentNode, matchers)) return indent(document); - if (node === parentNode.right) return document; - node = parentNode; - } - }; - -export const createComparisonOperationPrinter = - (indentIfNecessaryBuilder) => (node, path, print, options) => { - const indentIfNecessary = indentIfNecessaryBuilder(path); - - return group([ - path.call(print, 'left'), - indentIfNecessary(rightOperandPrinter(node, path, print, options)) - ]); - }; diff --git a/src/binary-operator-printers/printers/create-group-if-necessary-builder.js b/src/binary-operator-printers/printers/create-group-if-necessary-builder.js new file mode 100644 index 000000000..707458129 --- /dev/null +++ b/src/binary-operator-printers/printers/create-group-if-necessary-builder.js @@ -0,0 +1,11 @@ +import { doc } from 'prettier'; +import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; + +const { group } = doc.builders; + +export const createArithmeticGroupIfNecessaryBuilder = + (matchers) => (path) => (document) => { + const parentNode = path.getParentNode(); + if (shouldGroupOrIndent(parentNode, matchers)) return group(document); + return document; + }; diff --git a/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js b/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js new file mode 100644 index 000000000..dcb979c7a --- /dev/null +++ b/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js @@ -0,0 +1,28 @@ +import { doc } from 'prettier'; +import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; + +const { indent } = doc.builders; + +const createIndentIfNecessaryBuilder = + (notIndentParentTypes) => (shouldIndentMatchers) => (path) => (document) => { + let node = path.getNode(); + for (let i = 0; ; i += 1) { + const parentNode = path.getParentNode(i); + if (notIndentParentTypes.includes(parentNode.type)) return document; + if (shouldGroupOrIndent(parentNode, shouldIndentMatchers)) + return indent(document); + if (node === parentNode.right) return document; + node = parentNode; + } + }; + +export const createArithmeticIndentIfNecessaryBuilder = + createIndentIfNecessaryBuilder(['ReturnStatement']); + +export const createComparisonIndentIfNecessaryBuilder = + createIndentIfNecessaryBuilder([ + 'ReturnStatement', + 'IfStatement', + 'ForStatement', + 'WhileStatement' + ]); diff --git a/src/binary-operator-printers/printers/default-binary-operation-printer.js b/src/binary-operator-printers/printers/default-binary-operation-printer.js new file mode 100644 index 000000000..5af098740 --- /dev/null +++ b/src/binary-operator-printers/printers/default-binary-operation-printer.js @@ -0,0 +1,12 @@ +import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; +import { createArithmeticGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; +import { createArithmeticIndentIfNecessaryBuilder } from './create-indent-if-necessary-builder.js'; +import { equality } from '../equality.js'; +import { inequality } from '../inequality.js'; + +const comparisonMatchers = [equality, inequality]; + +export const defaultBinaryOperationPrinter = createBinaryOperationPrinter( + createArithmeticGroupIfNecessaryBuilder(comparisonMatchers), + createArithmeticIndentIfNecessaryBuilder(comparisonMatchers) +); diff --git a/src/binary-operator-printers/shift.js b/src/binary-operator-printers/shift.js index 7ea0ca436..32527da11 100644 --- a/src/binary-operator-printers/shift.js +++ b/src/binary-operator-printers/shift.js @@ -1,4 +1,4 @@ -import { defaultBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { defaultBinaryOperationPrinter } from './printers/default-binary-operation-printer.js'; export const shift = { match: (op) => ['<<', '>>'].includes(op), From 6984e42d7aae5fedf71fa54ae7f7fe8fce71c0a4 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 14:43:27 +1300 Subject: [PATCH 08/13] using the same pattern we developed for the logical operators as well --- src/binary-operator-printers/logical.js | 23 ++++++++----------- .../multiplication.js | 4 ++-- .../create-binary-operation-printer.js | 2 +- .../create-group-if-necessary-builder.js | 2 +- .../default-binary-operation-printer.js | 4 ++-- 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/binary-operator-printers/logical.js b/src/binary-operator-printers/logical.js index 18a3a2ede..c55dd7da4 100644 --- a/src/binary-operator-printers/logical.js +++ b/src/binary-operator-printers/logical.js @@ -1,10 +1,8 @@ import { doc } from 'prettier'; -import { rightOperandPrinter } from './printers/right-operand-printer.js'; +import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createGroupIfNecessaryBuilder } from './printers/create-group-if-necessary-builder.js'; -const { group, indent } = doc.builders; - -const groupIfNecessaryBuilder = (path) => (document) => - path.getParentNode().type === 'BinaryOperation' ? document : group(document); +const { indent } = doc.builders; const indentIfNecessaryBuilder = (path, options) => (document) => { let node = path.getNode(); @@ -25,15 +23,12 @@ const indentIfNecessaryBuilder = (path, options) => (document) => { } }; +const logicalPrinter = createBinaryOperationPrinter( + createGroupIfNecessaryBuilder([]), + indentIfNecessaryBuilder +); + export const logical = { match: (op) => ['&&', '||'].includes(op), - print: (node, path, print, options) => { - const groupIfNecessary = groupIfNecessaryBuilder(path); - const indentIfNecessary = indentIfNecessaryBuilder(path, options); - - return groupIfNecessary([ - path.call(print, 'left'), - indentIfNecessary(rightOperandPrinter(node, path, print, options)) - ]); - } + print: logicalPrinter }; diff --git a/src/binary-operator-printers/multiplication.js b/src/binary-operator-printers/multiplication.js index ddc2ef151..0efa0204d 100644 --- a/src/binary-operator-printers/multiplication.js +++ b/src/binary-operator-printers/multiplication.js @@ -1,5 +1,5 @@ import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; -import { createArithmeticGroupIfNecessaryBuilder } from './printers/create-group-if-necessary-builder.js'; +import { createGroupIfNecessaryBuilder } from './printers/create-group-if-necessary-builder.js'; import { createArithmeticIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { addition } from './addition.js'; import { bit } from './bit.js'; @@ -10,7 +10,7 @@ import { shift } from './shift.js'; const matchers = [addition, bit, equality, inequality, shift]; const multiplicationPrinter = createBinaryOperationPrinter( - createArithmeticGroupIfNecessaryBuilder(matchers), + createGroupIfNecessaryBuilder(matchers), createArithmeticIndentIfNecessaryBuilder(matchers) ); diff --git a/src/binary-operator-printers/printers/create-binary-operation-printer.js b/src/binary-operator-printers/printers/create-binary-operation-printer.js index 0707d585d..8428f8811 100644 --- a/src/binary-operator-printers/printers/create-binary-operation-printer.js +++ b/src/binary-operator-printers/printers/create-binary-operation-printer.js @@ -4,7 +4,7 @@ export const createBinaryOperationPrinter = (groupIfNecessaryBuilder, indentIfNecessaryBuilder) => (node, path, print, options) => { const groupIfNecessary = groupIfNecessaryBuilder(path); - const indentIfNecessary = indentIfNecessaryBuilder(path); + const indentIfNecessary = indentIfNecessaryBuilder(path, options); return groupIfNecessary([ path.call(print, 'left'), diff --git a/src/binary-operator-printers/printers/create-group-if-necessary-builder.js b/src/binary-operator-printers/printers/create-group-if-necessary-builder.js index 707458129..535d3db49 100644 --- a/src/binary-operator-printers/printers/create-group-if-necessary-builder.js +++ b/src/binary-operator-printers/printers/create-group-if-necessary-builder.js @@ -3,7 +3,7 @@ import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; const { group } = doc.builders; -export const createArithmeticGroupIfNecessaryBuilder = +export const createGroupIfNecessaryBuilder = (matchers) => (path) => (document) => { const parentNode = path.getParentNode(); if (shouldGroupOrIndent(parentNode, matchers)) return group(document); diff --git a/src/binary-operator-printers/printers/default-binary-operation-printer.js b/src/binary-operator-printers/printers/default-binary-operation-printer.js index 5af098740..59db1c1c6 100644 --- a/src/binary-operator-printers/printers/default-binary-operation-printer.js +++ b/src/binary-operator-printers/printers/default-binary-operation-printer.js @@ -1,5 +1,5 @@ import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; -import { createArithmeticGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; +import { createGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; import { createArithmeticIndentIfNecessaryBuilder } from './create-indent-if-necessary-builder.js'; import { equality } from '../equality.js'; import { inequality } from '../inequality.js'; @@ -7,6 +7,6 @@ import { inequality } from '../inequality.js'; const comparisonMatchers = [equality, inequality]; export const defaultBinaryOperationPrinter = createBinaryOperationPrinter( - createArithmeticGroupIfNecessaryBuilder(comparisonMatchers), + createGroupIfNecessaryBuilder(comparisonMatchers), createArithmeticIndentIfNecessaryBuilder(comparisonMatchers) ); From ba0bc676e02aaf78b05528ff35162eb54b001d35 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 14:59:35 +1300 Subject: [PATCH 09/13] moving the always grouped behaviour to it's own function --- src/binary-operator-printers/equality.js | 8 ++------ src/binary-operator-printers/exponentiation.js | 8 ++------ src/binary-operator-printers/inequality.js | 8 ++------ .../create-grouped-binary-operation-printer.js | 10 ++++++++++ 4 files changed, 16 insertions(+), 18 deletions(-) create mode 100644 src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js diff --git a/src/binary-operator-printers/equality.js b/src/binary-operator-printers/equality.js index c60c1ab9d..01693be5c 100644 --- a/src/binary-operator-printers/equality.js +++ b/src/binary-operator-printers/equality.js @@ -1,12 +1,8 @@ -import { doc } from 'prettier'; -import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createGroupedBinaryOperationPrinter } from './printers/create-grouped-binary-operation-printer.js'; import { createComparisonIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { logical } from './logical.js'; -const { group } = doc.builders; - -const equalityPrinter = createBinaryOperationPrinter( - () => (document) => group(document), // always group +const equalityPrinter = createGroupedBinaryOperationPrinter( createComparisonIndentIfNecessaryBuilder([logical]) ); diff --git a/src/binary-operator-printers/exponentiation.js b/src/binary-operator-printers/exponentiation.js index 9ff2779e1..57974640d 100644 --- a/src/binary-operator-printers/exponentiation.js +++ b/src/binary-operator-printers/exponentiation.js @@ -1,15 +1,11 @@ -import { doc } from 'prettier'; -import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createGroupedBinaryOperationPrinter } from './printers/create-grouped-binary-operation-printer.js'; import { createArithmeticIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { addition } from './addition.js'; import { equality } from './equality.js'; import { inequality } from './inequality.js'; import { multiplication } from './multiplication.js'; -const { group } = doc.builders; - -const exponentiationPrinter = createBinaryOperationPrinter( - () => (document) => group(document), // always group +const exponentiationPrinter = createGroupedBinaryOperationPrinter( createArithmeticIndentIfNecessaryBuilder([ addition, equality, diff --git a/src/binary-operator-printers/inequality.js b/src/binary-operator-printers/inequality.js index 310c9812e..e26eca36b 100644 --- a/src/binary-operator-printers/inequality.js +++ b/src/binary-operator-printers/inequality.js @@ -1,13 +1,9 @@ -import { doc } from 'prettier'; -import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createGroupedBinaryOperationPrinter } from './printers/create-grouped-binary-operation-printer.js'; import { createComparisonIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { logical } from './logical.js'; import { equality } from './equality.js'; -const { group } = doc.builders; - -const inequalityPrinter = createBinaryOperationPrinter( - () => (document) => group(document), // always group +const inequalityPrinter = createGroupedBinaryOperationPrinter( createComparisonIndentIfNecessaryBuilder([logical, equality]) ); diff --git a/src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js b/src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js new file mode 100644 index 000000000..b09b7edbd --- /dev/null +++ b/src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js @@ -0,0 +1,10 @@ +import { doc } from 'prettier'; +import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; + +const { group } = doc.builders; + +export const createGroupedBinaryOperationPrinter = (indentIfNecessaryBuilder) => + createBinaryOperationPrinter( + () => (document) => group(document), // always group + indentIfNecessaryBuilder + ); From 34ed20d9e9000d29d2326825898ee482a1aa4ee6 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 11 Mar 2025 16:41:50 +1300 Subject: [PATCH 10/13] Standardising the printers so that we can review at every level what are the binary operations that that should force grouping and indentation --- src/binary-operator-printers/addition.js | 11 +++--- src/binary-operator-printers/bit.js | 7 ++-- src/binary-operator-printers/equality.js | 9 ++--- .../exponentiation.js | 36 +++++++++++-------- src/binary-operator-printers/inequality.js | 9 ++--- src/binary-operator-printers/logical.js | 10 +++--- .../multiplication.js | 21 ++++++----- .../printers/binary-operation-printer.js | 12 +++++++ .../printers/comparison-operation-printer.js | 12 +++++++ .../create-group-if-necessary-builder.js | 5 +-- ...create-grouped-binary-operation-printer.js | 10 ------ .../create-indent-if-necessary-builder.js | 13 +------ .../default-binary-operation-printer.js | 12 ------- src/binary-operator-printers/shift.js | 10 +++--- 14 files changed, 85 insertions(+), 92 deletions(-) create mode 100644 src/binary-operator-printers/printers/binary-operation-printer.js create mode 100644 src/binary-operator-printers/printers/comparison-operation-printer.js delete mode 100644 src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js delete mode 100644 src/binary-operator-printers/printers/default-binary-operation-printer.js diff --git a/src/binary-operator-printers/addition.js b/src/binary-operator-printers/addition.js index 457a3feb2..1711ff32f 100644 --- a/src/binary-operator-printers/addition.js +++ b/src/binary-operator-printers/addition.js @@ -1,8 +1,11 @@ -import { defaultBinaryOperationPrinter } from './printers/default-binary-operation-printer.js'; +import { binaryOperationPrinter } from './printers/binary-operation-printer.js'; +import { bit } from './bit.js'; +import { shift } from './shift.js'; +import { inequality } from './inequality.js'; +import { equality } from './equality.js'; +import { logical } from './logical.js'; export const addition = { match: (op) => ['+', '-'].includes(op), - print: defaultBinaryOperationPrinter - // grouping and indenting before `bit` and `shift` should technically be here - // but they are properly parenthesised before reaching this point. + print: binaryOperationPrinter([shift, bit, inequality, equality, logical]) }; diff --git a/src/binary-operator-printers/bit.js b/src/binary-operator-printers/bit.js index 51e8958e4..c3d73d37c 100644 --- a/src/binary-operator-printers/bit.js +++ b/src/binary-operator-printers/bit.js @@ -1,6 +1,9 @@ -import { defaultBinaryOperationPrinter } from './printers/default-binary-operation-printer.js'; +import { binaryOperationPrinter } from './printers/binary-operation-printer.js'; +import { inequality } from './inequality.js'; +import { equality } from './equality.js'; +import { logical } from './logical.js'; export const bit = { match: (op) => ['&', '|', '^'].includes(op), - print: defaultBinaryOperationPrinter + print: binaryOperationPrinter([inequality, equality, logical]) }; diff --git a/src/binary-operator-printers/equality.js b/src/binary-operator-printers/equality.js index 01693be5c..e80083478 100644 --- a/src/binary-operator-printers/equality.js +++ b/src/binary-operator-printers/equality.js @@ -1,12 +1,7 @@ -import { createGroupedBinaryOperationPrinter } from './printers/create-grouped-binary-operation-printer.js'; -import { createComparisonIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; +import { comparisonOperationPrinter } from './printers/comparison-operation-printer.js'; import { logical } from './logical.js'; -const equalityPrinter = createGroupedBinaryOperationPrinter( - createComparisonIndentIfNecessaryBuilder([logical]) -); - export const equality = { match: (op) => ['==', '!='].includes(op), - print: equalityPrinter + print: comparisonOperationPrinter([logical]) }; diff --git a/src/binary-operator-printers/exponentiation.js b/src/binary-operator-printers/exponentiation.js index 57974640d..9b401301f 100644 --- a/src/binary-operator-printers/exponentiation.js +++ b/src/binary-operator-printers/exponentiation.js @@ -1,22 +1,28 @@ -import { createGroupedBinaryOperationPrinter } from './printers/create-grouped-binary-operation-printer.js'; -import { createArithmeticIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; +import { doc } from 'prettier'; +import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; +import { createBinaryIndentIfNecessaryBuilder } from './printers/binary-operation-printer.js'; +import { multiplication } from './multiplication.js'; import { addition } from './addition.js'; -import { equality } from './equality.js'; +import { shift } from './shift.js'; +import { bit } from './bit.js'; import { inequality } from './inequality.js'; -import { multiplication } from './multiplication.js'; +import { equality } from './equality.js'; +import { logical } from './logical.js'; -const exponentiationPrinter = createGroupedBinaryOperationPrinter( - createArithmeticIndentIfNecessaryBuilder([ - addition, - equality, - inequality, - multiplication - // `bit` and `shift` should technically be here but they are properly - // parenthesised before reaching this point. - ]) -); +const { group } = doc.builders; export const exponentiation = { match: (op) => op === '**', - print: exponentiationPrinter + print: createBinaryOperationPrinter( + () => (document) => group(document), // always group + createBinaryIndentIfNecessaryBuilder([ + multiplication, + addition, + shift, + bit, + inequality, + equality, + logical + ]) + ) }; diff --git a/src/binary-operator-printers/inequality.js b/src/binary-operator-printers/inequality.js index e26eca36b..fa0ec58c0 100644 --- a/src/binary-operator-printers/inequality.js +++ b/src/binary-operator-printers/inequality.js @@ -1,13 +1,8 @@ -import { createGroupedBinaryOperationPrinter } from './printers/create-grouped-binary-operation-printer.js'; -import { createComparisonIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; +import { comparisonOperationPrinter } from './printers/comparison-operation-printer.js'; import { logical } from './logical.js'; import { equality } from './equality.js'; -const inequalityPrinter = createGroupedBinaryOperationPrinter( - createComparisonIndentIfNecessaryBuilder([logical, equality]) -); - export const inequality = { match: (op) => ['<', '>', '<=', '>='].includes(op), - print: inequalityPrinter + print: comparisonOperationPrinter([logical, equality]) }; diff --git a/src/binary-operator-printers/logical.js b/src/binary-operator-printers/logical.js index c55dd7da4..aa2a8dc34 100644 --- a/src/binary-operator-printers/logical.js +++ b/src/binary-operator-printers/logical.js @@ -23,12 +23,10 @@ const indentIfNecessaryBuilder = (path, options) => (document) => { } }; -const logicalPrinter = createBinaryOperationPrinter( - createGroupIfNecessaryBuilder([]), - indentIfNecessaryBuilder -); - export const logical = { match: (op) => ['&&', '||'].includes(op), - print: logicalPrinter + print: createBinaryOperationPrinter( + createGroupIfNecessaryBuilder([]), + indentIfNecessaryBuilder + ) }; diff --git a/src/binary-operator-printers/multiplication.js b/src/binary-operator-printers/multiplication.js index 0efa0204d..dd39deed8 100644 --- a/src/binary-operator-printers/multiplication.js +++ b/src/binary-operator-printers/multiplication.js @@ -1,20 +1,19 @@ -import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; -import { createGroupIfNecessaryBuilder } from './printers/create-group-if-necessary-builder.js'; -import { createArithmeticIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; +import { binaryOperationPrinter } from './printers/binary-operation-printer.js'; import { addition } from './addition.js'; import { bit } from './bit.js'; import { equality } from './equality.js'; import { inequality } from './inequality.js'; import { shift } from './shift.js'; - -const matchers = [addition, bit, equality, inequality, shift]; - -const multiplicationPrinter = createBinaryOperationPrinter( - createGroupIfNecessaryBuilder(matchers), - createArithmeticIndentIfNecessaryBuilder(matchers) -); +import { logical } from './logical.js'; export const multiplication = { match: (op) => ['*', '/', '%'].includes(op), - print: multiplicationPrinter + print: binaryOperationPrinter([ + addition, + shift, + bit, + inequality, + equality, + logical + ]) }; diff --git a/src/binary-operator-printers/printers/binary-operation-printer.js b/src/binary-operator-printers/printers/binary-operation-printer.js new file mode 100644 index 000000000..cce2cc64b --- /dev/null +++ b/src/binary-operator-printers/printers/binary-operation-printer.js @@ -0,0 +1,12 @@ +import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; +import { createGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; +import { createIndentIfNecessaryBuilder } from './create-indent-if-necessary-builder.js'; + +export const createBinaryIndentIfNecessaryBuilder = + createIndentIfNecessaryBuilder(['ReturnStatement']); + +export const binaryOperationPrinter = (shouldGroupAndIndentMatchers) => + createBinaryOperationPrinter( + createGroupIfNecessaryBuilder(shouldGroupAndIndentMatchers), + createBinaryIndentIfNecessaryBuilder(shouldGroupAndIndentMatchers) + ); diff --git a/src/binary-operator-printers/printers/comparison-operation-printer.js b/src/binary-operator-printers/printers/comparison-operation-printer.js new file mode 100644 index 000000000..74ec32afe --- /dev/null +++ b/src/binary-operator-printers/printers/comparison-operation-printer.js @@ -0,0 +1,12 @@ +import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; +import { createGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; +import { createIndentIfNecessaryBuilder } from './create-indent-if-necessary-builder.js'; + +const createComparisonIndentIfNecessaryBuilder = createIndentIfNecessaryBuilder( + ['ReturnStatement', 'IfStatement', 'ForStatement', 'WhileStatement'] +); +export const comparisonOperationPrinter = (shouldGroupAndIndentMatchers) => + createBinaryOperationPrinter( + createGroupIfNecessaryBuilder(shouldGroupAndIndentMatchers), + createComparisonIndentIfNecessaryBuilder(shouldGroupAndIndentMatchers) + ); diff --git a/src/binary-operator-printers/printers/create-group-if-necessary-builder.js b/src/binary-operator-printers/printers/create-group-if-necessary-builder.js index 535d3db49..136f3afd4 100644 --- a/src/binary-operator-printers/printers/create-group-if-necessary-builder.js +++ b/src/binary-operator-printers/printers/create-group-if-necessary-builder.js @@ -4,8 +4,9 @@ import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; const { group } = doc.builders; export const createGroupIfNecessaryBuilder = - (matchers) => (path) => (document) => { + (shouldIndentMatchers) => (path) => (document) => { const parentNode = path.getParentNode(); - if (shouldGroupOrIndent(parentNode, matchers)) return group(document); + if (shouldGroupOrIndent(parentNode, shouldIndentMatchers)) + return group(document); return document; }; diff --git a/src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js b/src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js deleted file mode 100644 index b09b7edbd..000000000 --- a/src/binary-operator-printers/printers/create-grouped-binary-operation-printer.js +++ /dev/null @@ -1,10 +0,0 @@ -import { doc } from 'prettier'; -import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; - -const { group } = doc.builders; - -export const createGroupedBinaryOperationPrinter = (indentIfNecessaryBuilder) => - createBinaryOperationPrinter( - () => (document) => group(document), // always group - indentIfNecessaryBuilder - ); diff --git a/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js b/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js index dcb979c7a..c2ca84c12 100644 --- a/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js +++ b/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js @@ -3,7 +3,7 @@ import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; const { indent } = doc.builders; -const createIndentIfNecessaryBuilder = +export const createIndentIfNecessaryBuilder = (notIndentParentTypes) => (shouldIndentMatchers) => (path) => (document) => { let node = path.getNode(); for (let i = 0; ; i += 1) { @@ -15,14 +15,3 @@ const createIndentIfNecessaryBuilder = node = parentNode; } }; - -export const createArithmeticIndentIfNecessaryBuilder = - createIndentIfNecessaryBuilder(['ReturnStatement']); - -export const createComparisonIndentIfNecessaryBuilder = - createIndentIfNecessaryBuilder([ - 'ReturnStatement', - 'IfStatement', - 'ForStatement', - 'WhileStatement' - ]); diff --git a/src/binary-operator-printers/printers/default-binary-operation-printer.js b/src/binary-operator-printers/printers/default-binary-operation-printer.js deleted file mode 100644 index 59db1c1c6..000000000 --- a/src/binary-operator-printers/printers/default-binary-operation-printer.js +++ /dev/null @@ -1,12 +0,0 @@ -import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; -import { createGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; -import { createArithmeticIndentIfNecessaryBuilder } from './create-indent-if-necessary-builder.js'; -import { equality } from '../equality.js'; -import { inequality } from '../inequality.js'; - -const comparisonMatchers = [equality, inequality]; - -export const defaultBinaryOperationPrinter = createBinaryOperationPrinter( - createGroupIfNecessaryBuilder(comparisonMatchers), - createArithmeticIndentIfNecessaryBuilder(comparisonMatchers) -); diff --git a/src/binary-operator-printers/shift.js b/src/binary-operator-printers/shift.js index 32527da11..c58755127 100644 --- a/src/binary-operator-printers/shift.js +++ b/src/binary-operator-printers/shift.js @@ -1,8 +1,10 @@ -import { defaultBinaryOperationPrinter } from './printers/default-binary-operation-printer.js'; +import { binaryOperationPrinter } from './printers/binary-operation-printer.js'; +import { bit } from './bit.js'; +import { inequality } from './inequality.js'; +import { equality } from './equality.js'; +import { logical } from './logical.js'; export const shift = { match: (op) => ['<<', '>>'].includes(op), - print: defaultBinaryOperationPrinter - // grouping and indenting before `bit` should technically be here but they - // are properly parenthesised before reaching this point. + print: binaryOperationPrinter([bit, inequality, equality, logical]) }; From 2e3127fb0b5d62ab421e2857fd1d258e564962d5 Mon Sep 17 00:00:00 2001 From: Klaus Date: Sat, 15 Mar 2025 13:21:28 +1300 Subject: [PATCH 11/13] upon review, binary operation's indentation behave as `equality`, `inequality` when it's a child of `IfStatement`, `ForStatement`, or `WhileStatement` so there's no need for separate behaviours --- src/binary-operator-printers/equality.js | 4 ++-- src/binary-operator-printers/exponentiation.js | 4 ++-- src/binary-operator-printers/inequality.js | 4 ++-- src/binary-operator-printers/logical.js | 8 ++++---- .../printers/binary-operation-printer.js | 5 +---- .../printers/comparison-operation-printer.js | 12 ------------ .../printers/create-indent-if-necessary-builder.js | 9 ++++++++- 7 files changed, 19 insertions(+), 27 deletions(-) delete mode 100644 src/binary-operator-printers/printers/comparison-operation-printer.js diff --git a/src/binary-operator-printers/equality.js b/src/binary-operator-printers/equality.js index e80083478..edb601231 100644 --- a/src/binary-operator-printers/equality.js +++ b/src/binary-operator-printers/equality.js @@ -1,7 +1,7 @@ -import { comparisonOperationPrinter } from './printers/comparison-operation-printer.js'; +import { binaryOperationPrinter } from './printers/binary-operation-printer.js'; import { logical } from './logical.js'; export const equality = { match: (op) => ['==', '!='].includes(op), - print: comparisonOperationPrinter([logical]) + print: binaryOperationPrinter([logical]) }; diff --git a/src/binary-operator-printers/exponentiation.js b/src/binary-operator-printers/exponentiation.js index 9b401301f..2ea69068b 100644 --- a/src/binary-operator-printers/exponentiation.js +++ b/src/binary-operator-printers/exponentiation.js @@ -1,6 +1,6 @@ import { doc } from 'prettier'; import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; -import { createBinaryIndentIfNecessaryBuilder } from './printers/binary-operation-printer.js'; +import { createIndentIfNecessaryBuilder } from './printers/create-indent-if-necessary-builder.js'; import { multiplication } from './multiplication.js'; import { addition } from './addition.js'; import { shift } from './shift.js'; @@ -15,7 +15,7 @@ export const exponentiation = { match: (op) => op === '**', print: createBinaryOperationPrinter( () => (document) => group(document), // always group - createBinaryIndentIfNecessaryBuilder([ + createIndentIfNecessaryBuilder([ multiplication, addition, shift, diff --git a/src/binary-operator-printers/inequality.js b/src/binary-operator-printers/inequality.js index fa0ec58c0..dd1ad6778 100644 --- a/src/binary-operator-printers/inequality.js +++ b/src/binary-operator-printers/inequality.js @@ -1,8 +1,8 @@ -import { comparisonOperationPrinter } from './printers/comparison-operation-printer.js'; +import { binaryOperationPrinter } from './printers/binary-operation-printer.js'; import { logical } from './logical.js'; import { equality } from './equality.js'; export const inequality = { match: (op) => ['<', '>', '<=', '>='].includes(op), - print: comparisonOperationPrinter([logical, equality]) + print: binaryOperationPrinter([logical, equality]) }; diff --git a/src/binary-operator-printers/logical.js b/src/binary-operator-printers/logical.js index aa2a8dc34..bd327413c 100644 --- a/src/binary-operator-printers/logical.js +++ b/src/binary-operator-printers/logical.js @@ -1,6 +1,8 @@ import { doc } from 'prettier'; import { createBinaryOperationPrinter } from './printers/create-binary-operation-printer.js'; import { createGroupIfNecessaryBuilder } from './printers/create-group-if-necessary-builder.js'; +import { notIndentParentTypes } from './printers/create-indent-if-necessary-builder.js'; +import { shouldGroupOrIndent } from './utils/should-group-or-indent.js'; const { indent } = doc.builders; @@ -8,16 +10,14 @@ const indentIfNecessaryBuilder = (path, options) => (document) => { let node = path.getNode(); for (let i = 0; ; i += 1) { const parentNode = path.getParentNode(i); - if (parentNode.type === 'ReturnStatement') return document; - if (parentNode.type === 'IfStatement') return document; - if (parentNode.type === 'WhileStatement') return document; + if (notIndentParentTypes.includes(parentNode.type)) return document; if ( options.experimentalTernaries && parentNode.type === 'Conditional' && parentNode.condition === node ) return document; - if (parentNode.type !== 'BinaryOperation') return indent(document); + if (shouldGroupOrIndent(parentNode, [])) return indent(document); if (node === parentNode.right) return document; node = parentNode; } diff --git a/src/binary-operator-printers/printers/binary-operation-printer.js b/src/binary-operator-printers/printers/binary-operation-printer.js index cce2cc64b..46dd8f76f 100644 --- a/src/binary-operator-printers/printers/binary-operation-printer.js +++ b/src/binary-operator-printers/printers/binary-operation-printer.js @@ -2,11 +2,8 @@ import { createBinaryOperationPrinter } from './create-binary-operation-printer. import { createGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; import { createIndentIfNecessaryBuilder } from './create-indent-if-necessary-builder.js'; -export const createBinaryIndentIfNecessaryBuilder = - createIndentIfNecessaryBuilder(['ReturnStatement']); - export const binaryOperationPrinter = (shouldGroupAndIndentMatchers) => createBinaryOperationPrinter( createGroupIfNecessaryBuilder(shouldGroupAndIndentMatchers), - createBinaryIndentIfNecessaryBuilder(shouldGroupAndIndentMatchers) + createIndentIfNecessaryBuilder(shouldGroupAndIndentMatchers) ); diff --git a/src/binary-operator-printers/printers/comparison-operation-printer.js b/src/binary-operator-printers/printers/comparison-operation-printer.js deleted file mode 100644 index 74ec32afe..000000000 --- a/src/binary-operator-printers/printers/comparison-operation-printer.js +++ /dev/null @@ -1,12 +0,0 @@ -import { createBinaryOperationPrinter } from './create-binary-operation-printer.js'; -import { createGroupIfNecessaryBuilder } from './create-group-if-necessary-builder.js'; -import { createIndentIfNecessaryBuilder } from './create-indent-if-necessary-builder.js'; - -const createComparisonIndentIfNecessaryBuilder = createIndentIfNecessaryBuilder( - ['ReturnStatement', 'IfStatement', 'ForStatement', 'WhileStatement'] -); -export const comparisonOperationPrinter = (shouldGroupAndIndentMatchers) => - createBinaryOperationPrinter( - createGroupIfNecessaryBuilder(shouldGroupAndIndentMatchers), - createComparisonIndentIfNecessaryBuilder(shouldGroupAndIndentMatchers) - ); diff --git a/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js b/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js index c2ca84c12..3722ed260 100644 --- a/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js +++ b/src/binary-operator-printers/printers/create-indent-if-necessary-builder.js @@ -3,8 +3,15 @@ import { shouldGroupOrIndent } from '../utils/should-group-or-indent.js'; const { indent } = doc.builders; +export const notIndentParentTypes = [ + 'ReturnStatement', + 'IfStatement', + 'ForStatement', + 'WhileStatement' +]; + export const createIndentIfNecessaryBuilder = - (notIndentParentTypes) => (shouldIndentMatchers) => (path) => (document) => { + (shouldIndentMatchers) => (path) => (document) => { let node = path.getNode(); for (let i = 0; ; i += 1) { const parentNode = path.getParentNode(i); From 6c095eaeedd61bbada22f0b587831da1848befd1 Mon Sep 17 00:00:00 2001 From: Klaus Date: Sun, 16 Mar 2025 14:31:03 +1300 Subject: [PATCH 12/13] rightOperandPrinter is only used in a single place thus it's not needed to be exported --- .../create-binary-operation-printer.js | 20 ++++++++++++++++++- .../printers/right-operand-printer.js | 19 ------------------ 2 files changed, 19 insertions(+), 20 deletions(-) delete mode 100644 src/binary-operator-printers/printers/right-operand-printer.js diff --git a/src/binary-operator-printers/printers/create-binary-operation-printer.js b/src/binary-operator-printers/printers/create-binary-operation-printer.js index 8428f8811..e7b182967 100644 --- a/src/binary-operator-printers/printers/create-binary-operation-printer.js +++ b/src/binary-operator-printers/printers/create-binary-operation-printer.js @@ -1,4 +1,22 @@ -import { rightOperandPrinter } from './right-operand-printer.js'; +import { doc } from 'prettier'; +import { assignment } from '../assignment.js'; + +const { group, line } = doc.builders; + +const rightOperandPrinter = (node, path, print, options) => { + const right = + options.experimentalOperatorPosition === 'end' + ? [' ', node.operator, line, path.call(print, 'right')] + : [line, node.operator, ' ', path.call(print, 'right')]; + + // If it's a single binary operation, avoid having a small right + // operand like - 1 on its own line + const parent = path.getParentNode(); + return node.left.type !== 'BinaryOperation' && + (parent.type !== 'BinaryOperation' || assignment.match(parent.operator)) + ? group(right) + : right; +}; export const createBinaryOperationPrinter = (groupIfNecessaryBuilder, indentIfNecessaryBuilder) => diff --git a/src/binary-operator-printers/printers/right-operand-printer.js b/src/binary-operator-printers/printers/right-operand-printer.js deleted file mode 100644 index 8e21a16c3..000000000 --- a/src/binary-operator-printers/printers/right-operand-printer.js +++ /dev/null @@ -1,19 +0,0 @@ -import { doc } from 'prettier'; -import { assignment } from '../assignment.js'; - -const { group, line } = doc.builders; - -export const rightOperandPrinter = (node, path, print, options) => { - const right = - options.experimentalOperatorPosition === 'end' - ? [' ', node.operator, line, path.call(print, 'right')] - : [line, node.operator, ' ', path.call(print, 'right')]; - - // If it's a single binary operation, avoid having a small right - // operand like - 1 on its own line - const parent = path.getParentNode(); - return node.left.type !== 'BinaryOperation' && - (parent.type !== 'BinaryOperation' || assignment.match(parent.operator)) - ? group(right) - : right; -}; From c7546beb3e9cab03a5b16cbdf10fae041cc2e640 Mon Sep 17 00:00:00 2001 From: Klaus Date: Sat, 26 Apr 2025 18:04:19 +0200 Subject: [PATCH 13/13] fixing test after rebase --- .../__snapshots__/jsfmt.spec.js.snap | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/tests/format/ContractDefinitions/__snapshots__/jsfmt.spec.js.snap b/tests/format/ContractDefinitions/__snapshots__/jsfmt.spec.js.snap index e67a4276d..93c446beb 100644 --- a/tests/format/ContractDefinitions/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/ContractDefinitions/__snapshots__/jsfmt.spec.js.snap @@ -72,10 +72,8 @@ contract StorageLayoutSpecifier1 layout at contract StorageLayoutSpecifier2 layout at veryVeryLongFunction( - 12345678901234567890 * - 12345678901234567890 - - 12345678901234567890 / - 12345678901234567890 + + 12345678901234567890 * 12345678901234567890 - + 12345678901234567890 / 12345678901234567890 + 12345678901234567890 - 12345678901234567890 ) @@ -97,10 +95,8 @@ contract StorageLayoutSpecifier6 is Contract1, Contract2, Contract3, Contract4, Contract5 layout at veryVeryLongFunction( - 12345678901234567890 * - 12345678901234567890 - - 12345678901234567890 / - 12345678901234567890 + + 12345678901234567890 * 12345678901234567890 - + 12345678901234567890 / 12345678901234567890 + 12345678901234567890 - 12345678901234567890 ) @@ -142,10 +138,8 @@ contract StorageLayoutSpecifier9 Contract7 layout at veryVeryLongFunction( - 12345678901234567890 * - 12345678901234567890 - - 12345678901234567890 / - 12345678901234567890 + + 12345678901234567890 * 12345678901234567890 - + 12345678901234567890 / 12345678901234567890 + 12345678901234567890 - 12345678901234567890 ) @@ -168,10 +162,8 @@ contract InheritanceSpecifier4 is SomeOtherContract(1234, false) layout at veryVeryLongFunction( - 12345678901234567890 * - 12345678901234567890 - - 12345678901234567890 / - 12345678901234567890 + + 12345678901234567890 * 12345678901234567890 - + 12345678901234567890 / 12345678901234567890 + 12345678901234567890 - 12345678901234567890 ) @@ -215,10 +207,8 @@ contract LongInheritanceSpecifier4 ) layout at veryVeryLongFunction( - 12345678901234567890 * - 12345678901234567890 - - 12345678901234567890 / - 12345678901234567890 + + 12345678901234567890 * 12345678901234567890 - + 12345678901234567890 / 12345678901234567890 + 12345678901234567890 - 12345678901234567890 )