Fix const violations in ESM imports when transformed to CJS (#13258)
This commit is contained in:
parent
47ad54a057
commit
5ac5e3572f
@ -350,31 +350,33 @@ const rewriteReferencesVisitor: Visitor<RewriteReferencesVisitorState> = {
|
||||
) {
|
||||
const { scope, node } = path;
|
||||
const { left } = node;
|
||||
const { exported, scope: programScope } = this;
|
||||
const { exported, imported, scope: programScope } = this;
|
||||
|
||||
if (!t.isVariableDeclaration(left)) {
|
||||
let didTransform = false;
|
||||
const bodyPath = path.get("body");
|
||||
const loopBodyScope = bodyPath.scope;
|
||||
let didTransformExport = false,
|
||||
importConstViolationName;
|
||||
const loopBodyScope = path.get("body").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 (programScope.getBinding(name) === scope.getBinding(name)) {
|
||||
if (exported.has(name)) {
|
||||
didTransformExport = true;
|
||||
if (loopBodyScope.hasOwnBinding(name)) {
|
||||
loopBodyScope.rename(name);
|
||||
}
|
||||
}
|
||||
if (imported.has(name) && !importConstViolationName) {
|
||||
importConstViolationName = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!didTransform) {
|
||||
if (!didTransformExport && !importConstViolationName) {
|
||||
return;
|
||||
}
|
||||
|
||||
path.ensureBlock();
|
||||
const bodyPath = path.get("body");
|
||||
|
||||
const newLoopId = scope.generateUidIdentifierBasedOnNode(left);
|
||||
bodyPath.unshiftContainer(
|
||||
"body",
|
||||
t.expressionStatement(t.assignmentExpression("=", left, newLoopId)),
|
||||
);
|
||||
path
|
||||
.get("left")
|
||||
.replaceWith(
|
||||
@ -383,6 +385,19 @@ const rewriteReferencesVisitor: Visitor<RewriteReferencesVisitorState> = {
|
||||
]),
|
||||
);
|
||||
scope.registerDeclaration(path.get("left"));
|
||||
|
||||
if (didTransformExport) {
|
||||
bodyPath.unshiftContainer(
|
||||
"body",
|
||||
t.expressionStatement(t.assignmentExpression("=", left, newLoopId)),
|
||||
);
|
||||
}
|
||||
if (importConstViolationName) {
|
||||
bodyPath.unshiftContainer(
|
||||
"body",
|
||||
t.expressionStatement(buildImportThrow(importConstViolationName)),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@ -100,12 +100,30 @@ const simpleAssignmentVisitor = {
|
||||
return;
|
||||
}
|
||||
|
||||
path.node.right = t.binaryExpression(
|
||||
path.node.operator.slice(0, -1),
|
||||
t.cloneNode(path.node.left),
|
||||
path.node.right,
|
||||
);
|
||||
path.node.operator = "=";
|
||||
const operator = path.node.operator.slice(0, -1);
|
||||
if (t.LOGICAL_OPERATORS.includes(operator)) {
|
||||
// &&, ||, ??
|
||||
// (foo &&= bar) => (foo && foo = bar)
|
||||
path.replaceWith(
|
||||
t.logicalExpression(
|
||||
operator,
|
||||
path.node.left,
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.cloneNode(path.node.left),
|
||||
path.node.right,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// (foo += bar) => (foo = foo + bar)
|
||||
path.node.right = t.binaryExpression(
|
||||
operator,
|
||||
t.cloneNode(path.node.left),
|
||||
path.node.right,
|
||||
);
|
||||
path.node.operator = "=";
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -16,7 +16,9 @@ for ([foo, [...foo]] of []) {
|
||||
let foo;
|
||||
}
|
||||
|
||||
for (foo of []) ;
|
||||
|
||||
{
|
||||
let foo;
|
||||
for(foo of []) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +58,11 @@ for (let _ref2 of []) {
|
||||
let _foo8;
|
||||
}
|
||||
|
||||
for (let _foo9 of []) {
|
||||
exports.bar = exports.foo = foo = _foo9;
|
||||
;
|
||||
}
|
||||
|
||||
{
|
||||
let foo;
|
||||
|
||||
|
||||
@ -15,3 +15,33 @@ Baz = 44;
|
||||
({prop: Foo} = {});
|
||||
({prop: Bar} = {});
|
||||
({prop: Baz} = {});
|
||||
|
||||
Foo += 2;
|
||||
Bar += 2;
|
||||
Baz += 2;
|
||||
|
||||
Foo >>>= 3;
|
||||
Bar >>>= 3;
|
||||
Baz >>>= 3;
|
||||
|
||||
Foo &&= 4;
|
||||
Bar &&= 4;
|
||||
Baz &&= 4;
|
||||
|
||||
--Foo;
|
||||
--Bar;
|
||||
--Baz;
|
||||
|
||||
Foo++;
|
||||
Bar++;
|
||||
Baz++;
|
||||
|
||||
for (Foo in {}) ;
|
||||
for (Bar in {}) {}
|
||||
for (Baz of []) {
|
||||
let Baz;
|
||||
}
|
||||
|
||||
for ({Foo} in {}) {}
|
||||
for ([Bar] in {}) {}
|
||||
for ([...Baz] in {}) {}
|
||||
|
||||
@ -47,3 +47,88 @@ _baz.Baz = (44, function () {
|
||||
} = ({}, function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
}()));
|
||||
_foo.default = (_foo.default + 2, function () {
|
||||
throw new Error('"' + "Foo" + '" is read-only.');
|
||||
}());
|
||||
Bar = (Bar + 2, function () {
|
||||
throw new Error('"' + "Bar" + '" is read-only.');
|
||||
}());
|
||||
_baz.Baz = (_baz.Baz + 2, function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
}());
|
||||
_foo.default = (_foo.default >>> 3, function () {
|
||||
throw new Error('"' + "Foo" + '" is read-only.');
|
||||
}());
|
||||
Bar = (Bar >>> 3, function () {
|
||||
throw new Error('"' + "Bar" + '" is read-only.');
|
||||
}());
|
||||
_baz.Baz = (_baz.Baz >>> 3, function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
}());
|
||||
_foo.default && (_foo.default = (4, function () {
|
||||
throw new Error('"' + "Foo" + '" is read-only.');
|
||||
}()));
|
||||
Bar && (Bar = (4, function () {
|
||||
throw new Error('"' + "Bar" + '" is read-only.');
|
||||
}()));
|
||||
_baz.Baz && (_baz.Baz = (4, function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
}()));
|
||||
_foo.default = (_foo.default - 1, function () {
|
||||
throw new Error('"' + "Foo" + '" is read-only.');
|
||||
}());
|
||||
Bar = (Bar - 1, function () {
|
||||
throw new Error('"' + "Bar" + '" is read-only.');
|
||||
}());
|
||||
_baz.Baz = (_baz.Baz - 1, function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
}());
|
||||
_foo.default = (_foo.default + 1, function () {
|
||||
throw new Error('"' + "Foo" + '" is read-only.');
|
||||
}());
|
||||
Bar = (Bar + 1, function () {
|
||||
throw new Error('"' + "Bar" + '" is read-only.');
|
||||
}());
|
||||
_baz.Baz = (_baz.Baz + 1, function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
}());
|
||||
|
||||
for (let _Foo in {}) {
|
||||
(function () {
|
||||
throw new Error('"' + "Foo" + '" is read-only.');
|
||||
})();
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
for (let _Bar in {}) {
|
||||
(function () {
|
||||
throw new Error('"' + "Bar" + '" is read-only.');
|
||||
})();
|
||||
}
|
||||
|
||||
for (let _Baz of []) {
|
||||
(function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
})();
|
||||
|
||||
let Baz;
|
||||
}
|
||||
|
||||
for (let _Foo2 in {}) {
|
||||
(function () {
|
||||
throw new Error('"' + "Foo" + '" is read-only.');
|
||||
})();
|
||||
}
|
||||
|
||||
for (let _ref in {}) {
|
||||
(function () {
|
||||
throw new Error('"' + "Bar" + '" is read-only.');
|
||||
})();
|
||||
}
|
||||
|
||||
for (let _ref2 in {}) {
|
||||
(function () {
|
||||
throw new Error('"' + "Baz" + '" is read-only.');
|
||||
})();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user