Skip to content

Commit

Permalink
Add parens to head of ExpressionStatement instead of whole statement (
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker authored and medikoo committed Jan 4, 2024
1 parent 6703e4b commit d23585e
Show file tree
Hide file tree
Showing 17 changed files with 98 additions and 74 deletions.
19 changes: 19 additions & 0 deletions changelog_unreleased/javascript/14077.md
@@ -0,0 +1,19 @@
#### Add parentheses to head of `ExpressionStatement` instead of the whole statement (#14077 by @fisker)

<!-- prettier-ignore -->
```jsx
// Input
({}).toString.call(foo) === "[object Array]"
? foo.forEach(iterateArray)
: iterateObject(foo);

// Prettier stable
({}.toString.call(foo) === "[object Array]"
? foo.forEach(iterateArray)
: iterateObject(foo));

// Prettier main
({}).toString.call(foo.forEach) === "[object Array]"
? foo.forEach(iterateArray)
: iterateObject(foo);
```
35 changes: 20 additions & 15 deletions src/language-js/needs-parens.js
Expand Up @@ -127,6 +127,26 @@ function needsParens(path, options) {
return false;
}

if (
node.type === "ObjectExpression" ||
node.type === "FunctionExpression" ||
node.type === "ClassExpression" ||
node.type === "DoExpression"
) {
const expression = path.findAncestor(
(node) => node.type === "ExpressionStatement"
)?.expression;
if (
expression &&
startsWithNoLookaheadToken(
expression,
(leftmostNode) => leftmostNode === node
)
) {
return true;
}
}

switch (parent.type) {
case "ParenthesizedExpression":
return false;
Expand Down Expand Up @@ -200,21 +220,6 @@ function needsParens(path, options) {
}
break;
}
case "ExpressionStatement": {
if (
startsWithNoLookaheadToken(
node,
(node) =>
node.type === "ObjectExpression" ||
node.type === "FunctionExpression" ||
node.type === "ClassExpression" ||
node.type === "DoExpression"
)
) {
return true;
}
break;
}
case "ArrowFunctionExpression": {
if (
name === "body" &&
Expand Down
8 changes: 4 additions & 4 deletions tests/format/flow-repo/arith/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -156,7 +156,7 @@ let tests = [
x + ""; // error
"" + x; // error
x + {}; // error
({} + x); // error
({}) + x; // error
},
// when one side is a string or number and the other is invalid, we
Expand Down Expand Up @@ -322,10 +322,10 @@ let tests = [
"foo" < 1; // error
"foo" < "bar";
1 < { foo: 1 }; // error
({ foo: 1 } < 1); // error
({ foo: 1 } < { foo: 1 }); // error
({ foo: 1 }) < 1; // error
({ foo: 1 }) < { foo: 1 }; // error
"foo" < { foo: 1 }; // error
({ foo: 1 } < "foo"); // error
({ foo: 1 }) < "foo"; // error
var x = (null: ?number);
1 < x; // 2 errors: null !~> number; undefined !~> number
Expand Down
Expand Up @@ -98,7 +98,7 @@ let tests = [
function () {
null in {}; // error
void 0 in {}; // error
({} in {}); // error
({}) in {}; // error
[] in {}; // error
false in []; // error
},
Expand Down
Expand Up @@ -143,7 +143,7 @@ function foo() { this.m(); }
function bar(f: () => void) {
f(); // passing global object as \`this\`
({ f }.f()); // passing container object as \`this\`
({ f }).f(); // passing container object as \`this\`
}
bar(foo); // error, since \`this\` is used non-trivially in \`foo\`
Expand Down
16 changes: 8 additions & 8 deletions tests/format/js/classes/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -101,10 +101,10 @@ printWidth: 80
(class a extends b {}) + 1;
=====================================output=====================================
(class {} + 1);
(class a {} + 1);
(class extends b {} + 1);
(class a extends b {} + 1);
(class {}) + 1;
(class a {}) + 1;
(class extends b {}) + 1;
(class a extends b {}) + 1;
================================================================================
`;
Expand All @@ -118,7 +118,7 @@ printWidth: 80
(class {})(class {});
=====================================output=====================================
(class {}(class {}));
(class {})(class {});
================================================================================
`;
Expand Down Expand Up @@ -209,8 +209,8 @@ printWidth: 80
(class {}).a;
=====================================output=====================================
(class {}[1]);
(class {}.a);
(class {})[1];
(class {}).a;
================================================================================
`;
Expand Down Expand Up @@ -336,7 +336,7 @@ printWidth: 80
if (1) (class {}) ? 1 : 2;
=====================================output=====================================
if (1) (class {} ? 1 : 2);
if (1) (class {}) ? 1 : 2;
================================================================================
`;
Expand Up @@ -375,14 +375,14 @@ semi: false
(@deco class {}).name;
=====================================output=====================================
;((
;(
@deco
class Foo {}
).name)
;((
).name
;(
@deco
class {}
).name)
).name
================================================================================
`;
Expand All @@ -397,14 +397,14 @@ printWidth: 80
(@deco class {}).name;
=====================================output=====================================
((
(
@deco
class Foo {}
).name);
((
).name;
(
@deco
class {}
).name);
).name;
================================================================================
`;
Expand Down
2 changes: 1 addition & 1 deletion tests/format/js/do/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -250,7 +250,7 @@ function foo() {
}
(do {});
(do {} + 1);
(do {}) + 1;
1 + do {};
() => do {};
Expand Down
4 changes: 2 additions & 2 deletions tests/format/js/function/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -19,15 +19,15 @@ a + function() {};
new function() {};
=====================================output=====================================
(function () {}.length);
(function () {}).length;
typeof function () {};
export default (function () {})();
(function () {})()\`\`;
(function () {})\`\`;
new (function () {})();
(function () {});
a = function f() {} || b;
(function () {} && a);
(function () {}) && a;
a + function () {};
new (function () {})();
Expand Down
4 changes: 2 additions & 2 deletions tests/format/js/method-chain/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -1455,8 +1455,8 @@ method().then(x => x)
=====================================output=====================================
method().then((x) => x)["abc"]((x) => x)[abc]((x) => x);
({}.a().b());
({}.a().b());
({}).a().b();
({}).a().b();
================================================================================
`;
Expand Down
8 changes: 4 additions & 4 deletions tests/format/js/no-semi/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -727,9 +727,9 @@ x
x
;(() => {})()
x
;({ a: 1 }.entries())
;({ a: 1 }).entries()
x
;({ a: 1 }.entries())
;({ a: 1 }).entries()
x
;<Hello />
x
Expand Down Expand Up @@ -910,9 +910,9 @@ x;
x;
(() => {})();
x;
({ a: 1 }.entries());
({ a: 1 }).entries();
x;
({ a: 1 }.entries());
({ a: 1 }).entries();
x;
<Hello />;
x;
Expand Down
10 changes: 5 additions & 5 deletions tests/format/js/objects/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -125,12 +125,12 @@ const a3 = {
=====================================output=====================================
() => ({}\`\`);
({}\`\`);
({})\`\`;
a = () => ({}.x);
({} && a, b);
({}::b, 0);
({}::b()\`\`[""].c++ && 0 ? 0 : 0, 0);
({}(), 0);
({}) && a, b;
({})::b, 0;
({})::b()\`\`[""].c++ && 0 ? 0 : 0, 0;
({})(), 0;
({} = 0);
({} = 0), 1;
Expand Down
Expand Up @@ -172,8 +172,8 @@ a = () => ({}?.b() && a);
(x) => ({}?.().b);
(x) => ({}?.b());
(x) => ({}?.b.b);
({}?.a().b());
({ a: 1 }?.entries());
({})?.a().b();
({ a: 1 })?.entries();
new (foo?.bar)();
new (foo?.bar())();
Expand Down
4 changes: 2 additions & 2 deletions tests/format/js/template/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -388,7 +388,7 @@ async function f() { (await b)\`\`; }
b()\`\`;
// "ClassExpression"
(class {}\`\`);
(class {})\`\`;
// "ConditionalExpression"
(b ? c : d)\`\`;
Expand All @@ -406,7 +406,7 @@ b.c\`\`;
new B()\`\`;
// "ObjectExpression"
({}\`\`);
({})\`\`;
// "SequenceExpression"
(b, c)\`\`;
Expand Down
22 changes: 11 additions & 11 deletions tests/format/typescript/as/__snapshots__/jsfmt.spec.js.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`array-pattern.ts format 1`] = `
exports["array-pattern.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand All @@ -14,7 +14,7 @@ printWidth: 80
================================================================================
`;

exports[`as.ts format 1`] = `
exports["as.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand Down Expand Up @@ -81,10 +81,10 @@ export default class Column<T> extends (RcTable.Column as React.ComponentClass<
>) {}
export const MobxTypedForm = class extends (Form as { new (): any }) {};
export abstract class MobxTypedForm1 extends (Form as { new (): any }) {}
({} as {});
({}) as {};
function* g() { const test = (yield "foo") as number; }
async function g1() { const test = (await "foo") as number; }
({} as X);
({}) as X;
() => ({} as X);
const state = JSON.stringify({ next: window.location.href, nonce } as State);
Expand Down Expand Up @@ -121,7 +121,7 @@ const iter2 = createIterator(
================================================================================
`;
exports[`assignment.ts format 1`] = `
exports["assignment.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand Down Expand Up @@ -191,7 +191,7 @@ this.intervalID = setInterval(() => { self.step(); }, 30) as unknown as number;
================================================================================
`;
exports[`assignment2.ts format 1`] = `
exports["assignment2.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand Down Expand Up @@ -265,7 +265,7 @@ const originalPrototype = originalConstructor.prototype as TComponent &
================================================================================
`;
exports[`export_default_as.ts format 1`] = `
exports["export_default_as.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand All @@ -279,7 +279,7 @@ export default (function log() {} as typeof console.log);
================================================================================
`;
exports[`long-identifiers.ts format 1`] = `
exports["long-identifiers.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand Down Expand Up @@ -320,7 +320,7 @@ averredBathersBoxroomBuggyNurl(
================================================================================
`;
exports[`nested-await-and-as.ts format 1`] = `
exports["nested-await-and-as.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand All @@ -347,7 +347,7 @@ const getAccountCount = async () =>
================================================================================
`;
exports[`return.ts format 1`] = `
exports["return.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand All @@ -366,7 +366,7 @@ function foo() { return { foo: 1, bar: 2 } as Foo; }
================================================================================
`;
exports[`ternary.ts format 1`] = `
exports["ternary.ts format 1"] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
Expand Down

0 comments on commit d23585e

Please sign in to comment.