Skip to content

Commit

Permalink
Add parens to head of arrow function body instead of whole expression (
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed Mar 29, 2023
1 parent 9500403 commit 3f1153b
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 62 deletions.
13 changes: 13 additions & 0 deletions changelog_unreleased/javascript/14599.md
@@ -0,0 +1,13 @@
#### Add parentheses to head of `ExpressionStatement` instead of the whole statement (#14599 by @fisker)

<!-- prettier-ignore -->
```jsx
// Input
const isArray = (object) => ({}).toString.call(foo) === "[object Array]";

// Prettier stable
const isArray = (object) => ({}.toString.call(foo) === "[object Array]");

// Prettier main
const isArray = (object) => ({}).toString.call(foo) === "[object Array]";
```
30 changes: 17 additions & 13 deletions src/language-js/needs-parens.js
Expand Up @@ -133,6 +133,23 @@ function needsParens(path, options) {
}
}

if (node.type === "ObjectExpression") {
const arrowFunctionBody = path.findAncestor(
(node) => node.type === "ArrowFunctionExpression"
)?.body;
if (
arrowFunctionBody &&
arrowFunctionBody.type !== "SequenceExpression" && // these have parens added anyway
arrowFunctionBody.type !== "AssignmentExpression" &&
startsWithNoLookaheadToken(
arrowFunctionBody,
(leftmostNode) => leftmostNode === node
)
) {
return true;
}
}

switch (parent.type) {
case "ParenthesizedExpression":
return false;
Expand Down Expand Up @@ -211,19 +228,6 @@ function needsParens(path, options) {
}
break;

case "ArrowFunctionExpression":
if (
key === "body" &&
node.type !== "SequenceExpression" && // these have parens added anyway
startsWithNoLookaheadToken(
node,
(node) => node.type === "ObjectExpression"
)
) {
return true;
}
break;

case "TypeAnnotation":
if (
path.match(
Expand Down
Expand Up @@ -38,7 +38,7 @@ a => ({}::b()\`\`[''].c++ && 0 ? 0 : 0);
a::(b => c);
=====================================output=====================================
(a) => ({}::b()\`\`[""].c++ && 0 ? 0 : 0);
(a) => ({})::b()\`\`[""].c++ && 0 ? 0 : 0;
((a) => b)::c;
a::((b) => c);
Expand Down
56 changes: 28 additions & 28 deletions tests/format/js/arrows/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -51,24 +51,24 @@ export default (() => {})();
new (() => {})();
if ((() => {}) ? 1 : 0) {
}
let f = () => ({}());
let a = () => ({} instanceof a);
a = () => ({} && a);
a = () => ({}() && a);
a = () => ({} && a && b);
a = () => ({} + a);
a = () => ({}()() && a);
a = () => ({}.b && a);
a = () => ({}[b] && a);
a = () => ({}\`\` && a);
let f = () => ({})();
let a = () => ({}) instanceof a;
a = () => ({}) && a;
a = () => ({})() && a;
a = () => ({}) && a && b;
a = () => ({}) + a;
a = () => ({})()() && a;
a = () => ({}).b && a;
a = () => ({})[b] && a;
a = () => ({})\`\` && a;
a = () => ({} = 0);
a = () => ({}, a);
(a) => a instanceof {};
(a) => ({}().b && 0);
(a) => ({})().b && 0;
(a) => ({}().c = 0);
(x) => ({}()());
(x) => ({}()\`\`);
(x) => ({}().b);
(x) => ({})()();
(x) => ({})()\`\`;
(x) => ({})().b;
a = (b) => c;
(x) => (y = z);
(x) => (y += z);
Expand Down Expand Up @@ -133,24 +133,24 @@ export default (() => {})();
new (() => {})();
if ((() => {}) ? 1 : 0) {
}
let f = () => ({}());
let a = () => ({} instanceof a);
a = () => ({} && a);
a = () => ({}() && a);
a = () => ({} && a && b);
a = () => ({} + a);
a = () => ({}()() && a);
a = () => ({}.b && a);
a = () => ({}[b] && a);
a = () => ({}\`\` && a);
let f = () => ({})();
let a = () => ({}) instanceof a;
a = () => ({}) && a;
a = () => ({})() && a;
a = () => ({}) && a && b;
a = () => ({}) + a;
a = () => ({})()() && a;
a = () => ({}).b && a;
a = () => ({})[b] && a;
a = () => ({})\`\` && a;
a = () => ({} = 0);
a = () => ({}, a);
a => a instanceof {};
a => ({}().b && 0);
a => ({})().b && 0;
a => ({}().c = 0);
x => ({}()());
x => ({}()\`\`);
x => ({}().b);
x => ({})()();
x => ({})()\`\`;
x => ({})().b;
a = b => c;
x => (y = z);
x => (y += z);
Expand Down
4 changes: 2 additions & 2 deletions tests/format/js/objects/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -166,9 +166,9 @@ const a3 = {
};
=====================================output=====================================
() => ({}\`\`);
() => ({})\`\`;
({})\`\`;
a = () => ({}.x);
a = () => ({}).x;
({}) && a, b;
({})::b, 0;
({})::b()\`\`[""].c++ && 0 ? 0 : 0, 0;
Expand Down
26 changes: 13 additions & 13 deletions tests/format/js/optional-chaining/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -159,19 +159,19 @@ a?.[b ? c : d];
aaaaaaaaaaaaaaaaaaaaaaaa
)?.();
let f = () => ({}?.());
let g = () => ({}?.b);
a = () => ({}?.() && a);
a = () => ({}?.()() && a);
a = () => ({}?.().b && a);
a = () => ({}?.b && a);
a = () => ({}?.b() && a);
(a) => ({}?.()?.b && 0);
(a) => ({}?.b?.b && 0);
(x) => ({}?.()());
(x) => ({}?.().b);
(x) => ({}?.b());
(x) => ({}?.b.b);
let f = () => ({})?.();
let g = () => ({})?.b;
a = () => ({})?.() && a;
a = () => ({})?.()() && a;
a = () => ({})?.().b && a;
a = () => ({})?.b && a;
a = () => ({})?.b() && a;
(a) => ({})?.()?.b && 0;
(a) => ({})?.b?.b && 0;
(x) => ({})?.()();
(x) => ({})?.().b;
(x) => ({})?.b();
(x) => ({})?.b.b;
({})?.a().b();
({ a: 1 })?.entries();
Expand Down
Expand Up @@ -89,7 +89,7 @@ async function g1() {
const test = (await "foo") as number;
}
({}) as X;
() => ({} as X);
() => ({}) as X;
const state = JSON.stringify({
next: window.location.href,
nonce,
Expand Down
Expand Up @@ -27,9 +27,9 @@ const myFunction2 = (key: string): number =>
({
a: 42,
b: 42,
}[key]!);
})[key]!;
const myFunction3 = (key) => ({}!.a);
const myFunction3 = (key) => ({})!.a;
const f = ((a) => {
log(a);
Expand Down
Expand Up @@ -756,7 +756,7 @@ foo as unknown satisfies Bar;
=====================================output=====================================
;({}) satisfies {}
;({}) satisfies X
;() => ({} satisfies X)
;() => ({}) satisfies X
this.isTabActionBar((e.target || e.srcElement) satisfies HTMLElement)
"current" in (props.pagination satisfies Object)
Expand Down Expand Up @@ -812,7 +812,7 @@ foo as unknown satisfies Bar;
=====================================output=====================================
({}) satisfies {};
({}) satisfies X;
() => ({} satisfies X);
() => ({}) satisfies X;
this.isTabActionBar((e.target || e.srcElement) satisfies HTMLElement);
"current" in (props.pagination satisfies Object);
Expand Down

0 comments on commit 3f1153b

Please sign in to comment.