Destructuring: Fix handling of impure computed keys with object rest (#9416)

This commit is contained in:
Moti Zilberman
2019-03-27 02:11:44 +00:00
committed by Daniel Tschinder
parent f7bfc774ba
commit 1f5444e96a
5 changed files with 90 additions and 0 deletions

View File

@@ -44,6 +44,19 @@ export default declare((api, options) => {
return false;
}
/**
* Test if an ObjectPattern's elements contain any RestElements.
*/
function hasObjectRest(pattern) {
for (const elem of (pattern.properties: Array)) {
if (t.isRestElement(elem)) {
return true;
}
}
return false;
}
const STOP_TRAVERSAL = {};
// NOTE: This visitor is meant to be used via t.traverse
@@ -263,6 +276,31 @@ export default declare((api, options) => {
objRef = temp;
}
// Replace impure computed key expressions if we have a rest parameter
if (hasObjectRest(pattern)) {
let copiedPattern;
for (let i = 0; i < pattern.properties.length; i++) {
const prop = pattern.properties[i];
if (t.isRestElement(prop)) {
break;
}
const key = prop.key;
if (prop.computed && !this.scope.isPure(key)) {
const name = this.scope.generateUidIdentifierBasedOnNode(key);
this.nodes.push(this.buildVariableDeclaration(name, key));
if (!copiedPattern) {
copiedPattern = pattern = {
...pattern,
properties: pattern.properties.slice(),
};
}
copiedPattern.properties[i] = {
...copiedPattern.properties[i],
key: name,
};
}
}
}
//
for (let i = 0; i < pattern.properties.length; i++) {