Fix export bindings not updated by 'for...in' and 'for...of' (#11074)
* Correctly transpile export bindings for some for-of loops * Correctly transform non-destructured for of loops to update exported variables * Add tests * Don't replace entire for of loop * Correctly transform destructured for-of/for-in exports * Update exported variables in array pattern and more fixes * Refresh test output * Update tests and rebase on master * Refactor ForOf|ForIn visitor * Don't transform re-declared exported vars * Generate better name for loop id Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com> * Idiomatically generate UidIdentifier * Update scope after replacing loop declaration Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
5aa368cec1
commit
dadba01249
@ -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"));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
22
packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/input.mjs
vendored
Normal file
22
packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/input.mjs
vendored
Normal file
@ -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 []) {}
|
||||
}
|
||||
65
packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/output.js
vendored
Normal file
65
packages/babel-plugin-transform-modules-commonjs/test/fixtures/misc/for-of-in-export/output.js
vendored
Normal file
@ -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 []) {}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user