From e9a06d52004fe31e4f7bb2b7f4335085dc254b14 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 00:43:19 +0800 Subject: [PATCH 01/13] Empty array destructuring shouldn't call `next()` --- packages/babel-helpers/src/helpers.ts | 14 ++++- .../destructuring/empty-array-pattern/exec.js | 23 ++++++++ .../empty-array-pattern/input.js | 12 +++++ .../empty-array-pattern/output.js | 53 +++++++++++++++++++ .../destructuring/init-hole/output.js | 2 +- .../test/fixtures/regression/T7199/output.js | 2 +- .../plugins-integration/issue-15012/output.js | 2 +- packages/babel-traverse/src/scope/index.ts | 2 +- 8 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index 6cc25e4e8275..fd897d351a8e 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -787,8 +787,13 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` var _n = true; var _d = false; var _s, _e; + _i = _i.call(arr); + if (i === 0) { + if (typeof _i !== "object" && typeof _i !== "function") return; + return _arr; + } try { - for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } @@ -812,7 +817,12 @@ helpers.iterableToArrayLimitLoose = helper("7.0.0-beta.0")` if (_i == null) return; var _arr = []; - for (_i = _i.call(arr), _step; !(_step = _i.next()).done;) { + _i = _i.call(arr); + if (i === 0) { + if (typeof _i !== "object" && typeof _i !== "function") return; + return _arr; + } + for (_step; !(_step = _i.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js new file mode 100644 index 000000000000..47ea91f838f0 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js @@ -0,0 +1,23 @@ +expect(function () { + var [] = null; +}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + +expect(function () { + var [] = 42; +}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + +expect(function () { + var [] = {}; +}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + +expect(function () { + var [] = { [Symbol.iterator]: function() {} }; +}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + +var [] = []; +var [] = [0, 1, 2]; +var [] = "foo"; +var [] = (function*() { throw new Error("Should not throw"); })(); +var [] = { [Symbol.iterator]: function() { return {}; } } +var [] = { [Symbol.iterator]: function() { return function() {}; } } +var [] = { [Symbol.iterator]: async function*() {} } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js new file mode 100644 index 000000000000..a6f07a8ca18a --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js @@ -0,0 +1,12 @@ +var [] = null; +var [] = 42; +var [] = {}; +var [] = { [Symbol.iterator]: function() {} }; + +var [] = []; +var [] = [0, 1, 2]; +var [] = "foo"; +var [] = (function*() { throw new Error("Should not throw"); })(); +var [] = { [Symbol.iterator]: function() { return {}; } } +var [] = { [Symbol.iterator]: function() { return function() {}; } } +var [] = { [Symbol.iterator]: async function*() {} } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js new file mode 100644 index 000000000000..37ceff54e09f --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js @@ -0,0 +1,53 @@ +var _ref = null, + _ref2 = babelHelpers.slicedToArray(_ref, 0); +var _ = 42, + _ref3 = babelHelpers.slicedToArray(_, 0); +var _ref4 = {}, + _ref5 = babelHelpers.slicedToArray(_ref4, 0); +var _Symbol$iterator = { + [Symbol.iterator]: function () {} + }, + _Symbol$iterator2 = babelHelpers.slicedToArray(_Symbol$iterator, 0); +var _ref6 = [0, 1, 2]; +var _foo = "foo", + _foo2 = babelHelpers.slicedToArray(_foo, 0); +var _ref7 = /*#__PURE__*/babelHelpers.regeneratorRuntime().mark(function _callee() { + return babelHelpers.regeneratorRuntime().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + throw new Error("Should not throw"); + case 1: + case "end": + return _context.stop(); + } + } + }, _callee); + })(), + _ref8 = babelHelpers.slicedToArray(_ref7, 0); +var _Symbol$iterator3 = { + [Symbol.iterator]: function () { + return {}; + } + }, + _Symbol$iterator4 = babelHelpers.slicedToArray(_Symbol$iterator3, 0); +var _Symbol$iterator5 = { + [Symbol.iterator]: function () { + return function () {}; + } + }, + _Symbol$iterator6 = babelHelpers.slicedToArray(_Symbol$iterator5, 0); +var _Symbol$iterator7 = { + [Symbol.iterator]: /*#__PURE__*/babelHelpers.regeneratorRuntime().mark(function _callee2() { + return babelHelpers.regeneratorRuntime().async(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + case "end": + return _context2.stop(); + } + } + }, _callee2, null, null, Promise); + }) + }, + _Symbol$iterator8 = babelHelpers.slicedToArray(_Symbol$iterator7, 0); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js index 05a00e9b37d5..8ea1f3daea16 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/init-hole/output.js @@ -45,7 +45,7 @@ try { expect(thrown).toEqual(true); try { thrown = false; - var _ = babelHelpers.toArray(void 0); + var _ = babelHelpers.slicedToArray(void 0, 0); } catch (e) { thrown = true; } diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index 1a24ee595677..51c1728a5ccb 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; _i = _i.call(arr); if (i === 0) { if (typeof _i !== "object" && typeof _i !== "function") return; return _arr; } try { for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1), diff --git a/packages/babel-preset-env/test/fixtures/plugins-integration/issue-15012/output.js b/packages/babel-preset-env/test/fixtures/plugins-integration/issue-15012/output.js index ddfdfaa2c8ac..c273d4c8d716 100644 --- a/packages/babel-preset-env/test/fixtures/plugins-integration/issue-15012/output.js +++ b/packages/babel-preset-env/test/fixtures/plugins-integration/issue-15012/output.js @@ -1,5 +1,5 @@ function f(_ref) { - var _ref2 = babelHelpers.toArray(_ref); + var _ref2 = babelHelpers.slicedToArray(_ref, 0); return /*#__PURE__*/babelHelpers.regeneratorRuntime().mark(function _callee() { return babelHelpers.regeneratorRuntime().wrap(function _callee$(_context) { while (1) { diff --git a/packages/babel-traverse/src/scope/index.ts b/packages/babel-traverse/src/scope/index.ts index b858d452462e..1019f398bb15 100644 --- a/packages/babel-traverse/src/scope/index.ts +++ b/packages/babel-traverse/src/scope/index.ts @@ -686,7 +686,7 @@ export default class Scope { if (i === true) { // Used in array-spread to create an array. helperName = "toConsumableArray"; - } else if (i) { + } else if (typeof i === "number") { args.push(numericLiteral(i)); // Used in array-rest to create an array from a subset of an iterable. From a1655017b9a3cb701f6e3e43fdedc59b1ab28aef Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 01:47:23 +0800 Subject: [PATCH 02/13] Add missing variable declaration --- packages/babel-helpers/src/helpers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index fd897d351a8e..f2e8c4e25c55 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -822,8 +822,8 @@ helpers.iterableToArrayLimitLoose = helper("7.0.0-beta.0")` if (typeof _i !== "object" && typeof _i !== "function") return; return _arr; } - for (_step; !(_step = _i.next()).done;) { - _arr.push(_step.value); + for (var _s; !(_s = _i.next()).done;) { + _arr.push(_s.value); if (i && _arr.length === i) break; } return _arr; From 575d0ccc026a0492a7501bf24334d4f597883f5d Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 02:21:43 +0800 Subject: [PATCH 03/13] Should call `return()` --- packages/babel-helpers/src/helpers.ts | 11 +++++----- .../destructuring/empty-array-pattern/exec.js | 21 +++++++++++++++---- .../empty-array-pattern/input.js | 12 +++++++++++ .../empty-array-pattern/output.js | 12 +++++++++++ .../test/fixtures/regression/T7199/output.js | 2 +- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index f2e8c4e25c55..b575fa478047 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -787,12 +787,13 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` var _n = true; var _d = false; var _s, _e; - _i = _i.call(arr); - if (i === 0) { - if (typeof _i !== "object" && typeof _i !== "function") return; - return _arr; - } try { + _i = _i.call(arr); + if (i === 0) { + if (typeof _i !== "object" && typeof _i !== "function") return; + _n = false; + return _arr; + } for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js index 47ea91f838f0..3f6b5c2e87a1 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js @@ -1,17 +1,17 @@ expect(function () { - var [] = null; + var [] = null; }).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); expect(function () { - var [] = 42; + var [] = 42; }).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); expect(function () { - var [] = {}; + var [] = {}; }).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); expect(function () { - var [] = { [Symbol.iterator]: function() {} }; + var [] = { [Symbol.iterator]: function() {} }; }).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); var [] = []; @@ -21,3 +21,16 @@ var [] = (function*() { throw new Error("Should not throw"); })(); var [] = { [Symbol.iterator]: function() { return {}; } } var [] = { [Symbol.iterator]: function() { return function() {}; } } var [] = { [Symbol.iterator]: async function*() {} } + +var returnCalled = false; +var [] = { + [Symbol.iterator]: function() { + return { + return: function() { + returnCalled = true; + return {}; + } + }; + } +}; +expect(returnCalled).toStrictEqual(true); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js index a6f07a8ca18a..afc8822d7d13 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js @@ -10,3 +10,15 @@ var [] = (function*() { throw new Error("Should not throw"); })(); var [] = { [Symbol.iterator]: function() { return {}; } } var [] = { [Symbol.iterator]: function() { return function() {}; } } var [] = { [Symbol.iterator]: async function*() {} } + +var returnCalled = false; +var [] = { + [Symbol.iterator]: function() { + return { + return: function() { + returnCalled = true; + return {}; + } + }; + } +}; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js index 37ceff54e09f..8a7d98bbfe6b 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js @@ -51,3 +51,15 @@ var _Symbol$iterator7 = { }) }, _Symbol$iterator8 = babelHelpers.slicedToArray(_Symbol$iterator7, 0); +var returnCalled = false; +var _Symbol$iterator9 = { + [Symbol.iterator]: function () { + return { + return: function () { + returnCalled = true; + return {}; + } + }; + } + }, + _Symbol$iterator10 = babelHelpers.slicedToArray(_Symbol$iterator9, 0); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index 51c1728a5ccb..545f82ba2d69 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; _i = _i.call(arr); if (i === 0) { if (typeof _i !== "object" && typeof _i !== "function") return; return _arr; } try { for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { _i = _i.call(arr); if (i === 0) { if (typeof _i !== "object" && typeof _i !== "function") return; _n = false; return _arr; } for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1), From b8bc947e3c3919ec35017a5db6024de88cd9fa72 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 03:01:49 +0800 Subject: [PATCH 04/13] Simplify code --- packages/babel-helpers/src/helpers.ts | 13 +++++-------- .../test/fixtures/regression/T7199/output.js | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index b575fa478047..61e2f5d90afa 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -788,15 +788,12 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` var _d = false; var _s, _e; try { - _i = _i.call(arr); + for (_i = _i.call(arr); i < _arr.length && !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + } if (i === 0) { - if (typeof _i !== "object" && typeof _i !== "function") return; + if (Object(_i) !== _i) return; _n = false; - return _arr; - } - for (; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - if (i && _arr.length === i) break; } } catch (err) { _d = true; @@ -820,7 +817,7 @@ helpers.iterableToArrayLimitLoose = helper("7.0.0-beta.0")` var _arr = []; _i = _i.call(arr); if (i === 0) { - if (typeof _i !== "object" && typeof _i !== "function") return; + if (Object(_i) !== _i) return; return _arr; } for (var _s; !(_s = _i.next()).done;) { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index 545f82ba2d69..f655365b1c3b 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { _i = _i.call(arr); if (i === 0) { if (typeof _i !== "object" && typeof _i !== "function") return; _n = false; return _arr; } for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); i < _arr.length && !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); } if (i === 0) { if (Object(_i) !== _i) return; _n = false; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1), From 6936cde01fc4cdfb4701f06ccc67b3a1897cf4c4 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 04:45:44 +0800 Subject: [PATCH 05/13] Fix compare --- packages/babel-helpers/src/helpers.ts | 2 +- .../test/fixtures/regression/T7199/output.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index 61e2f5d90afa..a65534f9e861 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -788,7 +788,7 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` var _d = false; var _s, _e; try { - for (_i = _i.call(arr); i < _arr.length && !(_n = (_s = _i.next()).done); _n = true) { + for (_i = _i.call(arr); _arr.length < i && !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); } if (i === 0) { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index f655365b1c3b..562a95d7a0bb 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); i < _arr.length && !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); } if (i === 0) { if (Object(_i) !== _i) return; _n = false; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); _arr.length < i && !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); } if (i === 0) { if (Object(_i) !== _i) return; _n = false; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1), From 6f41ba02d3dd862bbf9ff4c161262bfa0d8630ad Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 05:27:04 +0800 Subject: [PATCH 06/13] Fix code --- packages/babel-helpers/src/helpers.ts | 9 ++++++--- .../test/fixtures/regression/T7199/output.js | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index a65534f9e861..a45e7ba54423 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -788,12 +788,15 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` var _d = false; var _s, _e; try { - for (_i = _i.call(arr); _arr.length < i && !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - } + _i = _i.call(arr); if (i === 0) { if (Object(_i) !== _i) return; _n = false; + } else { + for (; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + if(_arr.length === i) break; + } } } catch (err) { _d = true; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index 562a95d7a0bb..df0c8f1514be 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); _arr.length < i && !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); } if (i === 0) { if (Object(_i) !== _i) return; _n = false; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { _i = _i.call(arr); if (i === 0) { if (Object(_i) !== _i) return; _n = false; } else { for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (_arr.length === i) break; } } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1), From 68208612e10fe357379e7cdb53092c33ea143e17 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 21:10:56 +0800 Subject: [PATCH 07/13] Add tests for #15154 and #15168 --- .../destructuring/empty-array-pattern/exec.js | 16 +++++++++------- .../test/fixtures/regression/15154/exec.js | 3 +++ .../test/fixtures/regression/15154/input.js | 1 + .../test/fixtures/regression/15154/options.json | 3 +++ .../test/fixtures/regression/15154/output.js | 4 ++++ .../test/fixtures/regression/15168/exec.js | 3 +++ .../test/fixtures/regression/15168/input.js | 1 + .../test/fixtures/regression/15168/options.json | 3 +++ .../test/fixtures/regression/15168/output.js | 4 ++++ 9 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/exec.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/input.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/options.json create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/output.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/exec.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/input.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js index 3f6b5c2e87a1..11b986e55053 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js @@ -14,13 +14,15 @@ expect(function () { var [] = { [Symbol.iterator]: function() {} }; }).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -var [] = []; -var [] = [0, 1, 2]; -var [] = "foo"; -var [] = (function*() { throw new Error("Should not throw"); })(); -var [] = { [Symbol.iterator]: function() { return {}; } } -var [] = { [Symbol.iterator]: function() { return function() {}; } } -var [] = { [Symbol.iterator]: async function*() {} } +expect(function () { + var [] = []; + var [] = [0, 1, 2]; + var [] = "foo"; + var [] = (function*() { throw new Error("Should not throw"); })(); + var [] = { [Symbol.iterator]: function() { return {}; } } + var [] = { [Symbol.iterator]: function() { return function() {}; } } + var [] = { [Symbol.iterator]: async function*() {} } +}).not.toThrow(); var returnCalled = false; var [] = { diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/exec.js new file mode 100644 index 000000000000..200fe886738f --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/exec.js @@ -0,0 +1,3 @@ +expect(() => { + var [] = { [Symbol.iterator]: () => [] }; +}).not.toThrow(); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/input.js new file mode 100644 index 000000000000..fa976372b57a --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/input.js @@ -0,0 +1 @@ +var [] = { [Symbol.iterator]: () => [] }; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/options.json new file mode 100644 index 000000000000..84e28c07f51e --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-destructuring"] +} diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/output.js new file mode 100644 index 000000000000..678e2655ef49 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15154/output.js @@ -0,0 +1,4 @@ +var _Symbol$iterator = { + [Symbol.iterator]: () => [] + }, + _Symbol$iterator2 = babelHelpers.slicedToArray(_Symbol$iterator, 0); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/exec.js new file mode 100644 index 000000000000..d1a3ff74de70 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/exec.js @@ -0,0 +1,3 @@ +expect(() => { + var [] = { [Symbol.iterator]: () => async function* () {} }; +}).not.toThrow(); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/input.js new file mode 100644 index 000000000000..e7edfef99ff4 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/input.js @@ -0,0 +1 @@ +var [] = { [Symbol.iterator]: () => async function* () {} }; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json new file mode 100644 index 000000000000..84e28c07f51e --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-destructuring"] +} diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js new file mode 100644 index 000000000000..5bd8618795bb --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js @@ -0,0 +1,4 @@ +var _Symbol$iterator = { + [Symbol.iterator]: () => async function* () {} + }, + _Symbol$iterator2 = babelHelpers.slicedToArray(_Symbol$iterator, 0); From b0c4eac109460c6ba838c4f2383f421a7502c179 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 21:30:50 +0800 Subject: [PATCH 08/13] Should check result of `iterator.return()` --- packages/babel-helpers/src/helpers.ts | 7 +++- .../check-iterator-return/exec.js | 41 ++++++++++++++++++ .../check-iterator-return/input.js | 33 +++++++++++++++ .../check-iterator-return/output.js | 42 +++++++++++++++++++ .../destructuring/empty-array-pattern/exec.js | 34 +++++++-------- .../empty-array-pattern/input.js | 16 +++---- .../empty-array-pattern/output.js | 14 +++---- .../test/fixtures/regression/T7199/output.js | 2 +- 8 files changed, 152 insertions(+), 37 deletions(-) create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/exec.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/input.js create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/output.js diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index a45e7ba54423..b4f294fea89c 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -786,7 +786,7 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` var _arr = []; var _n = true; var _d = false; - var _s, _e; + var _s, _e, _r; try { _i = _i.call(arr); if (i === 0) { @@ -803,7 +803,10 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` _e = err; } finally { try { - if (!_n && _i["return"] != null) _i["return"](); + if (!_n && _i["return"] != null) { + _r = _i["return"](); + if (Object(_r) !== _r) return; + } } finally { if (_d) throw _e; } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/exec.js new file mode 100644 index 000000000000..64a9c9080885 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/exec.js @@ -0,0 +1,41 @@ +expect(() => { + var [] = { + [Symbol.iterator]: () => { + return { + return: () => {}, + }; + }, + }; +}).toThrow(TypeError); + +expect(() => { + var [] = { + [Symbol.iterator]: () => { + return { + return: () => ({}), + }; + }, + }; +}).not.toThrow(); + +expect(() => { + var [x] = { + [Symbol.iterator]: () => { + return { + next: () => ({ done: false, value: 1 }), + return: () => {}, + }; + }, + }; +}).toThrow(TypeError); + +expect(() => { + var [x] = { + [Symbol.iterator]: () => { + return { + next: () => ({ done: false, value: 1 }), + return: () => ({}), + }; + }, + }; +}).not.toThrow(); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/input.js new file mode 100644 index 000000000000..a79f08732cb2 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/input.js @@ -0,0 +1,33 @@ +var [] = { + [Symbol.iterator]: () => { + return { + return: () => {}, + }; + }, +}; + +var [] = { + [Symbol.iterator]: () => { + return { + return: () => ({}), + }; + }, +}; + +var [x] = { + [Symbol.iterator]: () => { + return { + next: () => ({ done: false, value: 1 }), + return: () => {}, + }; + }, +}; + +var [x] = { + [Symbol.iterator]: () => { + return { + next: () => ({ done: false, value: 1 }), + return: () => ({}), + }; + }, +}; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/output.js new file mode 100644 index 000000000000..7bdc193b7308 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/check-iterator-return/output.js @@ -0,0 +1,42 @@ +var _Symbol$iterator = { + [Symbol.iterator]: () => { + return { + return: () => {} + }; + } + }, + _Symbol$iterator2 = babelHelpers.slicedToArray(_Symbol$iterator, 0); +var _Symbol$iterator3 = { + [Symbol.iterator]: () => { + return { + return: () => ({}) + }; + } + }, + _Symbol$iterator4 = babelHelpers.slicedToArray(_Symbol$iterator3, 0); +var _Symbol$iterator5 = { + [Symbol.iterator]: () => { + return { + next: () => ({ + done: false, + value: 1 + }), + return: () => {} + }; + } + }, + _Symbol$iterator6 = babelHelpers.slicedToArray(_Symbol$iterator5, 1), + x = _Symbol$iterator6[0]; +var _Symbol$iterator7 = { + [Symbol.iterator]: () => { + return { + next: () => ({ + done: false, + value: 1 + }), + return: () => ({}) + }; + } + }, + _Symbol$iterator8 = babelHelpers.slicedToArray(_Symbol$iterator7, 1), + x = _Symbol$iterator8[0]; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js index 11b986e55053..4a74739479ba 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/exec.js @@ -1,38 +1,38 @@ -expect(function () { +expect(() => { var [] = null; -}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +}).toThrow(TypeError); -expect(function () { +expect(() => { var [] = 42; -}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +}).toThrow(TypeError); -expect(function () { +expect(() => { var [] = {}; -}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +}).toThrow(TypeError); -expect(function () { - var [] = { [Symbol.iterator]: function() {} }; -}).toThrow("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +expect(() => { + var [] = { [Symbol.iterator]: () => {} }; +}).toThrow(TypeError); -expect(function () { +expect(() => { var [] = []; var [] = [0, 1, 2]; var [] = "foo"; var [] = (function*() { throw new Error("Should not throw"); })(); - var [] = { [Symbol.iterator]: function() { return {}; } } - var [] = { [Symbol.iterator]: function() { return function() {}; } } - var [] = { [Symbol.iterator]: async function*() {} } + var [] = { [Symbol.iterator]: () => ({}) }; + var [] = { [Symbol.iterator]: () => () => {} }; + var [] = { [Symbol.iterator]: async function*() {} }; }).not.toThrow(); var returnCalled = false; var [] = { - [Symbol.iterator]: function() { + [Symbol.iterator]: () => { return { - return: function() { + return: () => { returnCalled = true; return {}; - } + }, }; - } + }, }; expect(returnCalled).toStrictEqual(true); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js index afc8822d7d13..064f8902399d 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/input.js @@ -1,24 +1,24 @@ var [] = null; var [] = 42; var [] = {}; -var [] = { [Symbol.iterator]: function() {} }; +var [] = { [Symbol.iterator]: () => {} }; var [] = []; var [] = [0, 1, 2]; var [] = "foo"; var [] = (function*() { throw new Error("Should not throw"); })(); -var [] = { [Symbol.iterator]: function() { return {}; } } -var [] = { [Symbol.iterator]: function() { return function() {}; } } -var [] = { [Symbol.iterator]: async function*() {} } +var [] = { [Symbol.iterator]: () => ({}) }; +var [] = { [Symbol.iterator]: () => () => {} }; +var [] = { [Symbol.iterator]: async function*() {} }; var returnCalled = false; var [] = { - [Symbol.iterator]: function() { + [Symbol.iterator]: () => { return { - return: function() { + return: () => { returnCalled = true; return {}; - } + }, }; - } + }, }; diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js index 8a7d98bbfe6b..a5f12c42ff7a 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/empty-array-pattern/output.js @@ -5,7 +5,7 @@ var _ = 42, var _ref4 = {}, _ref5 = babelHelpers.slicedToArray(_ref4, 0); var _Symbol$iterator = { - [Symbol.iterator]: function () {} + [Symbol.iterator]: () => {} }, _Symbol$iterator2 = babelHelpers.slicedToArray(_Symbol$iterator, 0); var _ref6 = [0, 1, 2]; @@ -26,15 +26,11 @@ var _ref7 = /*#__PURE__*/babelHelpers.regeneratorRuntime().mark(function _callee })(), _ref8 = babelHelpers.slicedToArray(_ref7, 0); var _Symbol$iterator3 = { - [Symbol.iterator]: function () { - return {}; - } + [Symbol.iterator]: () => ({}) }, _Symbol$iterator4 = babelHelpers.slicedToArray(_Symbol$iterator3, 0); var _Symbol$iterator5 = { - [Symbol.iterator]: function () { - return function () {}; - } + [Symbol.iterator]: () => () => {} }, _Symbol$iterator6 = babelHelpers.slicedToArray(_Symbol$iterator5, 0); var _Symbol$iterator7 = { @@ -53,9 +49,9 @@ var _Symbol$iterator7 = { _Symbol$iterator8 = babelHelpers.slicedToArray(_Symbol$iterator7, 0); var returnCalled = false; var _Symbol$iterator9 = { - [Symbol.iterator]: function () { + [Symbol.iterator]: () => { return { - return: function () { + return: () => { returnCalled = true; return {}; } diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index df0c8f1514be..783f6f483d5b 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { _i = _i.call(arr); if (i === 0) { if (Object(_i) !== _i) return; _n = false; } else { for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (_arr.length === i) break; } } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e, _r; try { _i = _i.call(arr); if (i === 0) { if (Object(_i) !== _i) return; _n = false; } else { for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (_arr.length === i) break; } } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) { _r = _i["return"](); if (Object(_r) !== _r) return; } } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1), From 42d95d5ac3df9b9ed601d381952ae4621a9f22a4 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Fri, 11 Nov 2022 21:56:10 +0800 Subject: [PATCH 09/13] Fix #15168 test --- .../test/fixtures/regression/15168/options.json | 5 ++++- .../test/fixtures/regression/15168/output.js | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json index 84e28c07f51e..bcd3c208a8bc 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/options.json @@ -1,3 +1,6 @@ { - "plugins": ["transform-destructuring"] + "plugins": [ + "transform-destructuring", + "transform-regenerator" + ] } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js index 5bd8618795bb..cf218b07135d 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/regression/15168/output.js @@ -1,4 +1,12 @@ var _Symbol$iterator = { - [Symbol.iterator]: () => async function* () {} + [Symbol.iterator]: () => /*#__PURE__*/babelHelpers.regeneratorRuntime().mark(function _callee() { + return babelHelpers.regeneratorRuntime().async(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + case "end": + return _context.stop(); + } + }, _callee, null, null, Promise); + }) }, _Symbol$iterator2 = babelHelpers.slicedToArray(_Symbol$iterator, 0); From 94f03b93faff103bb5d9f8868c7a6a3d9c331704 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Sat, 12 Nov 2022 00:12:01 +0800 Subject: [PATCH 10/13] `next` should only eval once --- packages/babel-helpers/src/helpers.ts | 8 ++++--- .../destructuring/next-eval-once/exec.js | 22 +++++++++++++++++++ .../test/fixtures/regression/T7199/output.js | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/next-eval-once/exec.js diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index b4f294fea89c..917e9f9dd242 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -779,6 +779,8 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` // _e = _iteratorError // _i = _iterator // _s = _step + // _x = _next + // _r = _return var _i = arr == null ? null : (typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]); if (_i == null) return; @@ -786,14 +788,14 @@ helpers.iterableToArrayLimit = helper("7.0.0-beta.0")` var _arr = []; var _n = true; var _d = false; - var _s, _e, _r; + var _s, _e, _x, _r; try { - _i = _i.call(arr); + _x = (_i = _i.call(arr)).next; if (i === 0) { if (Object(_i) !== _i) return; _n = false; } else { - for (; !(_n = (_s = _i.next()).done); _n = true) { + for (; !(_n = (_s = _x.call(_i)).done); _n = true) { _arr.push(_s.value); if(_arr.length === i) break; } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/next-eval-once/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/next-eval-once/exec.js new file mode 100644 index 000000000000..3c996571bae4 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/next-eval-once/exec.js @@ -0,0 +1,22 @@ +let gets = 0; +let it = { + [Symbol.iterator]: () => ({ + get next() { + gets++; + let i = 0; + return () => ({ done: false, value: i++ }); + }, + }), +}; + +let [] = it; +expect(gets).toBe(1); + +let [a] = it; +expect(gets).toBe(2); +expect(a).toBe(0); + +let [b, c] = it; +expect(gets).toBe(3); +expect(b).toBe(0); +expect(c).toBe(1); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index 783f6f483d5b..fa4ed1d67749 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e, _r; try { _i = _i.call(arr); if (i === 0) { if (Object(_i) !== _i) return; _n = false; } else { for (; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (_arr.length === i) break; } } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) { _r = _i["return"](); if (Object(_r) !== _r) return; } } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e, _x, _r; try { _x = (_i = _i.call(arr)).next; if (i === 0) { if (Object(_i) !== _i) return; _n = false; } else { for (; !(_n = (_s = _x.call(_i)).done); _n = true) { _arr.push(_s.value); if (_arr.length === i) break; } } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) { _r = _i["return"](); if (Object(_r) !== _r) return; } } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1), From 4f951f3a4dd536097883c7bf10805eeb83b9ef62 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Sat, 12 Nov 2022 00:40:27 +0800 Subject: [PATCH 11/13] Simplify `iterableToArrayLimitLoose` --- packages/babel-helpers/src/helpers.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/babel-helpers/src/helpers.ts b/packages/babel-helpers/src/helpers.ts index 917e9f9dd242..f8c04ab806d2 100644 --- a/packages/babel-helpers/src/helpers.ts +++ b/packages/babel-helpers/src/helpers.ts @@ -823,14 +823,9 @@ helpers.iterableToArrayLimitLoose = helper("7.0.0-beta.0")` if (_i == null) return; var _arr = []; - _i = _i.call(arr); - if (i === 0) { - if (Object(_i) !== _i) return; - return _arr; - } - for (var _s; !(_s = _i.next()).done;) { + var _s; + for (_i = _i.call(arr); arr.length < i && !(_s = _i.next()).done; ) { _arr.push(_s.value); - if (i && _arr.length === i) break; } return _arr; } From 1f404cb463aed0366fb059900c5a7923f6f582e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 25 Nov 2022 07:46:28 +0100 Subject: [PATCH 12/13] Move helpers to a separate file --- .../babel-helpers/src/helpers-generated.ts | 8 +++ packages/babel-helpers/src/helpers.ts | 63 ------------------- .../src/helpers/iterableToArrayLimit.js | 54 ++++++++++++++++ .../src/helpers/iterableToArrayLimitLoose.js | 16 +++++ packages/babel-runtime-corejs2/package.json | 36 +++++------ packages/babel-runtime-corejs3/package.json | 36 +++++------ packages/babel-runtime/package.json | 36 +++++------ 7 files changed, 132 insertions(+), 117 deletions(-) create mode 100644 packages/babel-helpers/src/helpers/iterableToArrayLimit.js create mode 100644 packages/babel-helpers/src/helpers/iterableToArrayLimitLoose.js diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index 19663a2a73f2..b1b389a98b34 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -45,6 +45,14 @@ export default Object.freeze({ "7.20.1", 'export default function _checkInRHS(value){if(Object(value)!==value)throw TypeError("right-hand side of \'in\' should be an object, got "+(null!==value?typeof value:"null"));return value}', ), + iterableToArrayLimit: helper( + "7.0.0-beta.0", + 'export default function _iterableToArrayLimit(arr,i){var _i=null==arr?null:"undefined"!=typeof Symbol&&arr[Symbol.iterator]||arr["@@iterator"];if(null!=_i){var _s,_e,_x,_r,_arr=[],_n=!0,_d=!1;try{if(_x=(_i=_i.call(arr)).next,0===i){if(Object(_i)!==_i)return;_n=!1}else for(;!(_n=(_s=_x.call(_i)).done)&&(_arr.push(_s.value),_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{if(!_n&&null!=_i.return&&(_r=_i.return(),Object(_r)!==_r))return}finally{if(_d)throw _e}}return _arr}}', + ), + iterableToArrayLimitLoose: helper( + "7.0.0-beta.0", + 'export default function _iterableToArrayLimitLoose(arr,i){var _i=arr&&("undefined"!=typeof Symbol&&arr[Symbol.iterator]||arr["@@iterator"]);if(null!=_i){var _s,_arr=[];for(_i=_i.call(arr);arr.length1){for(var childArray=new Array(childrenLength),i=0;i Date: Fri, 25 Nov 2022 07:57:50 +0100 Subject: [PATCH 13/13] Update fixtures --- .../test/fixtures/regression/T7199/output.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js index fa4ed1d67749..57d7b6094b99 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7199/output.js @@ -6,7 +6,7 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } -function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e, _x, _r; try { _x = (_i = _i.call(arr)).next; if (i === 0) { if (Object(_i) !== _i) return; _n = false; } else { for (; !(_n = (_s = _x.call(_i)).done); _n = true) { _arr.push(_s.value); if (_arr.length === i) break; } } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) { _r = _i["return"](); if (Object(_r) !== _r) return; } } finally { if (_d) throw _e; } } return _arr; } +function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } const _bar = bar, _bar2 = _slicedToArray(_bar, 1),