From 96f7a375bd0a75d93671bb1af412c757bd4edf7b Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 5 Jun 2026 17:16:35 +0800 Subject: [PATCH] Fix edge cases for parentheses in new expressions (#19295) --- .../parentheses/needs-parentheses.js | 2 ++ .../__snapshots__/format.test.js.snap | 16 ++++++++++++++++ .../format/js/bind-expressions/bind_parens.js | 4 ++++ .../__snapshots__/format.test.js.snap | 19 ++++++++++++++++++- .../{new_expression.js => new-expression.js} | 0 tests/format/js/new-expression/parentheses.js | 3 +++ .../new/__snapshots__/format.test.js.snap | 17 +++++++++++++++++ tests/format/typescript/new/parentheses.ts | 3 +++ 8 files changed, 63 insertions(+), 1 deletion(-) rename tests/format/js/new-expression/{new_expression.js => new-expression.js} (100%) create mode 100644 tests/format/js/new-expression/parentheses.js create mode 100644 tests/format/typescript/new/parentheses.ts diff --git a/src/language-js/parentheses/needs-parentheses.js b/src/language-js/parentheses/needs-parentheses.js index 971fc6f5b..ba4380214 100644 --- a/src/language-js/parentheses/needs-parentheses.js +++ b/src/language-js/parentheses/needs-parentheses.js @@ -787,6 +787,7 @@ function needsParentheses(path, options) { case "CallExpression": case "MemberExpression": case "TaggedTemplateExpression": + case "ImportExpression": if ( key === "callee" && (parent.type === "BindExpression" || parent.type === "NewExpression") @@ -795,6 +796,7 @@ function needsParentheses(path, options) { while (object) { switch (object.type) { case "CallExpression": + case "ImportExpression": return true; case "MemberExpression": case "OptionalMemberExpression": diff --git a/tests/format/js/bind-expressions/__snapshots__/format.test.js.snap b/tests/format/js/bind-expressions/__snapshots__/format.test.js.snap index e7480b4db..2ab81eaed 100644 --- a/tests/format/js/bind-expressions/__snapshots__/format.test.js.snap +++ b/tests/format/js/bind-expressions/__snapshots__/format.test.js.snap @@ -166,6 +166,10 @@ new f(a::b); f[a::b]; f[a::b()]; +a::(import("foo")); +a::(import("foo").bar); +a::(import("foo")\`bar\`); + =====================================output===================================== ;(a || b)::c a || b::c @@ -202,6 +206,10 @@ new f(a::b) f[a::b] f[a::b()] +a::(import("foo")) +a::(import("foo").bar) +a::(import("foo")\`bar\`) + ================================================================================ `; @@ -284,6 +292,10 @@ new f(a::b); f[a::b]; f[a::b()]; +a::(import("foo")); +a::(import("foo").bar); +a::(import("foo")\`bar\`); + =====================================output===================================== (a || b)::c; a || b::c; @@ -320,6 +332,10 @@ new f(a::b); f[a::b]; f[a::b()]; +a::(import("foo")); +a::(import("foo").bar); +a::(import("foo")\`bar\`); + ================================================================================ `; diff --git a/tests/format/js/bind-expressions/bind_parens.js b/tests/format/js/bind-expressions/bind_parens.js index 72f13543e..fa3a865bf 100644 --- a/tests/format/js/bind-expressions/bind_parens.js +++ b/tests/format/js/bind-expressions/bind_parens.js @@ -32,3 +32,7 @@ new (a::b)(); new f(a::b); f[a::b]; f[a::b()]; + +a::(import("foo")); +a::(import("foo").bar); +a::(import("foo")`bar`); diff --git a/tests/format/js/new-expression/__snapshots__/format.test.js.snap b/tests/format/js/new-expression/__snapshots__/format.test.js.snap index 0fdeec86d..72ac5f64f 100644 --- a/tests/format/js/new-expression/__snapshots__/format.test.js.snap +++ b/tests/format/js/new-expression/__snapshots__/format.test.js.snap @@ -19,7 +19,7 @@ new (factory())(factory()); ================================================================================ `; -exports[`new_expression.js format 1`] = ` +exports[`new-expression.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] printWidth: 80 (default) | @@ -48,6 +48,23 @@ new (a\`\`())(); ================================================================================ `; +exports[`parentheses.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] + printWidth: 80 (default) | +=====================================input====================================== +new (import("foo"))(); +new (import("foo").bar)(); +new (import("foo")\`bar\`)(); + +=====================================output===================================== +new (import("foo"))(); +new (import("foo").bar)(); +new (import("foo")\`bar\`)(); + +================================================================================ +`; + exports[`with-member-expression.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] diff --git a/tests/format/js/new-expression/new_expression.js b/tests/format/js/new-expression/new-expression.js similarity index 100% rename from tests/format/js/new-expression/new_expression.js rename to tests/format/js/new-expression/new-expression.js diff --git a/tests/format/js/new-expression/parentheses.js b/tests/format/js/new-expression/parentheses.js new file mode 100644 index 000000000..c4de102c5 --- /dev/null +++ b/tests/format/js/new-expression/parentheses.js @@ -0,0 +1,3 @@ +new (import("foo"))(); +new (import("foo").bar)(); +new (import("foo")`bar`)(); diff --git a/tests/format/typescript/new/__snapshots__/format.test.js.snap b/tests/format/typescript/new/__snapshots__/format.test.js.snap index 148111ebc..f2187bcc3 100644 --- a/tests/format/typescript/new/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/new/__snapshots__/format.test.js.snap @@ -140,6 +140,23 @@ interface TimerConstructor { ================================================================================ `; +exports[`parentheses.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] + printWidth: 80 (default) | +=====================================input====================================== +new (import("foo")!)(); +new (import("foo")!.bar)(); +new (import("foo")!\`bar\`)(); + +=====================================output===================================== +new (import("foo")!)(); +new (import("foo")!.bar)(); +new (import("foo")!\`bar\`)(); + +================================================================================ +`; + exports[`with-member-expression.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/format/typescript/new/parentheses.ts b/tests/format/typescript/new/parentheses.ts new file mode 100644 index 000000000..037a4a829 --- /dev/null +++ b/tests/format/typescript/new/parentheses.ts @@ -0,0 +1,3 @@ +new (import("foo")!)(); +new (import("foo")!.bar)(); +new (import("foo")!`bar`)();