From cfba21f493b9492f815d4aa7d450b9c40308aba2 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Wed, 10 Jul 2019 22:06:08 +0900 Subject: [PATCH] JavaScript: Keep unary expressions parentheses with comments (#6217) --- CHANGELOG.unreleased.md | 33 +- src/language-js/printer-estree.js | 15 +- .../__snapshots__/jsfmt.spec.js.snap | 81 +++ tests/bind_expressions/unary.js | 14 + .../__snapshots__/jsfmt.spec.js.snap | 580 ++++++++++++++++++ tests/unary_expression/comments.js | 285 +++++++++ 6 files changed, 1005 insertions(+), 3 deletions(-) create mode 100644 tests/bind_expressions/unary.js create mode 100644 tests/unary_expression/comments.js diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 2e52cba9..dcd6db27 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -146,6 +146,33 @@ Previously, Prettier would sometimes ignore whitespace when formatting comments. ``` +#### JavaScript: Keep unary expressions parentheses with comments ([#6217] by [@sosukesuzuki]) + +Previously, Prettier removes parentheses enclose unary expressions. This change modify to keep it when the expression has comments. + + +```ts +// Input +!( + /* foo */ + foo +); +!( + foo // foo +); + +// Output (Prettier stable) +!/* foo */ +foo; +!foo; // foo + +// Output (Prettier master) +!(/* foo */ foo); +!( + foo // foo +); +``` + ### Handlebars: Improve comment formatting ([#6234] by [@gavinjoyce]) Previously, Prettier would incorrectly decode HTML entiites. @@ -168,9 +195,11 @@ Previously, Prettier would incorrectly decode HTML entiites.

``` -[#6209]: https://github.com/prettier/prettier/pull/6209 [#6186]: https://github.com/prettier/prettier/pull/6186 -[#6186]: https://github.com/prettier/prettier/pull/6206 +[#6206]: https://github.com/prettier/prettier/pull/6206 +[#6209]: https://github.com/prettier/prettier/pull/6209 +[#6217]: https://github.com/prettier/prettier/pull/6217 [#6234]: https://github.com/prettier/prettier/pull/6234 [@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 2d471db3..a78c0c79 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -1630,7 +1630,20 @@ function printPathNoParens(path, options, print, args) { parts.push(" "); } - parts.push(path.call(print, "argument")); + if (n.argument.comments && n.argument.comments.length > 0) { + parts.push( + group( + concat([ + "(", + indent(concat([softline, path.call(print, "argument")])), + softline, + ")" + ]) + ) + ); + } else { + parts.push(path.call(print, "argument")); + } return concat(parts); case "UpdateExpression": diff --git a/tests/bind_expressions/__snapshots__/jsfmt.spec.js.snap b/tests/bind_expressions/__snapshots__/jsfmt.spec.js.snap index 5b0ce399..7c1d2b63 100644 --- a/tests/bind_expressions/__snapshots__/jsfmt.spec.js.snap +++ b/tests/bind_expressions/__snapshots__/jsfmt.spec.js.snap @@ -414,3 +414,84 @@ class X { ================================================================================ `; + +exports[`unary.js 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +!x::y; +!(x::y /* foo */); +!(/* foo */ x::y); +!( + /* foo */ + x::y +); +!( + x::y + /* foo */ +); +!( + x::y // foo +); + +=====================================output===================================== +!x::y; +!(x::y /* foo */); +!(/* foo */ x::y); +!( + /* foo */ + x::y +); +!( + x::y + /* foo */ +); +!( + x::y // foo +); + +================================================================================ +`; + +exports[`unary.js 2`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 +semi: false + | printWidth +=====================================input====================================== +!x::y; +!(x::y /* foo */); +!(/* foo */ x::y); +!( + /* foo */ + x::y +); +!( + x::y + /* foo */ +); +!( + x::y // foo +); + +=====================================output===================================== +!x::y +!(x::y /* foo */) +!(/* foo */ x::y) +!( + /* foo */ + x::y +) +!( + x::y + /* foo */ +) +!( + x::y // foo +) + +================================================================================ +`; diff --git a/tests/bind_expressions/unary.js b/tests/bind_expressions/unary.js new file mode 100644 index 00000000..96e63c1d --- /dev/null +++ b/tests/bind_expressions/unary.js @@ -0,0 +1,14 @@ +!x::y; +!(x::y /* foo */); +!(/* foo */ x::y); +!( + /* foo */ + x::y +); +!( + x::y + /* foo */ +); +!( + x::y // foo +); diff --git a/tests/unary_expression/__snapshots__/jsfmt.spec.js.snap b/tests/unary_expression/__snapshots__/jsfmt.spec.js.snap index 8302d25e..15d492f7 100644 --- a/tests/unary_expression/__snapshots__/jsfmt.spec.js.snap +++ b/tests/unary_expression/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,585 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`comments.js 1`] = ` +====================================options===================================== +parsers: ["flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +!x; +!(x /* foo */); +!(/* foo */ x); +!( + /* foo */ + x +); +!( + x + /* foo */ +); +!( + x // foo +); + +!(x + y); +!(x + y /* foo */); +!(/* foo */ x + y); +!( + /* foo */ + x + y +); +!( + x + y + /* foo */ +); +!( + x + y // foo +); + +!(x || y); +!(/* foo */ x || y); +!(x || y /* foo */); +!( + /* foo */ + x || y +); +!( + x || y + /* foo */ +); +!( + x || y // foo +); + +![1, 2, 3]; +!([1, 2, 3] /* foo */); +!(/* foo */ [1, 2, 3]); +!( + /* foo */ + [1, 2, 3] +); +!( + [1, 2, 3] + /* foo */ +); +!( + [1, 2, 3] // foo +); + +!{ a: 1, b: 2 }; +!({ a: 1, b: 2 } /* foo */); +!(/* foo */ { a: 1, b: 2 }); +!( + /* foo */ + { a: 1, b: 2 } +); +!( + { a: 1, b: 2 } + /* foo */ +); +!( + { a: 1, b: 2 } // foo +) + +!function() { + return x; +}; +!( + function() { + return x; + } /* foo */ +); +!( + /* foo */ function() { + return x; + } +); +!( + /* foo */ + function() { + return x; + } +); +!( + function() { + return x; + } + /* foo */ +); +!( + function() { + return x; + } // foo +) + +!+3; +!(+3 /* foo */); +!(/* foo */ +3); +!( + /* foo */ + +3 +); +!( + +3 + /* foo */ +); +!( + +3 // foo +); + +!+( + /* foo */ + 3 +); +!(/* foo */ +(3 /* foo */)); +!(+(3 /* foo */) /* foo */); +!( + /* foo */ + +( + /* foo */ + 3 + ) +); +!( + +( + 3 + /* foo */ + ) + /* foo */ +); +!( + +( + 3 /* foo */ + ) // foo +); + +!(x = y); +!(x = y /* foo */); +!(/* foo */ x = y); +!( + /* foo */ + x = y +); +!( + x = y + /* foo */ +); +!( + x = y // foo +); + +!x.y; +!(x.y /* foo */); +!(/* foo */ x.y); +!( + /* foo */ + x.y +); +!( + x.y + /* foo */ +); +!( + x.y // foo +); + +!(x ? y : z); +!(x ? y : z /* foo */); +!(/* foo */ x ? y : z); +!( + /* foo */ + x ? y : z +); +!( + x ? y : z + /* foo */ +); +!( + x ? y : z // foo +); + +!x(); +!(x() /* foo */); +!(/* foo */ x()); +!( + /* foo */ + x() +); +!( + x() + /* foo */ +); +!( + x() // foo +); + +!new x(); +!(new x() /* foo */); +!(/* foo */ new x()); +!( + /* foo */ + new x() +); +!( + new x() + /* foo */ +); +!( + new x() // foo +); + +!(x, y); +!(x, y /* foo */); +!(/* foo */ x, y); +!( + /* foo */ + x, y +); +!( + x, y + /* foo */ +); +!( + x.y // foo +); + +!(() => 3); +!(() => 3 /* foo */); +!(/* foo */ () => 3); +!( + /* foo */ + () => 3 +); +!( + () => 3 + /* foo */ +); +!( + () => 3 // foo +); + +function* bar() { + !(yield x); + !(yield x /* foo */); + !(/* foo */ yield x); + !( + /* foo */ + yield x + ); + !( + yield x + /* foo */ + ); + !( + yield x // foo + ); +} + +async function bar() { + !(await x); + !(await x /* foo */); + !(/* foo */ await x); + !( + /* foo */ + await x + ); + !( + await x + /* foo */ + ); + !( + await x // foo + ); +} + +=====================================output===================================== +!x; +!(x /* foo */); +!(/* foo */ x); +!( + /* foo */ + x +); +!( + x + /* foo */ +); +!( + x // foo +); + +!(x + y); +!((x + y) /* foo */); +!(/* foo */ (x + y)); +!( + /* foo */ + (x + y) +); +!( + (x + y) + /* foo */ +); +!( + (x + y) // foo +); + +!(x || y); +!(/* foo */ (x || y)); +!((x || y) /* foo */); +!( + /* foo */ + (x || y) +); +!( + (x || y) + /* foo */ +); +!( + (x || y) // foo +); + +![1, 2, 3]; +!([1, 2, 3] /* foo */); +!(/* foo */ [1, 2, 3]); +!( + /* foo */ + [1, 2, 3] +); +!( + [1, 2, 3] + /* foo */ +); +!( + [1, 2, 3] // foo +); + +!{ a: 1, b: 2 }; +!({ a: 1, b: 2 } /* foo */); +!(/* foo */ { a: 1, b: 2 }); +!( + /* foo */ + { a: 1, b: 2 } +); +!( + { a: 1, b: 2 } + /* foo */ +); +!( + { a: 1, b: 2 } // foo +); + +!function() { + return x; +}; +!( + function() { + return x; + } /* foo */ +); +!( + /* foo */ function() { + return x; + } +); +!( + /* foo */ + function() { + return x; + } +); +!( + function() { + return x; + } + /* foo */ +); +!( + function() { + return x; + } // foo +); + +!+3; +!(+3 /* foo */); +!(/* foo */ +3); +!( + /* foo */ + +3 +); +!( + +3 + /* foo */ +); +!( + +3 // foo +); + +!+( + /* foo */ + 3 +); +!(/* foo */ +(3 /* foo */)); +!(+(3 /* foo */) /* foo */); +!( + /* foo */ + +( + /* foo */ + 3 + ) +); +!( + +( + 3 + /* foo */ + ) + /* foo */ +); +!( + +(3 /* foo */) // foo +); + +!(x = y); +!((x = y) /* foo */); +!(/* foo */ (x = y)); +!( + /* foo */ + (x = y) +); +!( + (x = y) + /* foo */ +); +!( + (x = y) // foo +); + +!x.y; +!(x.y /* foo */); +!(/* foo */ x.y); +!( + /* foo */ + x.y +); +!( + x.y + /* foo */ +); +!( + x.y // foo +); + +!(x ? y : z); +!((x ? y : z) /* foo */); +!(/* foo */ (x ? y : z)); +!( + /* foo */ + (x ? y : z) +); +!( + (x ? y : z) + /* foo */ +); +!( + (x ? y : z) // foo +); + +!x(); +!(x() /* foo */); +!(/* foo */ x()); +!( + /* foo */ + x() +); +!( + x() + /* foo */ +); +!( + x() // foo +); + +!new x(); +!(new x() /* foo */); +!(/* foo */ new x()); +!( + /* foo */ + new x() +); +!( + new x() + /* foo */ +); +!( + new x() // foo +); + +!(x, y); +!((x, y) /* foo */); +!(/* foo */ (x, y)); +!( + /* foo */ + (x, y) +); +!( + (x, y) + /* foo */ +); +!( + x.y // foo +); + +!(() => 3); +!((() => 3) /* foo */); +!(/* foo */ (() => 3)); +!( + /* foo */ + (() => 3) +); +!( + (() => 3) + /* foo */ +); +!( + (() => 3) // foo +); + +function* bar() { + !(yield x); + !((yield x) /* foo */); + !(/* foo */ (yield x)); + !( + /* foo */ + (yield x) + ); + !( + (yield x) + /* foo */ + ); + !( + (yield x) // foo + ); +} + +async function bar() { + !(await x); + !((await x) /* foo */); + !(/* foo */ (await x)); + !( + /* foo */ + (await x) + ); + !( + (await x) + /* foo */ + ); + !( + (await x) // foo + ); +} + +================================================================================ +`; + exports[`urnary_expression.js 1`] = ` ====================================options===================================== parsers: ["flow", "typescript"] diff --git a/tests/unary_expression/comments.js b/tests/unary_expression/comments.js new file mode 100644 index 00000000..5acb1afb --- /dev/null +++ b/tests/unary_expression/comments.js @@ -0,0 +1,285 @@ +!x; +!(x /* foo */); +!(/* foo */ x); +!( + /* foo */ + x +); +!( + x + /* foo */ +); +!( + x // foo +); + +!(x + y); +!(x + y /* foo */); +!(/* foo */ x + y); +!( + /* foo */ + x + y +); +!( + x + y + /* foo */ +); +!( + x + y // foo +); + +!(x || y); +!(/* foo */ x || y); +!(x || y /* foo */); +!( + /* foo */ + x || y +); +!( + x || y + /* foo */ +); +!( + x || y // foo +); + +![1, 2, 3]; +!([1, 2, 3] /* foo */); +!(/* foo */ [1, 2, 3]); +!( + /* foo */ + [1, 2, 3] +); +!( + [1, 2, 3] + /* foo */ +); +!( + [1, 2, 3] // foo +); + +!{ a: 1, b: 2 }; +!({ a: 1, b: 2 } /* foo */); +!(/* foo */ { a: 1, b: 2 }); +!( + /* foo */ + { a: 1, b: 2 } +); +!( + { a: 1, b: 2 } + /* foo */ +); +!( + { a: 1, b: 2 } // foo +) + +!function() { + return x; +}; +!( + function() { + return x; + } /* foo */ +); +!( + /* foo */ function() { + return x; + } +); +!( + /* foo */ + function() { + return x; + } +); +!( + function() { + return x; + } + /* foo */ +); +!( + function() { + return x; + } // foo +) + +!+3; +!(+3 /* foo */); +!(/* foo */ +3); +!( + /* foo */ + +3 +); +!( + +3 + /* foo */ +); +!( + +3 // foo +); + +!+( + /* foo */ + 3 +); +!(/* foo */ +(3 /* foo */)); +!(+(3 /* foo */) /* foo */); +!( + /* foo */ + +( + /* foo */ + 3 + ) +); +!( + +( + 3 + /* foo */ + ) + /* foo */ +); +!( + +( + 3 /* foo */ + ) // foo +); + +!(x = y); +!(x = y /* foo */); +!(/* foo */ x = y); +!( + /* foo */ + x = y +); +!( + x = y + /* foo */ +); +!( + x = y // foo +); + +!x.y; +!(x.y /* foo */); +!(/* foo */ x.y); +!( + /* foo */ + x.y +); +!( + x.y + /* foo */ +); +!( + x.y // foo +); + +!(x ? y : z); +!(x ? y : z /* foo */); +!(/* foo */ x ? y : z); +!( + /* foo */ + x ? y : z +); +!( + x ? y : z + /* foo */ +); +!( + x ? y : z // foo +); + +!x(); +!(x() /* foo */); +!(/* foo */ x()); +!( + /* foo */ + x() +); +!( + x() + /* foo */ +); +!( + x() // foo +); + +!new x(); +!(new x() /* foo */); +!(/* foo */ new x()); +!( + /* foo */ + new x() +); +!( + new x() + /* foo */ +); +!( + new x() // foo +); + +!(x, y); +!(x, y /* foo */); +!(/* foo */ x, y); +!( + /* foo */ + x, y +); +!( + x, y + /* foo */ +); +!( + x.y // foo +); + +!(() => 3); +!(() => 3 /* foo */); +!(/* foo */ () => 3); +!( + /* foo */ + () => 3 +); +!( + () => 3 + /* foo */ +); +!( + () => 3 // foo +); + +function* bar() { + !(yield x); + !(yield x /* foo */); + !(/* foo */ yield x); + !( + /* foo */ + yield x + ); + !( + yield x + /* foo */ + ); + !( + yield x // foo + ); +} + +async function bar() { + !(await x); + !(await x /* foo */); + !(/* foo */ await x); + !( + /* foo */ + await x + ); + !( + await x + /* foo */ + ); + !( + await x // foo + ); +}