diff --git a/packages/babel-plugin-transform-destructuring/src/index.js b/packages/babel-plugin-transform-destructuring/src/index.js index b706ed5bea..a38cfb6b38 100644 --- a/packages/babel-plugin-transform-destructuring/src/index.js +++ b/packages/babel-plugin-transform-destructuring/src/index.js @@ -44,13 +44,23 @@ export default declare((api, options) => { return false; } - const arrayUnpackVisitor = { - ReferencedIdentifier(path, state) { - if (state.bindings[path.node.name]) { - state.deopt = true; - path.stop(); - } - }, + const STOP_TRAVERSAL = {}; + + // NOTE: This visitor is meant to be used via t.traverse + const arrayUnpackVisitor = (node, ancestors, state) => { + 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 { @@ -282,7 +292,13 @@ export default declare((api, options) => { // deopt on reference to left side identifiers const bindings = t.getBindingIdentifiers(pattern); 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; } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/input.js new file mode 100644 index 0000000000..9c6f1a1839 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/input.js @@ -0,0 +1,4 @@ +function isBetween(x, a, b) { + if (a > b) [a, b] = [b, a]; + return x > a && x < b; +} diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/options.json new file mode 100644 index 0000000000..84e28c07f5 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-destructuring"] +} diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/output.js new file mode 100644 index 0000000000..9546a2734c --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/8528/output.js @@ -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; +}