From 87c5f0392493c70d24ea21b02a218e8a69398eea Mon Sep 17 00:00:00 2001 From: phapp88 Date: Fri, 7 Dec 2018 08:52:08 -0600 Subject: [PATCH 1/4] Correctly transform spreads of arrays with holes --- .../src/index.js | 23 ++++++++++++++++--- .../spread/nested-array-with-hole/input.js | 2 ++ .../spread/nested-array-with-hole/output.js | 2 ++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/input.js create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js diff --git a/packages/babel-plugin-transform-spread/src/index.js b/packages/babel-plugin-transform-spread/src/index.js index f6559cfccd8c..23c870f7198e 100644 --- a/packages/babel-plugin-transform-spread/src/index.js +++ b/packages/babel-plugin-transform-spread/src/index.js @@ -20,6 +20,16 @@ export default declare((api, options) => { } } + function hasHole(spread) { + const elements = spread.elements; + for (let i = 0; i < elements.length; i++) { + if (elements[i] === null) { + return true; + } + } + return false; + } + function hasSpread(nodes) { for (let i = 0; i < nodes.length; i++) { if (t.isSpreadElement(nodes[i])) { @@ -35,14 +45,21 @@ export default declare((api, options) => { return []; } - function build(props: Array, scope) { + function build(props: Array, scope, file) { const nodes = []; let _props = []; for (const prop of props) { if (t.isSpreadElement(prop)) { _props = push(_props, nodes); - nodes.push(getSpreadLiteral(prop, scope)); + let spreadLiteral = getSpreadLiteral(prop, scope); + if (t.isArrayExpression(spreadLiteral) && hasHole(spreadLiteral)) { + spreadLiteral = t.callExpression( + file.addHelper("toConsumableArray"), + [spreadLiteral], + ); + } + nodes.push(spreadLiteral); } else { _props.push(prop); } @@ -62,7 +79,7 @@ export default declare((api, options) => { const elements = node.elements; if (!hasSpread(elements)) return; - const nodes = build(elements, scope); + const nodes = build(elements, scope, this); let first = nodes[0]; // If there is only one element in the ArrayExpression and diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/input.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/input.js new file mode 100644 index 000000000000..c24ce7d3edfc --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/input.js @@ -0,0 +1,2 @@ +var a = [...['a',, 'b']]; +var b = ['a', ...['b',, 'c']]; diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js new file mode 100644 index 000000000000..551e14822f17 --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js @@ -0,0 +1,2 @@ +var a = babelHelpers.toConsumableArray(['a',, 'b']); +var b = ['a'].concat(babelHelpers.toConsumableArray(['b',, 'c'])); From 4d927de528a9caf2e79f4505d0dcb1351fe6550b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 9 Jun 2021 16:53:46 +0200 Subject: [PATCH 2/4] Use `arrayWithoutHoles` helper --- packages/babel-plugin-transform-spread/src/index.js | 12 ++++-------- .../fixtures/spread/nested-array-with-hole/output.js | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/babel-plugin-transform-spread/src/index.js b/packages/babel-plugin-transform-spread/src/index.js index 23c870f7198e..dd55f31ff28a 100644 --- a/packages/babel-plugin-transform-spread/src/index.js +++ b/packages/babel-plugin-transform-spread/src/index.js @@ -21,13 +21,7 @@ export default declare((api, options) => { } function hasHole(spread) { - const elements = spread.elements; - for (let i = 0; i < elements.length; i++) { - if (elements[i] === null) { - return true; - } - } - return false; + return spread.elements.some(el => el === null); } function hasSpread(nodes) { @@ -53,12 +47,14 @@ export default declare((api, options) => { if (t.isSpreadElement(prop)) { _props = push(_props, nodes); let spreadLiteral = getSpreadLiteral(prop, scope); + if (t.isArrayExpression(spreadLiteral) && hasHole(spreadLiteral)) { spreadLiteral = t.callExpression( - file.addHelper("toConsumableArray"), + file.addHelper("arrayWithoutHoles"), [spreadLiteral], ); } + nodes.push(spreadLiteral); } else { _props.push(prop); diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js index 551e14822f17..bc2f49f74d1f 100644 --- a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js @@ -1,2 +1,2 @@ -var a = babelHelpers.toConsumableArray(['a',, 'b']); -var b = ['a'].concat(babelHelpers.toConsumableArray(['b',, 'c'])); +var a = babelHelpers.arrayWithoutHoles(['a',, 'b']); +var b = ['a'].concat(babelHelpers.arrayWithoutHoles(['b',, 'c'])); From f604e8421b9c4ea813313fd67c6825729a912db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 9 Jun 2021 16:55:45 +0200 Subject: [PATCH 3/4] Add exec test --- .../test/fixtures/spread/nested-array-with-hole/exec.js | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/exec.js diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/exec.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/exec.js new file mode 100644 index 000000000000..5e7bb424183b --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/exec.js @@ -0,0 +1,2 @@ +let arr = ['a', ...['b',,'c']]; +expect(2 in arr).toBe(true); From c68517725592eef57543b6ed1af1dd2f632f9dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 9 Jun 2021 19:28:15 +0200 Subject: [PATCH 4/4] Update for Babel 8 --- packages/babel-plugin-transform-spread/src/index.js | 6 +++++- .../fixtures/spread/nested-array-with-hole-babel-7/exec.js | 2 ++ .../fixtures/spread/nested-array-with-hole-babel-7/input.js | 2 ++ .../spread/nested-array-with-hole-babel-7/options.json | 3 +++ .../spread/nested-array-with-hole-babel-7/output.js | 2 ++ .../fixtures/spread/nested-array-with-hole/options.json | 3 +++ .../test/fixtures/spread/nested-array-with-hole/output.js | 4 ++-- 7 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/exec.js create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/input.js create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/options.json create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/output.js create mode 100644 packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/options.json diff --git a/packages/babel-plugin-transform-spread/src/index.js b/packages/babel-plugin-transform-spread/src/index.js index dd55f31ff28a..78e741eddf34 100644 --- a/packages/babel-plugin-transform-spread/src/index.js +++ b/packages/babel-plugin-transform-spread/src/index.js @@ -50,7 +50,11 @@ export default declare((api, options) => { if (t.isArrayExpression(spreadLiteral) && hasHole(spreadLiteral)) { spreadLiteral = t.callExpression( - file.addHelper("arrayWithoutHoles"), + file.addHelper( + process.env.BABEL_8_BREAKING + ? "arrayLikeToArray" + : "arrayWithoutHoles", + ), [spreadLiteral], ); } diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/exec.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/exec.js new file mode 100644 index 000000000000..5e7bb424183b --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/exec.js @@ -0,0 +1,2 @@ +let arr = ['a', ...['b',,'c']]; +expect(2 in arr).toBe(true); diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/input.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/input.js new file mode 100644 index 000000000000..c24ce7d3edfc --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/input.js @@ -0,0 +1,2 @@ +var a = [...['a',, 'b']]; +var b = ['a', ...['b',, 'c']]; diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/options.json b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/options.json new file mode 100644 index 000000000000..29a3f0e84167 --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": false +} diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/output.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/output.js new file mode 100644 index 000000000000..bc2f49f74d1f --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole-babel-7/output.js @@ -0,0 +1,2 @@ +var a = babelHelpers.arrayWithoutHoles(['a',, 'b']); +var b = ['a'].concat(babelHelpers.arrayWithoutHoles(['b',, 'c'])); diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/options.json b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/options.json new file mode 100644 index 000000000000..cbf6d1595427 --- /dev/null +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": true +} diff --git a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js index bc2f49f74d1f..b48ee388cb2d 100644 --- a/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js +++ b/packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js @@ -1,2 +1,2 @@ -var a = babelHelpers.arrayWithoutHoles(['a',, 'b']); -var b = ['a'].concat(babelHelpers.arrayWithoutHoles(['b',, 'c'])); +var a = babelHelpers.arrayLikeToArray(['a',, 'b']); +var b = ['a'].concat(babelHelpers.arrayLikeToArray(['b',, 'c']));