Correctly transform spreads of arrays with holes (#13439)
* Correctly transform spreads of arrays with holes * Use `arrayWithoutHoles` helper * Add exec test * Update for Babel 8 Co-authored-by: phapp88 <phapp1988@gmail.com>
This commit is contained in:
parent
366e6d9251
commit
e914d1219f
@ -20,6 +20,10 @@ export default declare((api, options) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasHole(spread) {
|
||||||
|
return spread.elements.some(el => el === null);
|
||||||
|
}
|
||||||
|
|
||||||
function hasSpread(nodes) {
|
function hasSpread(nodes) {
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
if (t.isSpreadElement(nodes[i])) {
|
if (t.isSpreadElement(nodes[i])) {
|
||||||
@ -35,14 +39,27 @@ export default declare((api, options) => {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function build(props: Array, scope) {
|
function build(props: Array, scope, file) {
|
||||||
const nodes = [];
|
const nodes = [];
|
||||||
let _props = [];
|
let _props = [];
|
||||||
|
|
||||||
for (const prop of props) {
|
for (const prop of props) {
|
||||||
if (t.isSpreadElement(prop)) {
|
if (t.isSpreadElement(prop)) {
|
||||||
_props = push(_props, nodes);
|
_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(
|
||||||
|
process.env.BABEL_8_BREAKING
|
||||||
|
? "arrayLikeToArray"
|
||||||
|
: "arrayWithoutHoles",
|
||||||
|
),
|
||||||
|
[spreadLiteral],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes.push(spreadLiteral);
|
||||||
} else {
|
} else {
|
||||||
_props.push(prop);
|
_props.push(prop);
|
||||||
}
|
}
|
||||||
@ -62,7 +79,7 @@ export default declare((api, options) => {
|
|||||||
const elements = node.elements;
|
const elements = node.elements;
|
||||||
if (!hasSpread(elements)) return;
|
if (!hasSpread(elements)) return;
|
||||||
|
|
||||||
const nodes = build(elements, scope);
|
const nodes = build(elements, scope, this);
|
||||||
let first = nodes[0];
|
let first = nodes[0];
|
||||||
|
|
||||||
// If there is only one element in the ArrayExpression and
|
// If there is only one element in the ArrayExpression and
|
||||||
|
|||||||
@ -0,0 +1,2 @@
|
|||||||
|
let arr = ['a', ...['b',,'c']];
|
||||||
|
expect(2 in arr).toBe(true);
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
var a = [...['a',, 'b']];
|
||||||
|
var b = ['a', ...['b',, 'c']];
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"BABEL_8_BREAKING": false
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
var a = babelHelpers.arrayWithoutHoles(['a',, 'b']);
|
||||||
|
var b = ['a'].concat(babelHelpers.arrayWithoutHoles(['b',, 'c']));
|
||||||
2
packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/exec.js
vendored
Normal file
2
packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/exec.js
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
let arr = ['a', ...['b',,'c']];
|
||||||
|
expect(2 in arr).toBe(true);
|
||||||
2
packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/input.js
vendored
Normal file
2
packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/input.js
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
var a = [...['a',, 'b']];
|
||||||
|
var b = ['a', ...['b',, 'c']];
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"BABEL_8_BREAKING": true
|
||||||
|
}
|
||||||
2
packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js
vendored
Normal file
2
packages/babel-plugin-transform-spread/test/fixtures/spread/nested-array-with-hole/output.js
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
var a = babelHelpers.arrayLikeToArray(['a',, 'b']);
|
||||||
|
var b = ['a'].concat(babelHelpers.arrayLikeToArray(['b',, 'c']));
|
||||||
Loading…
x
Reference in New Issue
Block a user