Do not unpack array patterns that update a referenced binding (#8535)

Fixes #8528
This commit is contained in:
Nicolò Ribaudo 2018-09-28 17:45:42 +02:00 committed by Henry Zhu
parent 55faa27b93
commit 626f47982e
4 changed files with 40 additions and 8 deletions

View File

@ -44,13 +44,23 @@ export default declare((api, options) => {
return false; return false;
} }
const arrayUnpackVisitor = { const STOP_TRAVERSAL = {};
ReferencedIdentifier(path, state) {
if (state.bindings[path.node.name]) { // NOTE: This visitor is meant to be used via t.traverse
state.deopt = true; const arrayUnpackVisitor = (node, ancestors, state) => {
path.stop(); if (!ancestors.length) {
// Top-level node: this is the array literal.
return;
}
if (
t.isIdentifier(node) &&
t.isReferenced(node, ancestors[ancestors.length - 1]) &&
state.bindings[node.name]
) {
state.deopt = true;
throw STOP_TRAVERSAL;
} }
},
}; };
class DestructuringTransformer { class DestructuringTransformer {
@ -282,7 +292,13 @@ export default declare((api, options) => {
// deopt on reference to left side identifiers // deopt on reference to left side identifiers
const bindings = t.getBindingIdentifiers(pattern); const bindings = t.getBindingIdentifiers(pattern);
const state = { deopt: false, bindings }; const state = { deopt: false, bindings };
this.scope.traverse(arr, arrayUnpackVisitor, state);
try {
t.traverse(arr, arrayUnpackVisitor, state);
} catch (e) {
if (e !== STOP_TRAVERSAL) throw e;
}
return !state.deopt; return !state.deopt;
} }

View File

@ -0,0 +1,4 @@
function isBetween(x, a, b) {
if (a > b) [a, b] = [b, a];
return x > a && x < b;
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["transform-destructuring"]
}

View File

@ -0,0 +1,9 @@
function isBetween(x, a, b) {
if (a > b) {
var _ref = [b, a];
a = _ref[0];
b = _ref[1];
}
return x > a && x < b;
}