fix object rest in array pattern (#10275)
* fix object rest in array pattern * update test fixtures * early return * use path.stop() at the right path
This commit is contained in:
parent
81831032c3
commit
8027dca501
@ -30,9 +30,20 @@ export default declare((api, opts) => {
|
|||||||
|
|
||||||
function hasRestElement(path) {
|
function hasRestElement(path) {
|
||||||
let foundRestElement = false;
|
let foundRestElement = false;
|
||||||
visitRestElements(path, () => {
|
visitRestElements(path, restElement => {
|
||||||
foundRestElement = true;
|
foundRestElement = true;
|
||||||
path.stop();
|
restElement.stop();
|
||||||
|
});
|
||||||
|
return foundRestElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasObjectPatternRestElement(path) {
|
||||||
|
let foundRestElement = false;
|
||||||
|
visitRestElements(path, restElement => {
|
||||||
|
if (restElement.parentPath.isObjectPattern()) {
|
||||||
|
foundRestElement = true;
|
||||||
|
restElement.stop();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return foundRestElement;
|
return foundRestElement;
|
||||||
}
|
}
|
||||||
@ -163,9 +174,9 @@ export default declare((api, opts) => {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceRestElement(parentPath, paramPath, i, numParams) {
|
function replaceRestElement(parentPath, paramPath) {
|
||||||
if (paramPath.isAssignmentPattern()) {
|
if (paramPath.isAssignmentPattern()) {
|
||||||
replaceRestElement(parentPath, paramPath.get("left"), i, numParams);
|
replaceRestElement(parentPath, paramPath.get("left"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +184,7 @@ export default declare((api, opts) => {
|
|||||||
const elements = paramPath.get("elements");
|
const elements = paramPath.get("elements");
|
||||||
|
|
||||||
for (let i = 0; i < elements.length; i++) {
|
for (let i = 0; i < elements.length; i++) {
|
||||||
replaceRestElement(parentPath, elements[i], i, elements.length);
|
replaceRestElement(parentPath, elements[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +211,7 @@ export default declare((api, opts) => {
|
|||||||
Function(path) {
|
Function(path) {
|
||||||
const params = path.get("params");
|
const params = path.get("params");
|
||||||
for (let i = params.length - 1; i >= 0; i--) {
|
for (let i = params.length - 1; i >= 0; i--) {
|
||||||
replaceRestElement(params[i].parentPath, params[i], i, params.length);
|
replaceRestElement(params[i].parentPath, params[i]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// adapted from transform-destructuring/src/index.js#pushObjectRest
|
// adapted from transform-destructuring/src/index.js#pushObjectRest
|
||||||
@ -380,8 +391,12 @@ export default declare((api, opts) => {
|
|||||||
const leftPath = path.get("left");
|
const leftPath = path.get("left");
|
||||||
const left = node.left;
|
const left = node.left;
|
||||||
|
|
||||||
|
if (!hasObjectPatternRestElement(leftPath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!t.isVariableDeclaration(left)) {
|
||||||
// for ({a, ...b} of []) {}
|
// for ({a, ...b} of []) {}
|
||||||
if (t.isObjectPattern(left) && hasRestElement(leftPath)) {
|
|
||||||
const temp = scope.generateUidIdentifier("ref");
|
const temp = scope.generateUidIdentifier("ref");
|
||||||
|
|
||||||
node.left = t.variableDeclaration("var", [
|
node.left = t.variableDeclaration("var", [
|
||||||
@ -401,14 +416,9 @@ export default declare((api, opts) => {
|
|||||||
t.assignmentExpression("=", left, t.cloneNode(temp)),
|
t.assignmentExpression("=", left, t.cloneNode(temp)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
return;
|
// for (var {a, ...b} of []) {}
|
||||||
}
|
|
||||||
|
|
||||||
if (!t.isVariableDeclaration(left)) return;
|
|
||||||
|
|
||||||
const pattern = left.declarations[0].id;
|
const pattern = left.declarations[0].id;
|
||||||
if (!t.isObjectPattern(pattern)) return;
|
|
||||||
|
|
||||||
const key = scope.generateUidIdentifier("ref");
|
const key = scope.generateUidIdentifier("ref");
|
||||||
node.left = t.variableDeclaration(left.kind, [
|
node.left = t.variableDeclaration(left.kind, [
|
||||||
@ -422,6 +432,38 @@ export default declare((api, opts) => {
|
|||||||
t.variableDeclarator(pattern, t.cloneNode(key)),
|
t.variableDeclarator(pattern, t.cloneNode(key)),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// [{a, ...b}] = c;
|
||||||
|
ArrayPattern(path) {
|
||||||
|
const objectPatterns = [];
|
||||||
|
|
||||||
|
visitRestElements(path, path => {
|
||||||
|
if (!path.parentPath.isObjectPattern()) {
|
||||||
|
// Return early if the parent is not an ObjectPattern, but
|
||||||
|
// (for example) an ArrayPattern or Function, because that
|
||||||
|
// means this RestElement is an not an object property.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const objectPattern = path.parentPath;
|
||||||
|
|
||||||
|
const uid = path.scope.generateUidIdentifier("ref");
|
||||||
|
objectPatterns.push(t.variableDeclarator(objectPattern.node, uid));
|
||||||
|
|
||||||
|
objectPattern.replaceWith(t.cloneNode(uid));
|
||||||
|
path.skip();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (objectPatterns.length > 0) {
|
||||||
|
const statementPath = path.getStatementParent();
|
||||||
|
statementPath.insertAfter(
|
||||||
|
t.variableDeclaration(
|
||||||
|
statementPath.node.kind || "var",
|
||||||
|
objectPatterns,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// var a = { ...b, ...c }
|
// var a = { ...b, ...c }
|
||||||
ObjectExpression(path, file) {
|
ObjectExpression(path, file) {
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
// ForXStatement
|
||||||
|
for (const [{a, ...b}] of []) {}
|
||||||
|
for ([{a, ...b}] of []) {}
|
||||||
|
async function a() {
|
||||||
|
for await ([{a, ...b}] of []) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip
|
||||||
|
for ([{a}] in {}) {}
|
||||||
|
for ([{a}] of []) {}
|
||||||
|
async function a() {
|
||||||
|
for await ([{a}] of []) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ([a, ...b] in {}) {}
|
||||||
|
for ([a, ...b] of []) {}
|
||||||
|
async function a() {
|
||||||
|
for await ([a, ...b] of []) {}
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
// ForXStatement
|
||||||
|
for (const _ref of []) {
|
||||||
|
const [_ref2] = _ref;
|
||||||
|
const {
|
||||||
|
a
|
||||||
|
} = _ref2,
|
||||||
|
b = babelHelpers.objectWithoutProperties(_ref2, ["a"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var _ref3 of []) {
|
||||||
|
[_ref4] = _ref3;
|
||||||
|
var {
|
||||||
|
a
|
||||||
|
} = _ref4,
|
||||||
|
b = babelHelpers.objectWithoutProperties(_ref4, ["a"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function a() {
|
||||||
|
for await (var _ref5 of []) {
|
||||||
|
[_ref6] = _ref5;
|
||||||
|
var {
|
||||||
|
a
|
||||||
|
} = _ref6,
|
||||||
|
b = babelHelpers.objectWithoutProperties(_ref6, ["a"]);
|
||||||
|
}
|
||||||
|
} // skip
|
||||||
|
|
||||||
|
|
||||||
|
for ([{
|
||||||
|
a
|
||||||
|
}] in {}) {}
|
||||||
|
|
||||||
|
for ([{
|
||||||
|
a
|
||||||
|
}] of []) {}
|
||||||
|
|
||||||
|
async function a() {
|
||||||
|
for await ([{
|
||||||
|
a
|
||||||
|
}] of []) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ([a, ...b] in {}) {}
|
||||||
|
|
||||||
|
for ([a, ...b] of []) {}
|
||||||
|
|
||||||
|
async function a() {
|
||||||
|
for await ([a, ...b] of []) {}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
const [a, [{b, ...c}], {d, ...e}, [{ f, ...g}, {h: [i, {j, ...k}] }]] = x;
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
const [a, [_ref], _ref2, [_ref3, {
|
||||||
|
h: [i, _ref4]
|
||||||
|
}]] = x;
|
||||||
|
const {
|
||||||
|
b
|
||||||
|
} = _ref,
|
||||||
|
c = babelHelpers.objectWithoutProperties(_ref, ["b"]),
|
||||||
|
{
|
||||||
|
d
|
||||||
|
} = _ref2,
|
||||||
|
e = babelHelpers.objectWithoutProperties(_ref2, ["d"]),
|
||||||
|
{
|
||||||
|
f
|
||||||
|
} = _ref3,
|
||||||
|
g = babelHelpers.objectWithoutProperties(_ref3, ["f"]),
|
||||||
|
{
|
||||||
|
j
|
||||||
|
} = _ref4,
|
||||||
|
k = babelHelpers.objectWithoutProperties(_ref4, ["j"]);
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
const [a, {b, ...c}] = x;
|
||||||
|
|
||||||
|
let [d, {e, ...f}] = x;
|
||||||
|
|
||||||
|
[g, {h, ...i}] = x;
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
const [a, _ref] = x;
|
||||||
|
const {
|
||||||
|
b
|
||||||
|
} = _ref,
|
||||||
|
c = babelHelpers.objectWithoutProperties(_ref, ["b"]);
|
||||||
|
let [d, _ref2] = x;
|
||||||
|
let {
|
||||||
|
e
|
||||||
|
} = _ref2,
|
||||||
|
f = babelHelpers.objectWithoutProperties(_ref2, ["e"]);
|
||||||
|
[g, _ref3] = x;
|
||||||
|
var {
|
||||||
|
h
|
||||||
|
} = _ref3,
|
||||||
|
i = babelHelpers.objectWithoutProperties(_ref3, ["h"]);
|
||||||
@ -1,9 +1,8 @@
|
|||||||
import "core-js/modules/es7.string.pad-end";
|
import "core-js/modules/es7.string.pad-end";
|
||||||
import "core-js/modules/es7.string.pad-start";
|
import "core-js/modules/es7.string.pad-start";
|
||||||
|
|
||||||
for (const _ref of foo) {
|
for (const {
|
||||||
const {
|
|
||||||
padStart
|
padStart
|
||||||
} = _ref;
|
} of foo) {
|
||||||
console.log('b'.padEnd(5));
|
console.log('b'.padEnd(5));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,8 @@ import "core-js/modules/es.array.iterator";
|
|||||||
import "core-js/modules/es.string.pad-end";
|
import "core-js/modules/es.string.pad-end";
|
||||||
import "core-js/modules/es.string.pad-start";
|
import "core-js/modules/es.string.pad-start";
|
||||||
|
|
||||||
for (const _ref of foo) {
|
for (const {
|
||||||
const {
|
|
||||||
padStart
|
padStart
|
||||||
} = _ref;
|
} of foo) {
|
||||||
console.log('b'.padEnd(5));
|
console.log('b'.padEnd(5));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user