diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 3aa72410..7805193c 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -573,7 +573,7 @@ Previously, even if the line length was shorter than `printWidth`, Prettier woul ``` -#### JavaScript: Empty lines in destructured arrow function parameters could break indentation and idempotence ([#6301] by [@sosukesuzuki]) +#### JavaScript: Fix breaks indentation and idempotency when an arrow function that args include object pattern is passed to a function as parameter. ([#6301] & [#6382] by [@sosukesuzuki]) Previously, Prettier indented code strangely when an arrow function whose parameters included an object pattern was passed to a function call as an argument. Also, it broke idempotence. Please see [#6294](https://github.com/prettier/prettier/issues/6294) for details. @@ -1116,6 +1116,7 @@ sometimes{{nogaps}}areimportant [#6640]: https://github.com/prettier/prettier/pull/6640 [#6646]: https://github.com/prettier/prettier/pull/6646 [#6673]: https://github.com/prettier/prettier/pull/6673 +[#6382]: https://github.com/prettier/prettier/pull/6382 [@brainkim]: https://github.com/brainkim [@duailibe]: https://github.com/duailibe [@gavinjoyce]: https://github.com/gavinjoyce diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 865ea2d3..0298477e 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -3879,26 +3879,29 @@ function printArgumentsList(path, options, print) { // b // }) => {} // ); - function hasEmptyLineInObjectArgInArrowFunction(arg) { - return ( - arg && - arg.type === "ArrowFunctionExpression" && - arg.params && - arg.params.some( - param => - param.type && - param.type === "ObjectPattern" && - param.properties && - param.properties.some( - (property, i, properties) => - i < properties.length - 1 && - isNextLineEmpty(options.originalText, property, options) - ) - ) - ); + function shouldBreakForArrowFunctionInArguments(arg, argPath) { + if ( + !arg || + arg.type !== "ArrowFunctionExpression" || + !arg.body || + arg.body.type !== "BlockStatement" || + !arg.params || + arg.params.length < 1 + ) { + return false; + } + + let shouldBreak = false; + argPath.each(paramPath => { + const printed = concat([print(paramPath)]); + shouldBreak = shouldBreak || willBreak(printed); + }, "params"); + + return shouldBreak; } let anyArgEmptyLine = false; + let shouldBreakForArrowFunction = false; let hasEmptyLineFollowingFirstArg = false; const lastArgIndex = args.length - 1; const printedArguments = path.map((argPath, index) => { @@ -3918,7 +3921,10 @@ function printArgumentsList(path, options, print) { parts.push(",", line); } - anyArgEmptyLine = hasEmptyLineInObjectArgInArrowFunction(arg); + shouldBreakForArrowFunction = shouldBreakForArrowFunctionInArguments( + arg, + argPath + ); return concat(parts); }, "arguments"); @@ -3953,7 +3959,9 @@ function printArgumentsList(path, options, print) { const shouldBreak = (shouldGroupFirst ? printedArguments.slice(1).some(willBreak) - : printedArguments.slice(0, -1).some(willBreak)) || anyArgEmptyLine; + : printedArguments.slice(0, -1).some(willBreak)) || + anyArgEmptyLine || + shouldBreakForArrowFunction; // We want to print the last argument with a special flag let printedExpanded; diff --git a/tests/arrows/__snapshots__/jsfmt.spec.js.snap b/tests/arrows/__snapshots__/jsfmt.spec.js.snap index f9c58baa..6ee69694 100644 --- a/tests/arrows/__snapshots__/jsfmt.spec.js.snap +++ b/tests/arrows/__snapshots__/jsfmt.spec.js.snap @@ -341,6 +341,269 @@ foo( }) => a ); +foo( + ({ + a: { + a, + + b + } + }) => {} +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => {} +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => {} +); + +foo( + ({ + a: { + a, + + b + } + }) => a +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => a +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => a +); + +foo( + ([ + { + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ([ + ...{ + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ( + n = { + a: { + b: { + c: { + d, + + e + } + } + } + } + ) => {} +); + +foo( + ({ + x: [ + { + a, + + b + } + ] + }) => {} +); + +foo( + ( + a = [ + { + a, + + b + } + ] + ) => a +); + +foo( + ([ + [ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ([ + [ + [ + [ + { + a, + b: { + c, + d: { + e, + + f + } + } + } + ] + ] + ] + ]) => {} +); + +foo( + ( + ...{ + a, + + b + } + ) => {} +); + +foo( + ( + ...[ + { + a, + + b + } + ] + ) => {} +); + +foo( + ([ + ...[ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ( + a = [{ + a, + + b + }] + ) => {} +); + +foo( + ( + a = (({ + a, + + b + }) => {})() + ) => {} +); + +foo( + ( + a = f({ + a, + + b + }) + ) => {} +); + +foo( + ( + a = ({ + a, + + b + }) => {} + ) => {} +); + +foo( + ( + a = 1 + + f({ + a, + + b + }) + ) => {} +); + =====================================output===================================== Seq(typeDef.interface.groups).forEach(group => Seq(group.members).forEach((member, memberName) => @@ -464,6 +727,271 @@ foo(({ a, b }) => a); foo(({ a, b }) => a); +foo( + ({ + a: { + a, + + b + } + }) => {} +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => {} +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => {} +); + +foo( + ({ + a: { + a, + + b + } + }) => a +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => a +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => a +); + +foo( + ([ + { + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ([ + ...{ + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ( + n = { + a: { + b: { + c: { + d, + + e + } + } + } + } + ) => {} +); + +foo( + ({ + x: [ + { + a, + + b + } + ] + }) => {} +); + +foo( + ( + a = [ + { + a, + + b + } + ] + ) => a +); + +foo( + ([ + [ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ([ + [ + [ + [ + { + a, + b: { + c, + d: { + e, + + f + } + } + } + ] + ] + ] + ]) => {} +); + +foo( + ( + ...{ + a, + + b + } + ) => {} +); + +foo( + ( + ...[ + { + a, + + b + } + ] + ) => {} +); + +foo( + ([ + ...[ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ( + a = [ + { + a, + + b + } + ] + ) => {} +); + +foo( + ( + a = (({ + a, + + b + }) => {})() + ) => {} +); + +foo( + ( + a = f({ + a, + + b + }) + ) => {} +); + +foo( + ( + a = ({ + a, + + b + }) => {} + ) => {} +); + +foo( + ( + a = 1 + + f({ + a, + + b + }) + ) => {} +); + ================================================================================ `; @@ -610,6 +1138,269 @@ foo( }) => a ); +foo( + ({ + a: { + a, + + b + } + }) => {} +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => {} +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => {} +); + +foo( + ({ + a: { + a, + + b + } + }) => a +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => a +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => a +); + +foo( + ([ + { + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ([ + ...{ + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ( + n = { + a: { + b: { + c: { + d, + + e + } + } + } + } + ) => {} +); + +foo( + ({ + x: [ + { + a, + + b + } + ] + }) => {} +); + +foo( + ( + a = [ + { + a, + + b + } + ] + ) => a +); + +foo( + ([ + [ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ([ + [ + [ + [ + { + a, + b: { + c, + d: { + e, + + f + } + } + } + ] + ] + ] + ]) => {} +); + +foo( + ( + ...{ + a, + + b + } + ) => {} +); + +foo( + ( + ...[ + { + a, + + b + } + ] + ) => {} +); + +foo( + ([ + ...[ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ( + a = [{ + a, + + b + }] + ) => {} +); + +foo( + ( + a = (({ + a, + + b + }) => {})() + ) => {} +); + +foo( + ( + a = f({ + a, + + b + }) + ) => {} +); + +foo( + ( + a = ({ + a, + + b + }) => {} + ) => {} +); + +foo( + ( + a = 1 + + f({ + a, + + b + }) + ) => {} +); + =====================================output===================================== Seq(typeDef.interface.groups).forEach((group) => Seq(group.members).forEach((member, memberName) => @@ -733,6 +1524,271 @@ foo(({ a, b }) => a); foo(({ a, b }) => a); +foo( + ({ + a: { + a, + + b + } + }) => {} +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => {} +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => {} +); + +foo( + ({ + a: { + a, + + b + } + }) => a +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => a +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => a +); + +foo( + ([ + { + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ([ + ...{ + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ( + n = { + a: { + b: { + c: { + d, + + e + } + } + } + } + ) => {} +); + +foo( + ({ + x: [ + { + a, + + b + } + ] + }) => {} +); + +foo( + ( + a = [ + { + a, + + b + } + ] + ) => a +); + +foo( + ([ + [ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ([ + [ + [ + [ + { + a, + b: { + c, + d: { + e, + + f + } + } + } + ] + ] + ] + ]) => {} +); + +foo( + ( + ...{ + a, + + b + } + ) => {} +); + +foo( + ( + ...[ + { + a, + + b + } + ] + ) => {} +); + +foo( + ([ + ...[ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ( + a = [ + { + a, + + b + } + ] + ) => {} +); + +foo( + ( + a = (({ + a, + + b + }) => {})() + ) => {} +); + +foo( + ( + a = f({ + a, + + b + }) + ) => {} +); + +foo( + ( + a = ({ + a, + + b + }) => {} + ) => {} +); + +foo( + ( + a = 1 + + f({ + a, + + b + }) + ) => {} +); + ================================================================================ `; diff --git a/tests/arrows/call.js b/tests/arrows/call.js index f2228250..3e3c38ec 100644 --- a/tests/arrows/call.js +++ b/tests/arrows/call.js @@ -133,3 +133,266 @@ foo( }) => a ); + +foo( + ({ + a: { + a, + + b + } + }) => {} +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => {} +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => {} +); + +foo( + ({ + a: { + a, + + b + } + }) => a +); + +foo( + ({ + a: { + b: { + c, + + d + } + } + }) => a +); + +foo( + ({ + a: { + b: { + c: { + d, + + e + } + } + } + }) => a +); + +foo( + ([ + { + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ([ + ...{ + a: { + b: { + c: { + d, + + e + } + } + } + } + ]) => {} +); + +foo( + ( + n = { + a: { + b: { + c: { + d, + + e + } + } + } + } + ) => {} +); + +foo( + ({ + x: [ + { + a, + + b + } + ] + }) => {} +); + +foo( + ( + a = [ + { + a, + + b + } + ] + ) => a +); + +foo( + ([ + [ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ([ + [ + [ + [ + { + a, + b: { + c, + d: { + e, + + f + } + } + } + ] + ] + ] + ]) => {} +); + +foo( + ( + ...{ + a, + + b + } + ) => {} +); + +foo( + ( + ...[ + { + a, + + b + } + ] + ) => {} +); + +foo( + ([ + ...[ + { + a, + + b + } + ] + ]) => {} +); + +foo( + ( + a = [{ + a, + + b + }] + ) => {} +); + +foo( + ( + a = (({ + a, + + b + }) => {})() + ) => {} +); + +foo( + ( + a = f({ + a, + + b + }) + ) => {} +); + +foo( + ( + a = ({ + a, + + b + }) => {} + ) => {} +); + +foo( + ( + a = 1 + + f({ + a, + + b + }) + ) => {} +);