diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 2b3031f8..9f2e4ada 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -339,6 +339,35 @@ Previously, even if the line length is shorter than print-width is Prettier brea ``` +#### JavaScript: Fix breaks indentation and idempotency when an arrow function that args include object pattern is passed to a function as parameter. ([#6301] by [@sosukesuzuki]) + +Previously, Prettier collapses strangely, when an arrow function that args include object pattern is passed to a function as parameter. Also, it breaks idempotency. Please see [#6294](https://github.com/prettier/prettier/issues/6294) for detail. + + +```js +// Input +foo( + ({ + a, + + b + }) => {} +); + +// Output (Prettier stable) +foo(({ a, + b }) => {}); + +// Output (Prettier master) +foo( + ({ + a, + + b + }) => {} +); +``` + [#5910]: https://github.com/prettier/prettier/pull/5910 [#6186]: https://github.com/prettier/prettier/pull/6186 [#6206]: https://github.com/prettier/prettier/pull/6206 @@ -350,6 +379,7 @@ Previously, even if the line length is shorter than print-width is Prettier brea [#6289]: https://github.com/prettier/prettier/pull/6289 [#6332]: https://github.com/prettier/prettier/pull/6332 [#6284]: https://github.com/prettier/prettier/pull/6284 +[#6301]: https://github.com/prettier/prettier/pull/6301 [@duailibe]: https://github.com/duailibe [@gavinjoyce]: https://github.com/gavinjoyce [@sosukesuzuki]: https://github.com/sosukesuzuki diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 4d38318a..73ca68c4 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -4056,6 +4056,32 @@ function printArgumentsList(path, options, print) { ]); } + // func( + // ({ + // a, + + // 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) + ) + ) + ); + } + let anyArgEmptyLine = false; let hasEmptyLineFollowingFirstArg = false; const lastArgIndex = args.length - 1; @@ -4076,6 +4102,8 @@ function printArgumentsList(path, options, print) { parts.push(",", line); } + anyArgEmptyLine = hasEmptyLineInObjectArgInArrowFunction(arg); + return concat(parts); }, "arguments"); diff --git a/tests/arrows/__snapshots__/jsfmt.spec.js.snap b/tests/arrows/__snapshots__/jsfmt.spec.js.snap index 19caf038..46cdbc7a 100644 --- a/tests/arrows/__snapshots__/jsfmt.spec.js.snap +++ b/tests/arrows/__snapshots__/jsfmt.spec.js.snap @@ -286,6 +286,61 @@ fooooooooooooooooooooooooooooooooooooooooooooooooooo(action => next => dispatch(action), ); +foo( + ({ + a, + + b + }) => {} +); + +foo( + ({ + a, + b + + }) => {} +); + +foo( + ({ + a, + b + }) => {} +); + +foo( + a, + ({ + a, + + b + }) => {} +) + +foo( + ({ + a, + + b + }) => a +); + +foo( + ({ + a, + b + }) => a +); + +foo( + ({ + a, + b + + }) => a +); + =====================================output===================================== Seq(typeDef.interface.groups).forEach(group => Seq(group.members).forEach((member, memberName) => @@ -376,6 +431,39 @@ fooooooooooooooooooooooooooooooooooooooooooooooooooo(action => next => dispatch(action) ); +foo( + ({ + a, + + b + }) => {} +); + +foo(({ a, b }) => {}); + +foo(({ a, b }) => {}); + +foo( + a, + ({ + a, + + b + }) => {} +); + +foo( + ({ + a, + + b + }) => a +); + +foo(({ a, b }) => a); + +foo(({ a, b }) => a); + ================================================================================ `; @@ -467,6 +555,61 @@ fooooooooooooooooooooooooooooooooooooooooooooooooooo(action => next => dispatch(action), ); +foo( + ({ + a, + + b + }) => {} +); + +foo( + ({ + a, + b + + }) => {} +); + +foo( + ({ + a, + b + }) => {} +); + +foo( + a, + ({ + a, + + b + }) => {} +) + +foo( + ({ + a, + + b + }) => a +); + +foo( + ({ + a, + b + }) => a +); + +foo( + ({ + a, + b + + }) => a +); + =====================================output===================================== Seq(typeDef.interface.groups).forEach((group) => Seq(group.members).forEach((member, memberName) => @@ -557,6 +700,39 @@ fooooooooooooooooooooooooooooooooooooooooooooooooooo((action) => (next) => dispatch(action) ); +foo( + ({ + a, + + b + }) => {} +); + +foo(({ a, b }) => {}); + +foo(({ a, b }) => {}); + +foo( + a, + ({ + a, + + b + }) => {} +); + +foo( + ({ + a, + + b + }) => a +); + +foo(({ a, b }) => a); + +foo(({ a, b }) => a); + ================================================================================ `; diff --git a/tests/arrows/call.js b/tests/arrows/call.js index bc4b2244..f2228250 100644 --- a/tests/arrows/call.js +++ b/tests/arrows/call.js @@ -78,3 +78,58 @@ jest.mock( fooooooooooooooooooooooooooooooooooooooooooooooooooo(action => next => dispatch(action), ); + +foo( + ({ + a, + + b + }) => {} +); + +foo( + ({ + a, + b + + }) => {} +); + +foo( + ({ + a, + b + }) => {} +); + +foo( + a, + ({ + a, + + b + }) => {} +) + +foo( + ({ + a, + + b + }) => a +); + +foo( + ({ + a, + b + }) => a +); + +foo( + ({ + a, + b + + }) => a +);