From 1e471a007968b7490563b91ed6909ae6046f3fe8 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Thu, 28 Mar 2019 11:06:39 -0700 Subject: [PATCH] Add parentheses for immediately-constructed fn/class (#5996) --- CHANGELOG.unreleased.md | 16 ++++++++++++++++ src/language-js/needs-parens.js | 10 +++++++++- tests/classes/__snapshots__/jsfmt.spec.js.snap | 16 ++++++++++++++++ tests/classes/new.js | 2 ++ .../flow/async/__snapshots__/jsfmt.spec.js.snap | 6 +++--- tests/function/__snapshots__/jsfmt.spec.js.snap | 4 ++-- 6 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 tests/classes/new.js diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index ee4dd2be..f3a3215d 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -42,6 +42,22 @@ Examples: --> +- JavaScript: Add parentheses for immediately-constructed fn/class ([#5996] by [@bakkot]) + + ``` + // Input + new class {}; + new function() {} + + // Output (Prettier stable) + new class {}(); + new function() {}(); + + // Output (Prettier master) + new (class {})(); + new (function() {})(); + ``` + - Config: Support shared configurations ([#5963] by [@azz]) Sharing a Prettier configuration is simple: just publish a module that exports a configuration object, say `@company/prettier-config`, and reference it in your `package.json`: diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 1887e9c1..4ad67228 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -610,6 +610,7 @@ function needsParens(path, options) { case "FunctionExpression": switch (parent.type) { + case "NewExpression": case "CallExpression": return name === "callee"; // Not strictly necessary, but it's clearer to the reader if IIFEs are wrapped in parentheses. case "TaggedTemplateExpression": @@ -649,7 +650,14 @@ function needsParens(path, options) { } case "ClassExpression": - return parent.type === "ExportDefaultDeclaration"; + switch (parent.type) { + case "ExportDefaultDeclaration": + return true; + case "NewExpression": + return name === "callee" && parent.callee === node; + default: + return false; + } case "OptionalMemberExpression": return parent.type === "MemberExpression"; diff --git a/tests/classes/__snapshots__/jsfmt.spec.js.snap b/tests/classes/__snapshots__/jsfmt.spec.js.snap index 02c20513..b4bd62dc 100644 --- a/tests/classes/__snapshots__/jsfmt.spec.js.snap +++ b/tests/classes/__snapshots__/jsfmt.spec.js.snap @@ -203,6 +203,22 @@ class C { ================================================================================ `; +exports[`new.js 1`] = ` +====================================options===================================== +parsers: ["flow", "babel", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +new class {}; +new Ctor(class {}); + +=====================================output===================================== +new (class {})(); +new Ctor(class {}); + +================================================================================ +`; + exports[`property.js 1`] = ` ====================================options===================================== parsers: ["flow", "babel", "typescript"] diff --git a/tests/classes/new.js b/tests/classes/new.js new file mode 100644 index 00000000..23317a98 --- /dev/null +++ b/tests/classes/new.js @@ -0,0 +1,2 @@ +new class {}; +new Ctor(class {}); diff --git a/tests/flow/async/__snapshots__/jsfmt.spec.js.snap b/tests/flow/async/__snapshots__/jsfmt.spec.js.snap index cf423abb..e0781b82 100644 --- a/tests/flow/async/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/async/__snapshots__/jsfmt.spec.js.snap @@ -209,7 +209,7 @@ class C { var e = async function() {}; var et = async function(a: T) {}; -var n = new async function() {}(); +var n = new (async function() {})(); var o = { async m() {} }; var ot = { async m(a: T) {} }; @@ -552,9 +552,9 @@ var et = async function(a: T) { await 1; }; -var n = new async function() { +var n = new (async function() { await 1; -}(); +})(); var o = { async m() { diff --git a/tests/function/__snapshots__/jsfmt.spec.js.snap b/tests/function/__snapshots__/jsfmt.spec.js.snap index 2e5f56c8..2ddbba07 100644 --- a/tests/function/__snapshots__/jsfmt.spec.js.snap +++ b/tests/function/__snapshots__/jsfmt.spec.js.snap @@ -24,12 +24,12 @@ typeof function() {}; export default (function() {})(); (function() {})()\`\`; (function() {})\`\`; -new function() {}(); +new (function() {})(); (function() {}); a = function f() {} || b; (function() {} && a); a + function() {}; -new function() {}(); +new (function() {})(); ================================================================================ `;