Do not unpack array patterns that update a referenced binding (#8535)
Fixes #8528
This commit is contained in:
parent
55faa27b93
commit
626f47982e
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/input.js
vendored
Normal file
4
packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/input.js
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
function isBetween(x, a, b) {
|
||||||
|
if (a > b) [a, b] = [b, a];
|
||||||
|
return x > a && x < b;
|
||||||
|
}
|
||||||
3
packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/options.json
vendored
Normal file
3
packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["transform-destructuring"]
|
||||||
|
}
|
||||||
9
packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/output.js
vendored
Normal file
9
packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/output.js
vendored
Normal 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;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user