diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index 5aa4fad4a894..4d589f58e3a3 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -1036,6 +1036,61 @@ helpers.nonIterableRest = helper("7.0.0-beta.0")` } `; +helpers.createForOfIteratorHelper = helper("7.9.0")` + // s: start (create the iterator) + // n: next + // e: error (called whenever something throws) + // f: finish (always called at the end) + + export default 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() { + it = o[Symbol.iterator](); + }, + n() { + var step = it.next(); + normalCompletion = step.done; + return step; + }, + e(e) { + didErr = true; + err = e; + }, + f() { + try { + if (!normalCompletion && it.return != null) it.return(); + } finally { + if (didErr) throw err; + } + } + }; + } +`; + +helpers.createForOfIteratorHelperLoose = helper("7.9.0")` + export default function _createForOfIteratorHelperLoose(o) { + var i = 0; + + if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { + if (Array.isArray(o)) + return function() { + if (i >= o.length) return { done: true }; + return { done: false, value: o[i++] }; + } + + throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + i = o[Symbol.iterator](); + return i.next.bind(i); + } +`; + helpers.skipFirstGeneratorNext = helper("7.0.0-beta.0")` export default function _skipFirstGeneratorNext(fn) { return function () { diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/options.json index c1b2fe494b7f..9d3c67e6ce2d 100644 --- a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/options.json +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/options.json @@ -4,6 +4,7 @@ "syntax-jsx", "transform-react-jsx", "transform-block-scoped-functions", - "transform-for-of" + "transform-for-of", + ["external-helpers", { "helperVersion": "7.100.0" }] ] } diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/output.js index 0562fd1fe6f4..f9a734b608c3 100644 --- a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/output.js +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/hoisting/output.js @@ -10,12 +10,11 @@ var _loop = function (i) { }); }; -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(nums), + _step; try { - for (var _iterator = nums[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var i = _step.value; var x; var f; @@ -23,16 +22,7 @@ try { _loop(i); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-for-of/src/index.js b/packages/babel-plugin-transform-for-of/src/index.js index 4e203f8a7a83..429f2899a93a 100644 --- a/packages/babel-plugin-transform-for-of/src/index.js +++ b/packages/babel-plugin-transform-for-of/src/index.js @@ -1,6 +1,8 @@ import { declare } from "@babel/helper-plugin-utils"; import { template, types as t } from "@babel/core"; +import transformWithoutHelper from "./no-helper-implementation"; + export default declare((api, options) => { api.assertVersion(7); @@ -79,64 +81,45 @@ export default declare((api, options) => { }; } - const pushComputedProps = loose - ? pushComputedPropsLoose - : pushComputedPropsSpec; - const buildForOfArray = template(` for (var KEY = 0, NAME = ARR; KEY < NAME.length; KEY++) BODY; `); - const buildForOfLoose = template(` - for (var LOOP_OBJECT = OBJECT, - IS_ARRAY = Array.isArray(LOOP_OBJECT), - INDEX = 0, - LOOP_OBJECT = IS_ARRAY ? LOOP_OBJECT : LOOP_OBJECT[Symbol.iterator]();;) { - INTERMEDIATE; - if (IS_ARRAY) { - if (INDEX >= LOOP_OBJECT.length) break; - ID = LOOP_OBJECT[INDEX++]; - } else { - INDEX = LOOP_OBJECT.next(); - if (INDEX.done) break; - ID = INDEX.value; - } - } + const buildForOfLoose = template.statements(` + for (var ITERATOR_HELPER = CREATE_ITERATOR_HELPER(OBJECT), STEP_KEY; + !(STEP_KEY = ITERATOR_HELPER()).done;) BODY; `); - const buildForOf = template(` - var ITERATOR_COMPLETION = true; - var ITERATOR_HAD_ERROR_KEY = false; - var ITERATOR_ERROR_KEY = undefined; + const buildForOf = template.statements(` + var ITERATOR_HELPER = CREATE_ITERATOR_HELPER(OBJECT), STEP_KEY; try { - for ( - var ITERATOR_KEY = OBJECT[Symbol.iterator](), STEP_KEY; - !(ITERATOR_COMPLETION = (STEP_KEY = ITERATOR_KEY.next()).done); - ITERATOR_COMPLETION = true - ) {} + for (ITERATOR_HELPER.s(); !(STEP_KEY = ITERATOR_HELPER.n()).done;) BODY; } catch (err) { - ITERATOR_HAD_ERROR_KEY = true; - ITERATOR_ERROR_KEY = err; + ITERATOR_HELPER.e(err); } finally { - try { - if (!ITERATOR_COMPLETION && ITERATOR_KEY.return != null) { - ITERATOR_KEY.return(); - } - } finally { - if (ITERATOR_HAD_ERROR_KEY) { - throw ITERATOR_ERROR_KEY; - } - } + ITERATOR_HELPER.f(); } `); + const builder = loose + ? { + build: buildForOfLoose, + helper: "createForOfIteratorHelperLoose", + getContainer: nodes => nodes, + } + : { + build: buildForOf, + helper: "createForOfIteratorHelper", + getContainer: nodes => nodes[1].block.body, + }; + function _ForOfStatementArray(path) { const { node, scope } = path; const right = scope.generateUidIdentifierBasedOnNode(node.right, "arr"); const iterationKey = scope.generateUidIdentifier("i"); - let loop = buildForOfArray({ + const loop = buildForOfArray({ BODY: node.body, KEY: iterationKey, NAME: right, @@ -164,19 +147,7 @@ export default declare((api, options) => { ); } - if (path.parentPath.isLabeledStatement()) { - loop = t.labeledStatement(path.parentPath.node.label, loop); - } - - return [loop]; - } - - function replaceWithArray(path) { - if (path.parentPath.isLabeledStatement()) { - path.parentPath.replaceWithMultiple(_ForOfStatementArray(path)); - } else { - path.replaceWithMultiple(_ForOfStatementArray(path)); - } + return loop; } return { @@ -189,156 +160,64 @@ export default declare((api, options) => { right.isGenericType("Array") || t.isArrayTypeAnnotation(right.getTypeAnnotation()) ) { - replaceWithArray(path); + path.replaceWith(_ForOfStatementArray(path)); return; } - const { node } = path; - const build = pushComputedProps(path, state); - const declar = build.declar; - const loop = build.loop; - const block = loop.body; + if (!state.availableHelper(builder.helper)) { + // Babel <7.9.0 doesn't support this helper + transformWithoutHelper(loose, path, state); + return; + } + + const { node, parent, scope } = path; + const left = node.left; + let declar; + + const stepKey = scope.generateUid("step"); + const stepValue = t.memberExpression( + t.identifier(stepKey), + t.identifier("value"), + ); + + if (t.isVariableDeclaration(left)) { + // for (let i of test) + declar = t.variableDeclaration(left.kind, [ + t.variableDeclarator(left.declarations[0].id, stepValue), + ]); + } else { + // for (i of test), for ({ i } of test) + declar = t.expressionStatement( + t.assignmentExpression("=", left, stepValue), + ); + } // ensure that it's a block so we can take all its statements path.ensureBlock(); - // add the value declaration to the new loop body - if (declar) { - block.body.push(declar); - } + node.body.body.unshift(declar); - // push the rest of the original loop body onto our new body - block.body = block.body.concat(node.body.body); + const nodes = builder.build({ + CREATE_ITERATOR_HELPER: state.addHelper(builder.helper), + ITERATOR_HELPER: scope.generateUidIdentifier("iterator"), + STEP_KEY: t.identifier(stepKey), + OBJECT: node.right, + BODY: node.body, + }); + const container = builder.getContainer(nodes); - t.inherits(loop, node); - t.inherits(loop.body, node.body); + t.inherits(container[0], node); + t.inherits(container[0].body, node.body); - if (build.replaceParent) { - path.parentPath.replaceWithMultiple(build.node); + if (t.isLabeledStatement(parent)) { + container[0] = t.labeledStatement(parent.label, container[0]); + + path.parentPath.replaceWithMultiple(nodes); path.remove(); } else { - path.replaceWithMultiple(build.node); + path.replaceWithMultiple(nodes); } }, }, }; - - function pushComputedPropsLoose(path, file) { - const { node, scope, parent } = path; - const { left } = node; - let declar, id, intermediate; - - if ( - t.isIdentifier(left) || - t.isPattern(left) || - t.isMemberExpression(left) - ) { - // for (i of test), for ({ i } of test) - id = left; - intermediate = null; - } else if (t.isVariableDeclaration(left)) { - // for (let i of test) - id = scope.generateUidIdentifier("ref"); - declar = t.variableDeclaration(left.kind, [ - t.variableDeclarator(left.declarations[0].id, t.identifier(id.name)), - ]); - intermediate = t.variableDeclaration("var", [ - t.variableDeclarator(t.identifier(id.name)), - ]); - } else { - throw file.buildCodeFrameError( - left, - `Unknown node type ${left.type} in ForStatement`, - ); - } - - const iteratorKey = scope.generateUidIdentifier("iterator"); - const isArrayKey = scope.generateUidIdentifier("isArray"); - - const loop = buildForOfLoose({ - LOOP_OBJECT: iteratorKey, - IS_ARRAY: isArrayKey, - OBJECT: node.right, - INDEX: scope.generateUidIdentifier("i"), - ID: id, - INTERMEDIATE: intermediate, - }); - - // - const isLabeledParent = t.isLabeledStatement(parent); - let labeled; - - if (isLabeledParent) { - labeled = t.labeledStatement(parent.label, loop); - } - - return { - replaceParent: isLabeledParent, - declar: declar, - node: labeled || loop, - loop: loop, - }; - } - - function pushComputedPropsSpec(path, file) { - const { node, scope, parent } = path; - const left = node.left; - let declar; - - const stepKey = scope.generateUid("step"); - const stepValue = t.memberExpression( - t.identifier(stepKey), - t.identifier("value"), - ); - - if ( - t.isIdentifier(left) || - t.isPattern(left) || - t.isMemberExpression(left) - ) { - // for (i of test), for ({ i } of test) - declar = t.expressionStatement( - t.assignmentExpression("=", left, stepValue), - ); - } else if (t.isVariableDeclaration(left)) { - // for (let i of test) - declar = t.variableDeclaration(left.kind, [ - t.variableDeclarator(left.declarations[0].id, stepValue), - ]); - } else { - throw file.buildCodeFrameError( - left, - `Unknown node type ${left.type} in ForStatement`, - ); - } - - const template = buildForOf({ - ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"), - ITERATOR_COMPLETION: scope.generateUidIdentifier( - "iteratorNormalCompletion", - ), - ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"), - ITERATOR_KEY: scope.generateUidIdentifier("iterator"), - STEP_KEY: t.identifier(stepKey), - OBJECT: node.right, - }); - - const isLabeledParent = t.isLabeledStatement(parent); - - const tryBody = template[3].block.body; - const loop = tryBody[0]; - - if (isLabeledParent) { - tryBody[0] = t.labeledStatement(parent.label, loop); - } - - // - - return { - replaceParent: isLabeledParent, - declar: declar, - loop: loop, - node: template, - }; - } }); diff --git a/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js b/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js new file mode 100644 index 000000000000..2624f0bc9093 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/src/no-helper-implementation.js @@ -0,0 +1,192 @@ +import { template, types as t } from "@babel/core"; + +// This is the legacy implementation, which inlines all the code. +// It must be kept for compatibility reasons. +// TODO (Babel 8): Remove this code. + +export default function transformWithoutHelper(loose, path, state) { + const pushComputedProps = loose + ? pushComputedPropsLoose + : pushComputedPropsSpec; + + const { node } = path; + const build = pushComputedProps(path, state); + const declar = build.declar; + const loop = build.loop; + const block = loop.body; + + // ensure that it's a block so we can take all its statements + path.ensureBlock(); + + // add the value declaration to the new loop body + if (declar) { + block.body.push(declar); + } + + // push the rest of the original loop body onto our new body + block.body = block.body.concat(node.body.body); + + t.inherits(loop, node); + t.inherits(loop.body, node.body); + + if (build.replaceParent) { + path.parentPath.replaceWithMultiple(build.node); + path.remove(); + } else { + path.replaceWithMultiple(build.node); + } +} + +const buildForOfLoose = template(` + for (var LOOP_OBJECT = OBJECT, + IS_ARRAY = Array.isArray(LOOP_OBJECT), + INDEX = 0, + LOOP_OBJECT = IS_ARRAY ? LOOP_OBJECT : LOOP_OBJECT[Symbol.iterator]();;) { + INTERMEDIATE; + if (IS_ARRAY) { + if (INDEX >= LOOP_OBJECT.length) break; + ID = LOOP_OBJECT[INDEX++]; + } else { + INDEX = LOOP_OBJECT.next(); + if (INDEX.done) break; + ID = INDEX.value; + } + } +`); + +const buildForOf = template(` + var ITERATOR_COMPLETION = true; + var ITERATOR_HAD_ERROR_KEY = false; + var ITERATOR_ERROR_KEY = undefined; + try { + for ( + var ITERATOR_KEY = OBJECT[Symbol.iterator](), STEP_KEY; + !(ITERATOR_COMPLETION = (STEP_KEY = ITERATOR_KEY.next()).done); + ITERATOR_COMPLETION = true + ) {} + } catch (err) { + ITERATOR_HAD_ERROR_KEY = true; + ITERATOR_ERROR_KEY = err; + } finally { + try { + if (!ITERATOR_COMPLETION && ITERATOR_KEY.return != null) { + ITERATOR_KEY.return(); + } + } finally { + if (ITERATOR_HAD_ERROR_KEY) { + throw ITERATOR_ERROR_KEY; + } + } + } +`); + +function pushComputedPropsLoose(path, file) { + const { node, scope, parent } = path; + const { left } = node; + let declar, id, intermediate; + + if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) { + // for (i of test), for ({ i } of test) + id = left; + intermediate = null; + } else if (t.isVariableDeclaration(left)) { + // for (let i of test) + id = scope.generateUidIdentifier("ref"); + declar = t.variableDeclaration(left.kind, [ + t.variableDeclarator(left.declarations[0].id, t.identifier(id.name)), + ]); + intermediate = t.variableDeclaration("var", [ + t.variableDeclarator(t.identifier(id.name)), + ]); + } else { + throw file.buildCodeFrameError( + left, + `Unknown node type ${left.type} in ForStatement`, + ); + } + + const iteratorKey = scope.generateUidIdentifier("iterator"); + const isArrayKey = scope.generateUidIdentifier("isArray"); + + const loop = buildForOfLoose({ + LOOP_OBJECT: iteratorKey, + IS_ARRAY: isArrayKey, + OBJECT: node.right, + INDEX: scope.generateUidIdentifier("i"), + ID: id, + INTERMEDIATE: intermediate, + }); + + // + const isLabeledParent = t.isLabeledStatement(parent); + let labeled; + + if (isLabeledParent) { + labeled = t.labeledStatement(parent.label, loop); + } + + return { + replaceParent: isLabeledParent, + declar: declar, + node: labeled || loop, + loop: loop, + }; +} + +function pushComputedPropsSpec(path, file) { + const { node, scope, parent } = path; + const left = node.left; + let declar; + + const stepKey = scope.generateUid("step"); + const stepValue = t.memberExpression( + t.identifier(stepKey), + t.identifier("value"), + ); + + if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) { + // for (i of test), for ({ i } of test) + declar = t.expressionStatement( + t.assignmentExpression("=", left, stepValue), + ); + } else if (t.isVariableDeclaration(left)) { + // for (let i of test) + declar = t.variableDeclaration(left.kind, [ + t.variableDeclarator(left.declarations[0].id, stepValue), + ]); + } else { + throw file.buildCodeFrameError( + left, + `Unknown node type ${left.type} in ForStatement`, + ); + } + + const template = buildForOf({ + ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"), + ITERATOR_COMPLETION: scope.generateUidIdentifier( + "iteratorNormalCompletion", + ), + ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"), + ITERATOR_KEY: scope.generateUidIdentifier("iterator"), + STEP_KEY: t.identifier(stepKey), + OBJECT: node.right, + }); + + const isLabeledParent = t.isLabeledStatement(parent); + + const tryBody = template[3].block.body; + const loop = tryBody[0]; + + if (isLabeledParent) { + tryBody[0] = t.labeledStatement(parent.label, loop); + } + + // + + return { + replaceParent: isLabeledParent, + declar: declar, + loop: loop, + node: template, + }; +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array-break.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array-break.js new file mode 100644 index 000000000000..ffa1dbfb4296 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array-break.js @@ -0,0 +1,9 @@ +let arr = (() => [1, 2, 3])(); // Disable inference +let res = []; + +for (const x of arr) { + if (x === 2) break; + res.push(x); +} + +expect(res).toEqual([1]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array-continue.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array-continue.js new file mode 100644 index 000000000000..d0112f95c4a7 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array-continue.js @@ -0,0 +1,9 @@ +let arr = (() => [1, 2, 3])(); // Disable inference +let res = []; + +for (const x of arr) { + if (x === 2) continue; + res.push(x); +} + +expect(res).toEqual([1, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array.js new file mode 100644 index 000000000000..7750c2d157a6 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/array.js @@ -0,0 +1,6 @@ +let arr = (() => [1, 2, 3])(); // Disable inference +let res = []; + +for (const x of arr) res.push(x); + +expect(res).toEqual([1, 2, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator-break.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator-break.js new file mode 100644 index 000000000000..2509928d098b --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator-break.js @@ -0,0 +1,12 @@ +function* f() { + yield 1; yield 2; yield 3; +} + +let res = []; + +for (const x of f()) { + if (x === 2) break; + res.push(x); +} + +expect(res).toEqual([1]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator-continue.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator-continue.js new file mode 100644 index 000000000000..393a703d19a1 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator-continue.js @@ -0,0 +1,12 @@ +function* f() { + yield 1; yield 2; yield 3; +} + +let res = []; + +for (const x of f()) { + if (x === 2) continue; + res.push(x); +} + +expect(res).toEqual([1, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator.js new file mode 100644 index 000000000000..988f89a46aec --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/generator.js @@ -0,0 +1,9 @@ +function* f() { + yield 1; yield 2; yield 3; +} + +let res = []; + +for (const x of f()) res.push(x); + +expect(res).toEqual([1, 2, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/options.json b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/options.json new file mode 100644 index 000000000000..56e88c472f4f --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose-exec/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + ["transform-for-of", { "loose": true }], + ["external-helpers", { "helperVersion": "7.100.0" }] + ] +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/identifier/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose/identifier/output.js index 4ce44f50f58c..09cfa4b62184 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/identifier/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/identifier/output.js @@ -1,10 +1,3 @@ -for (var _iterator = arr, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - if (_isArray) { - if (_i >= _iterator.length) break; - i = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - i = _i.value; - } +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + i = _step.value; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/ignore-cases/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose/ignore-cases/output.js index 9c64275021c0..346e9bed2735 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/ignore-cases/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/ignore-cases/output.js @@ -1,16 +1,5 @@ -for (var _iterator = foo, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - var i = _ref; +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(foo), _step; !(_step = _iterator()).done;) { + var i = _step.value; switch (i) { case 1: diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/let/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose/let/output.js index 097ced3ac720..5181b1253590 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/let/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/let/output.js @@ -1,14 +1,3 @@ -for (var _iterator = arr, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - let i = _ref; +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + let i = _step.value; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/member-expression/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose/member-expression/output.js index 4945bb71274f..670a8f952d51 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/member-expression/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/member-expression/output.js @@ -1,10 +1,3 @@ -for (var _iterator = arr, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - if (_isArray) { - if (_i >= _iterator.length) break; - obj.prop = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - obj.prop = _i.value; - } +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + obj.prop = _step.value; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/multiple/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose/multiple/output.js index 985c62fc8563..adc55422e337 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/multiple/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/multiple/output.js @@ -1,29 +1,7 @@ -for (var _iterator = arr, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - var i = _ref; +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + var i = _step.value; } -for (var _iterator2 = numbers, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - - var i = _ref2; +for (var _iterator2 = babelHelpers.createForOfIteratorHelperLoose(numbers), _step2; !(_step2 = _iterator2()).done;) { + var i = _step2.value; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/nested-label-for-of/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose/nested-label-for-of/output.js index eb23e78167bd..87e1ddec80f7 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/nested-label-for-of/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/nested-label-for-of/output.js @@ -1,30 +1,8 @@ -b: for (var _iterator = d(), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; +b: for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(d()), _step; !(_step = _iterator()).done;) { + let c = _step.value; - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - let c = _ref; - - for (var _iterator2 = f(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - - let e = _ref2; + for (var _iterator2 = babelHelpers.createForOfIteratorHelperLoose(f()), _step2; !(_step2 = _iterator2()).done;) { + let e = _step2.value; continue b; } } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/options.json b/packages/babel-plugin-transform-for-of/test/fixtures/loose/options.json index b180b3b7a8c9..56e88c472f4f 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/options.json +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/options.json @@ -1,3 +1,6 @@ { - "plugins": [["transform-for-of", { "loose": true }]] + "plugins": [ + ["transform-for-of", { "loose": true }], + ["external-helpers", { "helperVersion": "7.100.0" }] + ] } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/loose/var/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/loose/var/output.js index 7565d63def0a..c9f297e237ab 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/loose/var/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/loose/var/output.js @@ -1,14 +1,3 @@ -for (var _iterator = arr, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - var i = _ref; +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + var i = _step.value; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/opt/options.json b/packages/babel-plugin-transform-for-of/test/fixtures/opt/options.json index 5ac45b8e39fe..fab63f43b1f5 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/opt/options.json +++ b/packages/babel-plugin-transform-for-of/test/fixtures/opt/options.json @@ -1,3 +1,7 @@ { - "plugins": ["transform-for-of", "transform-flow-strip-types"] + "plugins": [ + "transform-for-of", + "transform-flow-strip-types", + ["external-helpers", { "helperVersion": "7.100.0" }] + ] } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/opt/typeannotation/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/opt/typeannotation/output.js index 55ebccb8d7db..7b047a5d5517 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/opt/typeannotation/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/opt/typeannotation/output.js @@ -3,26 +3,16 @@ for (var _i = 0, _arr = b; _i < _arr.length; _i++) { } function a(b) { - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + var _iterator = babelHelpers.createForOfIteratorHelper(b), + _step; try { - for (var _iterator = b[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { const y = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/if-label-3858/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/regression/if-label-3858/output.js index 0085c57dcafa..25a2ca8e2f22 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/regression/if-label-3858/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/if-label-3858/output.js @@ -1,5 +1,3 @@ -if (true) { - loop: for (var _i = 0, _arr = []; _i < _arr.length; _i++) { - let ch = _arr[_i]; - } +if (true) loop: for (var _i = 0, _arr = []; _i < _arr.length; _i++) { + let ch = _arr[_i]; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/label-object-with-comment-4995/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/regression/label-object-with-comment-4995/output.js index 6350ca6bee63..81e37c25b3a5 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/regression/label-object-with-comment-4995/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/label-object-with-comment-4995/output.js @@ -1,24 +1,14 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(b), + _step; try { myLabel: //woops - for (var _iterator = b[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { let a = _step.value; continue myLabel; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/options.json b/packages/babel-plugin-transform-for-of/test/fixtures/regression/options.json index 9d8c9cc3446e..529e1126a163 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/regression/options.json +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/options.json @@ -1,3 +1,6 @@ { - "plugins": ["transform-for-of"] + "plugins": [ + "transform-for-of", + ["external-helpers", { "helperVersion": "7.100.0" }] + ] } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-break.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-break.js new file mode 100644 index 000000000000..ffa1dbfb4296 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-break.js @@ -0,0 +1,9 @@ +let arr = (() => [1, 2, 3])(); // Disable inference +let res = []; + +for (const x of arr) { + if (x === 2) break; + res.push(x); +} + +expect(res).toEqual([1]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-continue.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-continue.js new file mode 100644 index 000000000000..d0112f95c4a7 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array-continue.js @@ -0,0 +1,9 @@ +let arr = (() => [1, 2, 3])(); // Disable inference +let res = []; + +for (const x of arr) { + if (x === 2) continue; + res.push(x); +} + +expect(res).toEqual([1, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array.js new file mode 100644 index 000000000000..7750c2d157a6 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/array.js @@ -0,0 +1,6 @@ +let arr = (() => [1, 2, 3])(); // Disable inference +let res = []; + +for (const x of arr) res.push(x); + +expect(res).toEqual([1, 2, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator-break.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator-break.js new file mode 100644 index 000000000000..2509928d098b --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator-break.js @@ -0,0 +1,12 @@ +function* f() { + yield 1; yield 2; yield 3; +} + +let res = []; + +for (const x of f()) { + if (x === 2) break; + res.push(x); +} + +expect(res).toEqual([1]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator-continue.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator-continue.js new file mode 100644 index 000000000000..393a703d19a1 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator-continue.js @@ -0,0 +1,12 @@ +function* f() { + yield 1; yield 2; yield 3; +} + +let res = []; + +for (const x of f()) { + if (x === 2) continue; + res.push(x); +} + +expect(res).toEqual([1, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator.js new file mode 100644 index 000000000000..988f89a46aec --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/generator.js @@ -0,0 +1,9 @@ +function* f() { + yield 1; yield 2; yield 3; +} + +let res = []; + +for (const x of f()) res.push(x); + +expect(res).toEqual([1, 2, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/options.json b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/options.json new file mode 100644 index 000000000000..4cfffdb34840 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + ["transform-for-of", { "loose": false }], + ["external-helpers", { "helperVersion": "7.100.0" }] + ] +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/throw-iterator-handling.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/throw-iterator-handling.js new file mode 100644 index 000000000000..50a5f512137e --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec-exec/throw-iterator-handling.js @@ -0,0 +1,35 @@ +let done = false, value = 0; + +// jest.fn isn't available in exec tests +function fn(impl = () => {}) { + function f() { + f.calls++; + return impl(); + } + f.calls = 0; + return f; +} + +const iterator = { + next: fn(() => ({ done, value })), + throw: fn(), + return: fn(() => { throw {} }), +}; + +const obj = { + [Symbol.iterator]: fn(() => iterator), +}; + +const err = new Error(); + +expect(() => { + for (const x of obj) { + value++; + if (value == 2) throw err; + } +}).toThrow(err); + +expect(obj[Symbol.iterator].calls).toBe(1); +expect(iterator.next.calls).toBe(2); +expect(iterator.throw.calls).toBe(0); +expect(iterator.return.calls).toBe(1); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/identifier/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec/identifier/output.js index a8f3a57a580f..e4f502d49422 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/identifier/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/identifier/output.js @@ -1,22 +1,12 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { i = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/ignore-cases/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec/ignore-cases/output.js index 908af15f61c5..0b4feeecf9d9 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/ignore-cases/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/ignore-cases/output.js @@ -1,9 +1,8 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(foo), + _step; try { - for (var _iterator = foo[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var i = _step.value; switch (i) { @@ -12,16 +11,7 @@ try { } } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/let/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec/let/output.js index 2dbda90cd964..fd1743ed5d38 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/let/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/let/output.js @@ -1,22 +1,12 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { let i = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/member-expression/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec/member-expression/output.js index ffe31ebc3c10..5707826b647b 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/member-expression/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/member-expression/output.js @@ -1,22 +1,12 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { obj.prop = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/multiple/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec/multiple/output.js index d467fabeb6ff..6f636f1b5743 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/multiple/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/multiple/output.js @@ -1,45 +1,25 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var i = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } -var _iteratorNormalCompletion2 = true; -var _didIteratorError2 = false; -var _iteratorError2 = undefined; +var _iterator2 = babelHelpers.createForOfIteratorHelper(numbers), + _step2; try { - for (var _iterator2 = numbers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var i = _step2.value; } } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; + _iterator2.e(err); } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return != null) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } + _iterator2.f(); } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/nested-label-for-of/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec/nested-label-for-of/output.js index 95b8cc547295..2a3ce2b3627e 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/nested-label-for-of/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/nested-label-for-of/output.js @@ -1,45 +1,26 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(d()), + _step; try { - b: for (var _iterator = d()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + b: for (_iterator.s(); !(_step = _iterator.n()).done;) { let c = _step.value; - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; + + var _iterator2 = babelHelpers.createForOfIteratorHelper(f()), + _step2; try { - for (var _iterator2 = f()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { let e = _step2.value; continue b; } } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; + _iterator2.e(err); } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return != null) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } + _iterator2.f(); } } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/options.json b/packages/babel-plugin-transform-for-of/test/fixtures/spec/options.json index 9d8c9cc3446e..3e99d8381d2b 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/options.json +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/options.json @@ -1,3 +1,6 @@ { - "plugins": ["transform-for-of"] + "plugins": [ + "transform-for-of", + ["external-helpers", { "helperVersion": "7.100.0" }] + ] } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/spec/var/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/spec/var/output.js index ec97a710aed5..941432518de7 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/spec/var/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/spec/var/output.js @@ -1,22 +1,12 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = babelHelpers.createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var i = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json index 4698618caab7..81ab23a54067 100644 --- a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json @@ -1,7 +1,7 @@ { "plugins": [ "proposal-class-properties", - "external-helpers", + ["external-helpers", { "helperVersion": "7.100.0" }], "syntax-typescript", "syntax-flow", "transform-parameters", diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/output.js b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/output.js index 29238be5a127..8330132f0bf9 100644 --- a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/output.js +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-member-expression-deoptimisation/output.js @@ -153,28 +153,18 @@ function forOf() { rest[_key16] = arguments[_key16]; } - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; + var _iterator = babelHelpers.createForOfIteratorHelper(this), + _step; try { - for (var _iterator = this[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { rest[0] = _step.value; ; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } } diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-nested-iife/output.js b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-nested-iife/output.js index a6a5a35134fb..72b8f12f86a7 100644 --- a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-nested-iife/output.js +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-nested-iife/output.js @@ -1,7 +1,3 @@ -function _createSuper(Derived) { return function () { var Super = babelHelpers.getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = babelHelpers.getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return babelHelpers.possibleConstructorReturn(this, result); }; } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } - function broken(x) { if (true) { var Foo = /*#__PURE__*/function (_Bar) { @@ -9,7 +5,7 @@ function broken(x) { babelHelpers.inherits(Foo, _Bar); - var _super = _createSuper(Foo); + var _super = babelHelpers.createSuper(Foo); function Foo() { babelHelpers.classCallCheck(this, Foo); diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/options.json b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/options.json index 5b5b7b35f106..a855e9bdf376 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/options.json +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/options.json @@ -1,3 +1,6 @@ { - "plugins": ["transform-for-of", ["transform-runtime", { "corejs": 2 }]] + "plugins": [ + "transform-for-of", + ["transform-runtime", { "corejs": 2, "version": "7.100.0" }] + ] } diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/output.js index be11791731f3..ad7039a8ea59 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/output.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/es6-for-of/output.js @@ -1,24 +1,14 @@ -var _getIterator = require("@babel/runtime-corejs2/core-js/get-iterator"); +var _createForOfIteratorHelper = require("@babel/runtime-corejs2/helpers/createForOfIteratorHelper"); -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = _createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = _getIterator(arr), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var i = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/options.json b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/options.json index 79f4e0ec1085..e26d8d98a9bc 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/options.json +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/options.json @@ -1,3 +1,6 @@ { - "plugins": ["transform-for-of", ["transform-runtime", { "corejs": 3 }]] + "plugins": [ + "transform-for-of", + ["transform-runtime", { "corejs": 3, "version": "7.100.0" }] + ] } diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/output.js index 2bb4ba66cbc7..a8dac71ca6f0 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/output.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/es6-for-of/output.js @@ -1,24 +1,14 @@ -var _getIterator = require("@babel/runtime-corejs3/core-js/get-iterator"); +var _createForOfIteratorHelper = require("@babel/runtime-corejs3/helpers/createForOfIteratorHelper"); -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = _createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = _getIterator(arr), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var i = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/options.json b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/options.json index 79e414ae0c4a..7823a1ff438a 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/options.json +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/options.json @@ -1,3 +1,6 @@ { - "plugins": ["transform-for-of", "transform-runtime"] + "plugins": [ + "transform-for-of", + ["transform-runtime", { "version": "7.100.0" }] + ] } diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/output.js index ec97a710aed5..7a9a9c6cf2e5 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/output.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/output.js @@ -1,22 +1,14 @@ -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _createForOfIteratorHelper = require("@babel/runtime/helpers/createForOfIteratorHelper"); + +var _iterator = _createForOfIteratorHelper(arr), + _step; try { - for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { var i = _step.value; } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return != null) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); } 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 4e061ab31db5..6e042ccb6338 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 @@ -6,10 +6,11 @@ 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; } } }; } + // https://github.com/babel/babel/issues/7557 -var _iteratorNormalCompletion = true; -var _didIteratorError = false; -var _iteratorError = undefined; +var _iterator = _createForOfIteratorHelper(c), + _step; try { var _loop = function _loop() { @@ -23,20 +24,11 @@ try { }); }; - for (var _iterator = c[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator.s(); !(_step = _iterator.n()).done;) { _loop(); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _iterator.e(err); } finally { - try { - if (!_iteratorNormalCompletion && _iterator["return"] != null) { - _iterator["return"](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } + _iterator.f(); }