From 1c6c6d1e2c61481ff40c35146004c9dd7bab0dd1 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 09:51:56 +0800 Subject: [PATCH 01/10] Add tests --- .../for-of/__snapshots__/jsfmt.spec.js.snap | 25 +++++++++++++++++++ .../format/js/identifier/for-of/jsfmt.spec.js | 5 ++++ tests/format/js/identifier/for-of/let.js | 6 +++++ 3 files changed, 36 insertions(+) create mode 100644 tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/format/js/identifier/for-of/jsfmt.spec.js create mode 100644 tests/format/js/identifier/for-of/let.js diff --git a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000000..545ae278ec0f --- /dev/null +++ b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`let.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +for ((let) of foo); +for (foo of let); +for (foo of let.a); +for (foo of let[a]); +for ((let.a) of foo); +for ((let[a]) of foo); + +=====================================output===================================== +for (let of foo); +for (foo of let); +for (foo of let.a); +for (foo of let[a]); +for (let.a of foo); +for ((let)[a] of foo); + +================================================================================ +`; diff --git a/tests/format/js/identifier/for-of/jsfmt.spec.js b/tests/format/js/identifier/for-of/jsfmt.spec.js new file mode 100644 index 000000000000..0e59aa341125 --- /dev/null +++ b/tests/format/js/identifier/for-of/jsfmt.spec.js @@ -0,0 +1,5 @@ +run_spec(__dirname, [ + "babel", + // "flow", + "typescript", +]); diff --git a/tests/format/js/identifier/for-of/let.js b/tests/format/js/identifier/for-of/let.js new file mode 100644 index 000000000000..ede6a77d3664 --- /dev/null +++ b/tests/format/js/identifier/for-of/let.js @@ -0,0 +1,6 @@ +for ((let) of foo); +for (foo of let); +for (foo of let.a); +for (foo of let[a]); +for ((let.a) of foo); +for ((let[a]) of foo); From 636c4c1445f7160448871c067be57e3b2c6e3e81 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 09:57:03 +0800 Subject: [PATCH 02/10] Fix --- src/language-js/needs-parens.js | 21 +++++++++++++++++-- .../for-of/__snapshots__/jsfmt.spec.js.snap | 4 ++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 7a31778038dc..b6c769cf110e 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -67,16 +67,33 @@ function needsParens(path, options) { return true; } - // `for (async of []);` is invalid + // `for ((async) of []);` and `for ((let) of []);` if ( name === "left" && - node.name === "async" && + (node.name === "async" || node.name === "let") && parent.type === "ForOfStatement" && !parent.await ) { return true; } + // `for ((let.a) of []);` + if (name === "object" && node.name === "let") { + const statement = path.findAncestor( + (node) => node.type === "ForOfStatement" + ); + const expression = statement.left; + if ( + expression && + startsWithNoLookaheadToken( + expression, + (leftmostNode) => leftmostNode === node + ) + ) { + return true; + } + } + // `(let)[a] = 1` if ( name === "object" && diff --git a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap index 545ae278ec0f..dab717a75c58 100644 --- a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap @@ -14,11 +14,11 @@ for ((let.a) of foo); for ((let[a]) of foo); =====================================output===================================== -for (let of foo); +for ((let) of foo); for (foo of let); for (foo of let.a); for (foo of let[a]); -for (let.a of foo); +for ((let).a of foo); for ((let)[a] of foo); ================================================================================ From 8792fd190240007c3b7ff6acffa55804fb67275e Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 10:07:22 +0800 Subject: [PATCH 03/10] for await of --- .../for-of/__snapshots__/jsfmt.spec.js.snap | 24 +++++++++++++++++++ tests/format/js/identifier/for-of/await.js | 6 +++++ 2 files changed, 30 insertions(+) create mode 100644 tests/format/js/identifier/for-of/await.js diff --git a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap index dab717a75c58..f4330e8117fc 100644 --- a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`await.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +async function a() { + for await((let).a of foo); +} +async function b() { + for await((let)[a] of foo); +} + +=====================================output===================================== +async function a() { + for await ((let).a of foo); +} +async function b() { + for await ((let)[a] of foo); +} + +================================================================================ +`; + exports[`let.js format 1`] = ` ====================================options===================================== parsers: ["babel", "typescript"] diff --git a/tests/format/js/identifier/for-of/await.js b/tests/format/js/identifier/for-of/await.js new file mode 100644 index 000000000000..8b8ff85190fe --- /dev/null +++ b/tests/format/js/identifier/for-of/await.js @@ -0,0 +1,6 @@ +async function a() { + for await((let).a of foo); +} +async function b() { + for await((let)[a] of foo); +} From 422e5f4db278f21bd1c9a0c43f86749f85c3ab25 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 10:15:42 +0800 Subject: [PATCH 04/10] Fix --- src/language-js/needs-parens.js | 5 ++--- .../js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap | 6 ++++++ tests/format/js/identifier/for-of/let.js | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index b6c769cf110e..522accea831b 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -79,10 +79,9 @@ function needsParens(path, options) { // `for ((let.a) of []);` if (name === "object" && node.name === "let") { - const statement = path.findAncestor( + const expression = path.findAncestor( (node) => node.type === "ForOfStatement" - ); - const expression = statement.left; + )?.left if ( expression && startsWithNoLookaheadToken( diff --git a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap index f4330e8117fc..f408f6871811 100644 --- a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap @@ -37,6 +37,9 @@ for (foo of let[a]); for ((let.a) of foo); for ((let[a]) of foo); +for ((let.a) in foo); +for ((let[a]) in foo); + =====================================output===================================== for ((let) of foo); for (foo of let); @@ -45,5 +48,8 @@ for (foo of let[a]); for ((let).a of foo); for ((let)[a] of foo); +for (let.a in foo); +for ((let)[a] in foo); + ================================================================================ `; diff --git a/tests/format/js/identifier/for-of/let.js b/tests/format/js/identifier/for-of/let.js index ede6a77d3664..8e40c4e48230 100644 --- a/tests/format/js/identifier/for-of/let.js +++ b/tests/format/js/identifier/for-of/let.js @@ -4,3 +4,6 @@ for (foo of let.a); for (foo of let[a]); for ((let.a) of foo); for ((let[a]) of foo); + +for ((let.a) in foo); +for ((let[a]) in foo); From f9bb4e400e0bbf1a5737f8cdbc2575f6acf37ef6 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 10:21:04 +0800 Subject: [PATCH 05/10] Linting --- src/language-js/needs-parens.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 522accea831b..14b5664136e7 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -81,7 +81,7 @@ function needsParens(path, options) { if (name === "object" && node.name === "let") { const expression = path.findAncestor( (node) => node.type === "ForOfStatement" - )?.left + )?.left; if ( expression && startsWithNoLookaheadToken( From 7ae34837df67594e8dcfc7af3f9a94d725ad1560 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 10:24:10 +0800 Subject: [PATCH 06/10] Check parent type --- src/language-js/needs-parens.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 14b5664136e7..71e366b8ecaa 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -78,7 +78,11 @@ function needsParens(path, options) { } // `for ((let.a) of []);` - if (name === "object" && node.name === "let") { + if ( + name === "object" && + node.name === "let" && + parent.type === "MemberExpression" + ) { const expression = path.findAncestor( (node) => node.type === "ForOfStatement" )?.left; From 707fe329d132ab986649b73a7b7e13e69b6c006c Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 10:27:44 +0800 Subject: [PATCH 07/10] Don't check parent type --- src/language-js/needs-parens.js | 6 +----- .../js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap | 2 ++ tests/format/js/identifier/for-of/let.js | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 71e366b8ecaa..57920577fcf4 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -78,11 +78,7 @@ function needsParens(path, options) { } // `for ((let.a) of []);` - if ( - name === "object" && - node.name === "let" && - parent.type === "MemberExpression" - ) { + if (node.name === "let") { const expression = path.findAncestor( (node) => node.type === "ForOfStatement" )?.left; diff --git a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap index f408f6871811..9620444c31ac 100644 --- a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap @@ -36,6 +36,7 @@ for (foo of let.a); for (foo of let[a]); for ((let.a) of foo); for ((let[a]) of foo); +for ((let)().a of foo); for ((let.a) in foo); for ((let[a]) in foo); @@ -47,6 +48,7 @@ for (foo of let.a); for (foo of let[a]); for ((let).a of foo); for ((let)[a] of foo); +for ((let)().a of foo); for (let.a in foo); for ((let)[a] in foo); diff --git a/tests/format/js/identifier/for-of/let.js b/tests/format/js/identifier/for-of/let.js index 8e40c4e48230..db8682daf9cf 100644 --- a/tests/format/js/identifier/for-of/let.js +++ b/tests/format/js/identifier/for-of/let.js @@ -4,6 +4,7 @@ for (foo of let.a); for (foo of let[a]); for ((let.a) of foo); for ((let[a]) of foo); +for ((let)().a of foo); for ((let.a) in foo); for ((let[a]) in foo); From f1791103c4909bcb2bde2e8e2246b3f11042a55c Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 10:29:10 +0800 Subject: [PATCH 08/10] More tests --- .../js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap | 8 ++++---- tests/format/js/identifier/for-of/await.js | 3 +-- tests/format/js/identifier/for-of/let.js | 1 + 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap index 9620444c31ac..1ccc4806b684 100644 --- a/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/identifier/for-of/__snapshots__/jsfmt.spec.js.snap @@ -8,17 +8,15 @@ printWidth: 80 =====================================input====================================== async function a() { for await((let).a of foo); -} -async function b() { for await((let)[a] of foo); + for await((let)()[a] of foo); } =====================================output===================================== async function a() { for await ((let).a of foo); -} -async function b() { for await ((let)[a] of foo); + for await ((let)()[a] of foo); } ================================================================================ @@ -37,6 +35,7 @@ for (foo of let[a]); for ((let.a) of foo); for ((let[a]) of foo); for ((let)().a of foo); +for (letFoo of foo); for ((let.a) in foo); for ((let[a]) in foo); @@ -49,6 +48,7 @@ for (foo of let[a]); for ((let).a of foo); for ((let)[a] of foo); for ((let)().a of foo); +for (letFoo of foo); for (let.a in foo); for ((let)[a] in foo); diff --git a/tests/format/js/identifier/for-of/await.js b/tests/format/js/identifier/for-of/await.js index 8b8ff85190fe..0fa9d0a508f1 100644 --- a/tests/format/js/identifier/for-of/await.js +++ b/tests/format/js/identifier/for-of/await.js @@ -1,6 +1,5 @@ async function a() { for await((let).a of foo); -} -async function b() { for await((let)[a] of foo); + for await((let)()[a] of foo); } diff --git a/tests/format/js/identifier/for-of/let.js b/tests/format/js/identifier/for-of/let.js index db8682daf9cf..5c2398ee26e0 100644 --- a/tests/format/js/identifier/for-of/let.js +++ b/tests/format/js/identifier/for-of/let.js @@ -5,6 +5,7 @@ for (foo of let[a]); for ((let.a) of foo); for ((let[a]) of foo); for ((let)().a of foo); +for (letFoo of foo); for ((let.a) in foo); for ((let[a]) in foo); From 89a0bbe64d80518d72fe830162e4cc44b88a1779 Mon Sep 17 00:00:00 2001 From: fisker Date: Thu, 22 Dec 2022 10:38:09 +0800 Subject: [PATCH 09/10] Add PR number to change log --- changelog_unreleased/javascript/14000.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog_unreleased/javascript/14000.md b/changelog_unreleased/javascript/14000.md index a8388fda0f1a..914800969a96 100644 --- a/changelog_unreleased/javascript/14000.md +++ b/changelog_unreleased/javascript/14000.md @@ -1,4 +1,4 @@ -#### Fix missing parentheses when an expression statement starts with `let[` (#14000 by @fisker, @thorn0) +#### Fix missing parentheses when an expression statement starts with `let[` (#14000, #14044 by @fisker, @thorn0) ```jsx From a05f885a5088dcce50d9b6f91300490d298cd53a Mon Sep 17 00:00:00 2001 From: Georgii Dolzhykov Date: Thu, 22 Dec 2022 22:05:33 +0200 Subject: [PATCH 10/10] Remove an unused line --- src/language-js/needs-parens.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 57920577fcf4..02b8bf7ac1a6 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -105,8 +105,7 @@ function needsParens(path, options) { (node) => node.type === "ExpressionStatement" || node.type === "ForStatement" || - node.type === "ForInStatement" || - node.type === "ForOfStatement" + node.type === "ForInStatement" ); const expression = !statement ? undefined