diff --git a/packages/babel-helper-module-transforms/src/rewrite-live-references.js b/packages/babel-helper-module-transforms/src/rewrite-live-references.js index 95f1daadd158..b98953f70662 100644 --- a/packages/babel-helper-module-transforms/src/rewrite-live-references.js +++ b/packages/babel-helper-module-transforms/src/rewrite-live-references.js @@ -306,4 +306,40 @@ const rewriteReferencesVisitor = { } }, }, + "ForOfStatement|ForInStatement"(path) { + const { scope, node } = path; + const { left } = node; + const { exported, scope: programScope } = this; + + if (!t.isVariableDeclaration(left)) { + let didTransform = false; + const bodyPath = path.get("body"); + const loopBodyScope = bodyPath.scope; + for (const name of Object.keys(t.getOuterBindingIdentifiers(left))) { + if ( + exported.get(name) && + programScope.getBinding(name) === scope.getBinding(name) + ) { + didTransform = true; + if (loopBodyScope.hasOwnBinding(name)) { + loopBodyScope.rename(name); + } + } + } + if (!didTransform) { + return; + } + const newLoopId = scope.generateUidIdentifierBasedOnNode(left); + bodyPath.unshiftContainer( + "body", + t.expressionStatement(t.assignmentExpression("=", left, newLoopId)), + ); + path + .get("left") + .replaceWith( + t.variableDeclaration("let", [t.variableDeclarator(newLoopId)]), + ); + scope.registerDeclaration(path.get("left")); + } + }, }; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/input.mjs new file mode 100644 index 000000000000..fe09208eea2c --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/input.mjs @@ -0,0 +1,22 @@ +export let foo; +export {foo as bar} + +for (foo of []) {} +for (foo in []) {} +for (foo of []) { + let foo; +} +for ({foo} of []) {} +for ({foo} of []) { + let foo; +} +for ({test: {foo}} of []) {} +for ([foo, [...foo]] of []) {} +for ([foo, [...foo]] of []) { + let foo; +} + +{ + let foo; + for(foo of []) {} +} \ No newline at end of file diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/output.js new file mode 100644 index 000000000000..bb8330350160 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/output.js @@ -0,0 +1,65 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.bar = exports.foo = void 0; +let foo; +exports.bar = exports.foo = foo; + +for (let _foo of []) { + exports.bar = exports.foo = foo = _foo; +} + +for (let _foo2 in []) { + exports.bar = exports.foo = foo = _foo2; +} + +for (let _foo4 of []) { + exports.bar = exports.foo = foo = _foo4; + + let _foo3; +} + +for (let _foo5 of []) { + ({ + foo + } = _foo5); + exports.bar = exports.foo = foo; +} + +for (let _foo7 of []) { + ({ + foo + } = _foo7); + exports.bar = exports.foo = foo; + + let _foo6; +} + +for (let _test of []) { + ({ + test: { + foo + } + } = _test); + exports.bar = exports.foo = foo; +} + +for (let _ref of []) { + [foo, [...foo]] = _ref; + exports.bar = exports.foo = foo; +} + +for (let _ref2 of []) { + [foo, [...foo]] = _ref2; + exports.bar = exports.foo = foo; + + let _foo8; +} + +{ + let foo; + + for (foo of []) {} +}