diff --git a/packages/babel-core/src/config/validation/options.js b/packages/babel-core/src/config/validation/options.js index 4e383eb47b46..5b45a0dcbd74 100644 --- a/packages/babel-core/src/config/validation/options.js +++ b/packages/babel-core/src/config/validation/options.js @@ -337,11 +337,12 @@ export const assumptionsNames = new Set([ "ignoreToPrimitiveHint", "iterableIsArray", "mutableTemplateObject", + "noDocumentAll", "pureGetters", "setClassMethods", "setComputedProperties", "setPublicClassFields", - "noDocumentAll", + "skipForOfIteratorClosing", ]); function getSource(loc: NestingPath): OptionsSource { diff --git a/packages/babel-plugin-transform-for-of/src/index.js b/packages/babel-plugin-transform-for-of/src/index.js index 25386f1ba836..1207433d02cf 100644 --- a/packages/babel-plugin-transform-for-of/src/index.js +++ b/packages/babel-plugin-transform-for-of/src/index.js @@ -6,10 +6,8 @@ import transformWithoutHelper from "./no-helper-implementation"; export default declare((api, options) => { api.assertVersion(7); - const { loose } = options; - { - const { assumeArray, allowArrayLike } = options; + const { assumeArray, allowArrayLike, loose } = options; if (loose === true && assumeArray === true) { throw new Error( @@ -35,11 +33,14 @@ export default declare((api, options) => { options.assumeArray ?? // Loose mode is not compatible with 'assumeArray', so we shouldn't read // 'iterableIsArray' if 'loose' is true. - (!loose && api.assumption("iterableIsArray")); + (!options.loose && api.assumption("iterableIsArray")); const arrayLikeIsIterable = options.allowArrayLike ?? api.assumption("arrayLikeIsIterable"); + const skipteratorClosing = + api.assumption("skipForOfIteratorClosing") ?? options.loose; + if (iterableIsArray && arrayLikeIsIterable) { throw new Error( `The "iterableIsArray" and "arrayLikeIsIterable" assumptions are not compatible.`, @@ -113,16 +114,16 @@ export default declare((api, options) => { }; } - const buildForOfArray = template(` + const buildForOfArray = template` for (var KEY = 0, NAME = ARR; KEY < NAME.length; KEY++) BODY; - `); + `; - const buildForOfLoose = template.statements(` + const buildForOfNoIteratorClosing = template.statements` for (var ITERATOR_HELPER = CREATE_ITERATOR_HELPER(OBJECT, ARRAY_LIKE_IS_ITERABLE), STEP_KEY; !(STEP_KEY = ITERATOR_HELPER()).done;) BODY; - `); + `; - const buildForOf = template.statements(` + const buildForOf = template.statements` var ITERATOR_HELPER = CREATE_ITERATOR_HELPER(OBJECT, ARRAY_LIKE_IS_ITERABLE), STEP_KEY; try { for (ITERATOR_HELPER.s(); !(STEP_KEY = ITERATOR_HELPER.n()).done;) BODY; @@ -131,11 +132,11 @@ export default declare((api, options) => { } finally { ITERATOR_HELPER.f(); } - `); + `; - const builder = loose + const builder = skipteratorClosing ? { - build: buildForOfLoose, + build: buildForOfNoIteratorClosing, helper: "createForOfIteratorHelperLoose", getContainer: nodes => nodes, } @@ -198,7 +199,7 @@ export default declare((api, options) => { if (!state.availableHelper(builder.helper)) { // Babel <7.9.0 doesn't support this helper - transformWithoutHelper(loose, path, state); + transformWithoutHelper(skipteratorClosing, path, state); return; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/identifier/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/identifier/input.js new file mode 100644 index 000000000000..ddd15051ba40 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/identifier/input.js @@ -0,0 +1,3 @@ +for (i of arr) { + +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/identifier/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/identifier/output.js new file mode 100644 index 000000000000..09cfa4b62184 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/identifier/output.js @@ -0,0 +1,3 @@ +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + i = _step.value; +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/ignore-cases/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/ignore-cases/input.js new file mode 100644 index 000000000000..e79141052993 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/ignore-cases/input.js @@ -0,0 +1,6 @@ +for (var i of foo) { + switch (i) { + case 1: + break; + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/ignore-cases/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/ignore-cases/output.js new file mode 100644 index 000000000000..346e9bed2735 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/ignore-cases/output.js @@ -0,0 +1,8 @@ +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(foo), _step; !(_step = _iterator()).done;) { + var i = _step.value; + + switch (i) { + case 1: + break; + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/let/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/let/input.js new file mode 100644 index 000000000000..f1e32392def1 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/let/input.js @@ -0,0 +1,3 @@ +for (let i of arr) { + +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/let/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/let/output.js new file mode 100644 index 000000000000..5181b1253590 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/let/output.js @@ -0,0 +1,3 @@ +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/assumption-skipForOfIteratorClosing/member-expression/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/member-expression/input.js new file mode 100644 index 000000000000..d67e03308150 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/member-expression/input.js @@ -0,0 +1,3 @@ +for (obj.prop of arr) { + +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/member-expression/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/member-expression/output.js new file mode 100644 index 000000000000..670a8f952d51 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/member-expression/output.js @@ -0,0 +1,3 @@ +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/assumption-skipForOfIteratorClosing/multiple/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/multiple/input.js new file mode 100644 index 000000000000..d9c969b80951 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/multiple/input.js @@ -0,0 +1,7 @@ +for (var i of arr) { + +} + +for (var i of numbers) { + +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/multiple/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/multiple/output.js new file mode 100644 index 000000000000..adc55422e337 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/multiple/output.js @@ -0,0 +1,7 @@ +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + var i = _step.value; +} + +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/assumption-skipForOfIteratorClosing/nested-label-for-of/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/nested-label-for-of/input.js new file mode 100644 index 000000000000..73c8203449d4 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/nested-label-for-of/input.js @@ -0,0 +1,5 @@ +b: for (let c of d()) { + for (let e of f()) { + continue b; + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/nested-label-for-of/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/nested-label-for-of/output.js new file mode 100644 index 000000000000..87e1ddec80f7 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/nested-label-for-of/output.js @@ -0,0 +1,8 @@ +b: for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(d()), _step; !(_step = _iterator()).done;) { + let c = _step.value; + + 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/assumption-skipForOfIteratorClosing/options.json b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/options.json new file mode 100644 index 000000000000..77ffac99ff48 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/options.json @@ -0,0 +1,9 @@ +{ + "plugins": [ + ["external-helpers", { "helperVersion": "7.100.0" }], + "transform-for-of" + ], + "assumptions": { + "skipForOfIteratorClosing": true + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/var/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/var/input.js new file mode 100644 index 000000000000..48e5f59b2c6b --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/var/input.js @@ -0,0 +1,3 @@ +for (var i of arr) { + +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/var/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/var/output.js new file mode 100644 index 000000000000..c9f297e237ab --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/assumption-skipForOfIteratorClosing/var/output.js @@ -0,0 +1,3 @@ +for (var _iterator = babelHelpers.createForOfIteratorHelperLoose(arr), _step; !(_step = _iterator()).done;) { + var i = _step.value; +}