diff --git a/lib/babel/transformation/transformers/es6/destructuring.js b/lib/babel/transformation/transformers/es6/destructuring.js index 739c1cbfa3..8d1f815a3c 100644 --- a/lib/babel/transformation/transformers/es6/destructuring.js +++ b/lib/babel/transformation/transformers/es6/destructuring.js @@ -163,13 +163,16 @@ var hasRest = function (pattern) { }; DestructuringTransformer.prototype.canUnpackArrayPattern = function (pattern, arr) { + // not an array so there's no way we can deal with this if (!t.isArrayExpression(arr)) return false; - if (pattern.elements.length < arr.elements.length) return false; + // pattern has less elements than the array and doesn't have a rest so some + // elements wont be evaluated + if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) return false; + + // deopt on holes for (var i = 0; i < pattern.elements.length; i++) { - var elem = pattern.elements[i]; - if (!elem) return false; // hole - if (t.isRestElement(elem)) return false; + if (!pattern.elements[i]) return false; } return true; @@ -177,7 +180,12 @@ DestructuringTransformer.prototype.canUnpackArrayPattern = function (pattern, ar DestructuringTransformer.prototype.pushUnpackedArrayPattern = function (pattern, arr) { for (var i = 0; i < pattern.elements.length; i++) { - this.push(pattern.elements[i], arr.elements[i]); + var elem = pattern.elements[i] + if (t.isRestElement(elem)) { + this.push(elem.argument, t.arrayExpression(arr.elements.slice(i))); + } else { + this.push(elem, arr.elements[i]); + } } }; diff --git a/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/actual.js b/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/actual.js index 4fe7e1123f..89bfb76776 100644 --- a/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/actual.js +++ b/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/actual.js @@ -1,9 +1,9 @@ // opt var [a, b] = [1, 2]; var [[a, b]] = [[1, 2]]; +var [a, b, ...c] = [1, 2, 3, 4]; +var [[a, b, ...c]] = [[1, 2, 3, 4]]; // deopt var [a, b] = [1, 2, 3]; var [[a, b]] = [[1, 2, 3]]; -var [a, b, ...items] = [1, 2, 3]; -var [[a, b, ...items]] = [[1, 2, 3]]; diff --git a/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/expected.js b/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/expected.js index 559122ae23..ad9f44331c 100644 --- a/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/expected.js +++ b/test/fixtures/transformation/es6-destructuring/array-unpack-optimisation/expected.js @@ -5,6 +5,12 @@ var a = 1; var b = 2; var a = 1; var b = 2; +var a = 1; +var b = 2; +var c = [3, 4]; +var a = 1; +var b = 2; +var c = [3, 4]; // deopt var _ref = [1, 2, 3]; @@ -13,14 +19,3 @@ var b = _ref[1]; var _ref2 = [1, 2, 3]; var a = _ref2[0]; var b = _ref2[1]; -var _ref3 = [1, 2, 3]; -var a = _ref3[0]; -var b = _ref3[1]; - -var items = _ref3.slice(2); - -var _ref4 = [1, 2, 3]; -var a = _ref4[0]; -var b = _ref4[1]; - -var items = _ref4.slice(2);