diff --git a/changelog_unreleased/javascript/18087.md b/changelog_unreleased/javascript/18087.md new file mode 100644 index 000000000..f148090a6 --- /dev/null +++ b/changelog_unreleased/javascript/18087.md @@ -0,0 +1,42 @@ +#### Remove indention in logical expression in `Boolean()` call (#18087 by @kovsu) + +Reduce diff when changing a condition to an opposite value, or change between `!!` and `Boolean()`. + + +```js +// Input +const foo = Boolean( + a_long_long_condition || + a_long_long_long_condition || + a_long_long_long_condition +); +const bar = !!( + a_long_long_condition || + a_long_long_long_condition || + a_long_long_long_condition +); + +// Prettier stable +const foo = Boolean( + a_long_long_condition || + a_long_long_long_condition || + a_long_long_long_condition, +); +const bar = !!( + a_long_long_condition || + a_long_long_long_condition || + a_long_long_long_condition +); + +// Prettier main +const foo = Boolean( + a_long_long_condition || + a_long_long_long_condition || + a_long_long_long_condition +); +const bar = !!( + a_long_long_condition || + a_long_long_long_condition || + a_long_long_long_condition +); +``` diff --git a/src/language-js/print/binaryish.js b/src/language-js/print/binaryish.js index 04562ca9a..d670c1255 100644 --- a/src/language-js/print/binaryish.js +++ b/src/language-js/print/binaryish.js @@ -110,7 +110,8 @@ function printBinaryishExpression(path, options, print) { grandparent.type !== "ReturnStatement" && grandparent.type !== "ThrowStatement" && !isCallExpression(grandparent)) || - parent.type === "TemplateLiteral"; + parent.type === "TemplateLiteral" || + isBooleanTypeCoercion(path); const shouldIndentIfInlining = parent.type === "AssignmentExpression" || @@ -391,4 +392,27 @@ function isVueFilterSequenceExpression(path, options) { ); } +/** +@returns {boolean} +*/ +function isBooleanTypeCoercion(path) { + if (path.key !== "arguments") { + return false; + } + + const { parent } = path; + if ( + !( + isCallExpression(parent) && + !parent.optional && + parent.arguments.length === 1 + ) + ) { + return false; + } + + const { callee } = parent; + return callee.type === "Identifier" && callee.name === "Boolean"; +} + export { printBinaryishExpression, shouldInlineLogicalExpression }; diff --git a/tests/format/js/call/boolean/__snapshots__/format.test.js.snap b/tests/format/js/call/boolean/__snapshots__/format.test.js.snap new file mode 100644 index 000000000..3c6f5ab5d --- /dev/null +++ b/tests/format/js/call/boolean/__snapshots__/format.test.js.snap @@ -0,0 +1,366 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`boolean.js - {"experimentalOperatorPosition":"start"} format 1`] = ` +====================================options===================================== +experimentalOperatorPosition: "start" +parsers: ["babel", "typescript", "flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +)?.toString(); +a = new Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); +a = !( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +); +a = !!( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +); + +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); +a = new Foo( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); + +// Different operators +a = Boolean( + a_long_long_long_long_condition && a_long_long_long_long_condition && a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition ?? a_long_long_long_long_condition ?? a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition + a_long_long_long_long_condition + a_long_long_long_long_condition, +); + +// Not argument +a = ( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +)(Boolean); +a = new ( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +)(Foo); + +// Not \`Boolean\` +a = not_Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); + +// Nested +a = Boolean( + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) + && + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) +); +a = Boolean( + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) + || + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) +); +a = Boolean(Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +)); + +=====================================output===================================== +a = Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, +)?.toString(); +a = new Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, +); +a = !( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition +); +a = !!( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition +); + +a = Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, + anotherArgument, +); +a = Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, + anotherArgument, +); +a = new Foo( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, + anotherArgument, +); + +// Different operators +a = Boolean( + a_long_long_long_long_condition + && a_long_long_long_long_condition + && a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition + ?? a_long_long_long_long_condition + ?? a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition + + a_long_long_long_long_condition + + a_long_long_long_long_condition, +); + +// Not argument +a = ( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition +)(Boolean); +a = new (a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition)(Foo); + +// Not \`Boolean\` +a = not_Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, +); + +// Nested +a = Boolean( + (a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition) + && (a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition), +); +a = Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, +); +a = Boolean( + Boolean( + a_long_long_long_long_condition + || a_long_long_long_long_condition + || a_long_long_long_long_condition, + ), +); + +================================================================================ +`; + +exports[`boolean.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +)?.toString(); +a = new Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); +a = !( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +); +a = !!( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +); + +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); +a = new Foo( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); + +// Different operators +a = Boolean( + a_long_long_long_long_condition && a_long_long_long_long_condition && a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition ?? a_long_long_long_long_condition ?? a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition + a_long_long_long_long_condition + a_long_long_long_long_condition, +); + +// Not argument +a = ( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +)(Boolean); +a = new ( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +)(Foo); + +// Not \`Boolean\` +a = not_Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); + +// Nested +a = Boolean( + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) + && + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) +); +a = Boolean( + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) + || + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) +); +a = Boolean(Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +)); + +=====================================output===================================== +a = Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, +)?.toString(); +a = new Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, +); +a = !( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition +); +a = !!( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition +); + +a = Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, + anotherArgument, +); +a = Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, + anotherArgument, +); +a = new Foo( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, + anotherArgument, +); + +// Different operators +a = Boolean( + a_long_long_long_long_condition && + a_long_long_long_long_condition && + a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition ?? + a_long_long_long_long_condition ?? + a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition + + a_long_long_long_long_condition + + a_long_long_long_long_condition, +); + +// Not argument +a = ( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition +)(Boolean); +a = new (a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition)(Foo); + +// Not \`Boolean\` +a = not_Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, +); + +// Nested +a = Boolean( + (a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition) && + (a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition), +); +a = Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, +); +a = Boolean( + Boolean( + a_long_long_long_long_condition || + a_long_long_long_long_condition || + a_long_long_long_long_condition, + ), +); + +================================================================================ +`; diff --git a/tests/format/js/call/boolean/boolean.js b/tests/format/js/call/boolean/boolean.js new file mode 100644 index 000000000..39db89195 --- /dev/null +++ b/tests/format/js/call/boolean/boolean.js @@ -0,0 +1,67 @@ +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +)?.toString(); +a = new Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); +a = !( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +); +a = !!( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +); + +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); +a = Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); +a = new Foo( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, + anotherArgument, +); + +// Different operators +a = Boolean( + a_long_long_long_long_condition && a_long_long_long_long_condition && a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition ?? a_long_long_long_long_condition ?? a_long_long_long_long_condition, +); +a = Boolean( + a_long_long_long_long_condition + a_long_long_long_long_condition + a_long_long_long_long_condition, +); + +// Not argument +a = ( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +)(Boolean); +a = new ( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition +)(Foo); + +// Not `Boolean` +a = not_Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +); + +// Nested +a = Boolean( + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) + && + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) +); +a = Boolean( + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) + || + (a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition) +); +a = Boolean(Boolean( + a_long_long_long_long_condition || a_long_long_long_long_condition || a_long_long_long_long_condition, +)); diff --git a/tests/format/js/call/boolean/format.test.js b/tests/format/js/call/boolean/format.test.js new file mode 100644 index 000000000..775636727 --- /dev/null +++ b/tests/format/js/call/boolean/format.test.js @@ -0,0 +1,4 @@ +runFormatTest(import.meta, ["babel", "typescript", "flow"]); +runFormatTest(import.meta, ["babel", "typescript", "flow"], { + experimentalOperatorPosition: "start", +});