From 6f932978f8e69faa5f2f99baf96a2e23f8316204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 19 Mar 2020 02:17:41 +0100 Subject: [PATCH] =?UTF-8?q?Add=20for-of=20fallback=20for=20arrays=20in=20b?= =?UTF-8?q?rowsers=20without=20symbol=20supp=E2=80=A6=20(#11263)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add for-of fallback for arrays in browsers without symbol support * Update after rebase * Re-throw error when iterating array * Update fixture --- packages/babel-helpers/src/helpers.js | 19 ++++++++++++++- .../array-symbol-unsupported-throw.js | 23 +++++++++++++++++++ .../sanity/block-scoping-for-of/output.js | 2 +- 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-symbol-unsupported-throw.js diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index 009332c162d7..44ce01583a7a 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -1078,8 +1078,24 @@ helpers.createForOfIteratorHelper = helper("7.9.0")` // f: finish (always called at the end) export default function _createForOfIteratorHelper(o) { - if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) + if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { + // Fallback for engines without symbol support + if (Array.isArray(o)) { + var i = 0; + var F = function(){}; + return { + s: F, + n: function() { + if (i >= o.length) return { done: true }; + return { done: false, value: o[i++] }; + }, + e: function(e) { throw e; }, + f: F, + }; + } + throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } var it, normalCompletion = true, didErr = false, err; @@ -1112,6 +1128,7 @@ helpers.createForOfIteratorHelperLoose = helper("7.9.0")` var i = 0; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { + // Fallback for engines without symbol support if (Array.isArray(o)) return function() { if (i >= o.length) return { done: true }; diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-symbol-unsupported-throw.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-symbol-unsupported-throw.js new file mode 100644 index 000000000000..d0960352c267 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-symbol-unsupported-throw.js @@ -0,0 +1,23 @@ +var a = (() => [1, 2, 3])(); + +// Simulate old environment +let _Symbol = Symbol; +Symbol = void 0; +try { + let didErr = false, err; + let obj = {}; + + try { + for (let i of a) { + if (i === 2) throw obj; + } + } catch (e) { + didErr = true; + err = e; + } + + expect(didErr).toBe(true); + expect(obj).toBe(err); +} finally { + Symbol = _Symbol; +} diff --git a/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js b/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js index 8f0ed5b54574..8659fc16330d 100644 --- a/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js +++ b/packages/babel-preset-env/test/fixtures/sanity/block-scoping-for-of/output.js @@ -10,7 +10,7 @@ function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !( function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } -function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e) { didErr = true; err = _e; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } +function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o)) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } // https://github.com/babel/babel/issues/7557 var _iterator = _createForOfIteratorHelper(c),