Define readOnlyError helper and use in check-constants plugin
This commit is contained in:
parent
7064b298d7
commit
ba441c5ce4
@ -627,6 +627,12 @@ helpers.temporalRef = defineHelper(`
|
||||
}
|
||||
`);
|
||||
|
||||
helpers.readOnlyError = defineHelper(`
|
||||
export default function _readOnlyError(name) {
|
||||
throw new Error("\\"" + name + "\\" is read-only");
|
||||
}
|
||||
`);
|
||||
|
||||
helpers.temporalUndefined = defineHelper(`
|
||||
export default {};
|
||||
`);
|
||||
|
||||
@ -1,50 +1,37 @@
|
||||
import { types as t } from "@babel/core";
|
||||
|
||||
export default function() {
|
||||
/**
|
||||
* Helper function to run a statement before an expression by replacing it with a comma expression
|
||||
* and wrapping the statement in an IIFE as the first operand.
|
||||
*/
|
||||
function statementBeforeExpression(statement, expression) {
|
||||
return t.sequenceExpression([
|
||||
t.callExpression(
|
||||
t.functionExpression(null, [], t.blockStatement([statement])),
|
||||
[],
|
||||
),
|
||||
expression,
|
||||
]);
|
||||
}
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
Scope({ scope }) {
|
||||
Scope({ scope }, state) {
|
||||
for (const name in scope.bindings) {
|
||||
const binding = scope.bindings[name];
|
||||
if (binding.kind !== "const") continue;
|
||||
|
||||
for (const violation of (binding.constantViolations: Array)) {
|
||||
const throwNode = t.throwStatement(
|
||||
t.newExpression(t.identifier("Error"), [
|
||||
t.stringLiteral(`"${name}" is read-only`),
|
||||
]),
|
||||
);
|
||||
const readOnlyError = state.addHelper("readOnlyError");
|
||||
const throwNode = t.callExpression(readOnlyError, [
|
||||
t.stringLiteral(name),
|
||||
]);
|
||||
|
||||
if (violation.isAssignmentExpression()) {
|
||||
violation
|
||||
.get("right")
|
||||
.replaceWith(
|
||||
statementBeforeExpression(
|
||||
t.sequenceExpression([
|
||||
throwNode,
|
||||
violation.get("right").node,
|
||||
),
|
||||
]),
|
||||
);
|
||||
} else if (violation.isUpdateExpression()) {
|
||||
violation.replaceWith(
|
||||
statementBeforeExpression(throwNode, violation.node),
|
||||
t.sequenceExpression([throwNode, violation.node]),
|
||||
);
|
||||
} else if (violation.isForXStatement()) {
|
||||
violation.ensureBlock();
|
||||
violation.node.body.body.unshift(throwNode);
|
||||
violation.node.body.body.unshift(
|
||||
t.expressionStatement(throwNode),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
(function () {
|
||||
var a = "foo";
|
||||
if (false) a = (function () {
|
||||
throw new Error("\"a\" is read-only");
|
||||
}(), "false");
|
||||
if (false) a = (_readOnlyError("a"), "false");
|
||||
return a;
|
||||
})();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
var a = 1,
|
||||
b = 2;
|
||||
a = (function () {
|
||||
throw new Error("\"a\" is read-only");
|
||||
}(), 3);
|
||||
a = (_readOnlyError("a"), 3);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
for (var i = 0; i < 3; i = (function () {
|
||||
throw new Error("\"i\" is read-only");
|
||||
}(), i + 1)) {
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
for (var i = 0; i < 3; i = (_readOnlyError("i"), i + 1)) {
|
||||
console.log(i);
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
var c = 17;
|
||||
var a = 0;
|
||||
|
||||
function f() {
|
||||
return (function () {
|
||||
throw new Error("\"c\" is read-only");
|
||||
}(), ++c) + --a;
|
||||
return (_readOnlyError("c"), ++c) + --a;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
var MULTIPLIER = 5;
|
||||
MULTIPLIER = (function () {
|
||||
throw new Error("\"MULTIPLIER\" is read-only");
|
||||
}(), "overwrite");
|
||||
MULTIPLIER = (_readOnlyError("MULTIPLIER"), "overwrite");
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
var MULTIPLIER = 5;
|
||||
|
||||
for (MULTIPLIER in arr) {
|
||||
throw new Error("\"MULTIPLIER\" is read-only");
|
||||
_readOnlyError("MULTIPLIER");
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
var a = "str";
|
||||
(function () {
|
||||
throw new Error("\"a\" is read-only");
|
||||
})(), --a;
|
||||
_readOnlyError("a"), --a;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
function _readOnlyError(name) { throw new Error("\"" + name + "\" is read-only"); }
|
||||
|
||||
var foo = 1;
|
||||
(function () {
|
||||
throw new Error("\"foo\" is read-only");
|
||||
})(), foo++;
|
||||
_readOnlyError("foo"), foo++;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user