From 0e6eacd34a037bd1620626c5c0384ee78a8dcea4 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Fri, 4 Feb 2022 15:38:03 +0800 Subject: [PATCH 1/4] Fix destructuring with `hole` in assign pattern - fix `const` assign pattern - optimize the output of `let`/`var` assign pattern --- .../src/index.ts | 8 +++++ .../fixtures/destructuring/init-hole/exec.js | 33 +++++++++++++++++++ .../fixtures/destructuring/init-hole/input.js | 33 +++++++++++++++++++ .../destructuring/init-hole/options.json | 3 ++ .../destructuring/init-hole/output.js | 33 +++++++++++++++++++ 5 files changed, 110 insertions(+) create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/options.json create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js diff --git a/packages/babel-plugin-transform-destructuring/src/index.ts b/packages/babel-plugin-transform-destructuring/src/index.ts index 959e8fbf2ec8..acfaaead7258 100644 --- a/packages/babel-plugin-transform-destructuring/src/index.ts +++ b/packages/babel-plugin-transform-destructuring/src/index.ts @@ -158,6 +158,14 @@ export default declare((api, options) => { } pushAssignmentPattern({ left, right }, valueRef) { + // handle array init hole + // const [x = 42] = [,]; + // -> const x = 42; + if (valueRef === null) { + this.nodes.push(this.buildVariableAssignment(left, right)); + return; + } + // we need to assign the current value of the assignment to avoid evaluating // it more than once const tempId = this.scope.generateUidIdentifierBasedOnNode(valueRef); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js new file mode 100644 index 000000000000..ffd1579fa662 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js @@ -0,0 +1,33 @@ +let [x = 23] = [,]; +expect(x).toEqual(23); + +const [y = 24, z] = [, 42]; +expect(y).toEqual(24); +expect(z).toEqual(42); + +function* foo() { + yield 1; + yield 2; +} + +let bar = foo(); + +const [a = bar.next().value, b] = [, bar.next().value]; + +expect(a).toEqual(2); +expect(b).toEqual(1); + +const arr = [c = 42] = [,]; +expect(c).toEqual(42); +expect(arr).toEqual([,]); + +var iterCount = 0; + +for (const [x = 23] = [,]; iterCount < 1; ) { + expect(x).toEqual(23); + // another statement + + iterCount += 1; +} + +expect(iterCount).toEqual(1); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js new file mode 100644 index 000000000000..ffd1579fa662 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js @@ -0,0 +1,33 @@ +let [x = 23] = [,]; +expect(x).toEqual(23); + +const [y = 24, z] = [, 42]; +expect(y).toEqual(24); +expect(z).toEqual(42); + +function* foo() { + yield 1; + yield 2; +} + +let bar = foo(); + +const [a = bar.next().value, b] = [, bar.next().value]; + +expect(a).toEqual(2); +expect(b).toEqual(1); + +const arr = [c = 42] = [,]; +expect(c).toEqual(42); +expect(arr).toEqual([,]); + +var iterCount = 0; + +for (const [x = 23] = [,]; iterCount < 1; ) { + expect(x).toEqual(23); + // another statement + + iterCount += 1; +} + +expect(iterCount).toEqual(1); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/options.json new file mode 100644 index 000000000000..84e28c07f51e --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-destructuring"] +} diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js new file mode 100644 index 000000000000..192748420952 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js @@ -0,0 +1,33 @@ +var _ref2, _ref2$; + +let x = 23; +expect(x).toEqual(23); +const y = 24, + z = 42; +expect(y).toEqual(24); +expect(z).toEqual(42); + +function* foo() { + yield 1; + yield 2; +} + +let bar = foo(); +const _ref = [, bar.next().value], + _ref$ = _ref[0], + a = _ref$ === void 0 ? bar.next().value : _ref$, + b = _ref[1]; +expect(a).toEqual(2); +expect(b).toEqual(1); +const arr = (_ref2 = [,], _ref2$ = _ref2[0], c = _ref2$ === void 0 ? 42 : _ref2$, _ref2); +expect(c).toEqual(42); +expect(arr).toEqual([,]); +var iterCount = 0; + +for (const x = 23; iterCount < 1;) { + expect(x).toEqual(23); // another statement + + iterCount += 1; +} + +expect(iterCount).toEqual(1); From 52a9d39bcb3aef74bbf474614b3b7a934780d746 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Wed, 9 Feb 2022 10:36:56 +0800 Subject: [PATCH 2/4] chore: add test cases --- .../test/fixtures/destructuring/init-hole/exec.js | 6 ++++++ .../test/fixtures/destructuring/init-hole/input.js | 6 ++++++ .../test/fixtures/destructuring/init-hole/output.js | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js index ffd1579fa662..dcd9ae003362 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js @@ -31,3 +31,9 @@ for (const [x = 23] = [,]; iterCount < 1; ) { } expect(iterCount).toEqual(1); + +const [...d] = [,]; +const [...{ 0: e }] = [,]; + +expect(d).toEqual([,]); +expect(e).toEqual(undefined); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js index ffd1579fa662..dcd9ae003362 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js @@ -31,3 +31,9 @@ for (const [x = 23] = [,]; iterCount < 1; ) { } expect(iterCount).toEqual(1); + +const [...d] = [,]; +const [...{ 0: e }] = [,]; + +expect(d).toEqual([,]); +expect(e).toEqual(undefined); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js index 192748420952..8d828dc07a71 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js @@ -31,3 +31,7 @@ for (const x = 23; iterCount < 1;) { } expect(iterCount).toEqual(1); +const d = [,]; +const e = [,][0]; +expect(d).toEqual([,]); +expect(e).toEqual(undefined); From 4fc6f73922ae9ce1161a63dccd09d1072794b8ba Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 10 Feb 2022 10:28:12 +0800 Subject: [PATCH 3/4] Fix const destructuring `hole` without default value --- packages/babel-plugin-transform-destructuring/src/index.ts | 4 ++++ .../test/fixtures/destructuring/init-hole/exec.js | 6 ++++++ .../test/fixtures/destructuring/init-hole/input.js | 6 ++++++ .../test/fixtures/destructuring/init-hole/output.js | 4 ++++ 4 files changed, 20 insertions(+) diff --git a/packages/babel-plugin-transform-destructuring/src/index.ts b/packages/babel-plugin-transform-destructuring/src/index.ts index acfaaead7258..63ce1f1d0b7a 100644 --- a/packages/babel-plugin-transform-destructuring/src/index.ts +++ b/packages/babel-plugin-transform-destructuring/src/index.ts @@ -114,6 +114,10 @@ export default declare((api, options) => { ), ); } else { + if (this.kind === "const" && init === null) { + init = this.scope.buildUndefinedNode(); + } + node = t.variableDeclaration(this.kind, [ t.variableDeclarator(id, t.cloneNode(init)), ]); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js index dcd9ae003362..05623e2c91d2 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/exec.js @@ -37,3 +37,9 @@ const [...{ 0: e }] = [,]; expect(d).toEqual([,]); expect(e).toEqual(undefined); + +const [f] = [,]; +expect(f).toEqual(undefined); + +let [g] = [,]; +expect(g).toEqual(undefined); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js index dcd9ae003362..05623e2c91d2 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/input.js @@ -37,3 +37,9 @@ const [...{ 0: e }] = [,]; expect(d).toEqual([,]); expect(e).toEqual(undefined); + +const [f] = [,]; +expect(f).toEqual(undefined); + +let [g] = [,]; +expect(g).toEqual(undefined); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js index 8d828dc07a71..b965fc9fd613 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js @@ -35,3 +35,7 @@ const d = [,]; const e = [,][0]; expect(d).toEqual([,]); expect(e).toEqual(undefined); +const f = void 0; +expect(f).toEqual(undefined); +let g; +expect(g).toEqual(undefined); From e4be9d267e6c674062ada67b5e434c633ae9d645 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Thu, 10 Feb 2022 10:43:16 +0800 Subject: [PATCH 4/4] Avoid redundant `cloneNode` --- .../babel-plugin-transform-destructuring/src/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/babel-plugin-transform-destructuring/src/index.ts b/packages/babel-plugin-transform-destructuring/src/index.ts index 63ce1f1d0b7a..dc401a04ab96 100644 --- a/packages/babel-plugin-transform-destructuring/src/index.ts +++ b/packages/babel-plugin-transform-destructuring/src/index.ts @@ -114,12 +114,16 @@ export default declare((api, options) => { ), ); } else { + let nodeInit: t.Expression; + if (this.kind === "const" && init === null) { - init = this.scope.buildUndefinedNode(); + nodeInit = this.scope.buildUndefinedNode(); + } else { + nodeInit = t.cloneNode(init); } node = t.variableDeclaration(this.kind, [ - t.variableDeclarator(id, t.cloneNode(init)), + t.variableDeclarator(id, nodeInit), ]); }