Spaces:
Running
Running
File size: 5,033 Bytes
4cadbaf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validateUsage = validateUsage;
var _core = require("@babel/core");
function validateUsage(path, state, tdzEnabled) {
const dynamicTDZNames = [];
for (const name of Object.keys(path.getBindingIdentifiers())) {
const binding = path.scope.getBinding(name);
if (!binding) continue;
if (tdzEnabled) {
if (injectTDZChecks(binding, state)) dynamicTDZNames.push(name);
}
if (path.node.kind === "const") {
disallowConstantViolations(name, binding, state);
}
}
return dynamicTDZNames;
}
function disallowConstantViolations(name, binding, state) {
for (const violation of binding.constantViolations) {
const readOnlyError = state.addHelper("readOnlyError");
const throwNode = _core.types.callExpression(readOnlyError, [_core.types.stringLiteral(name)]);
if (violation.isAssignmentExpression()) {
const {
operator,
left,
right
} = violation.node;
if (operator === "=") {
const exprs = [right];
exprs.push(throwNode);
violation.replaceWith(_core.types.sequenceExpression(exprs));
} else if (["&&=", "||=", "??="].includes(operator)) {
violation.replaceWith(_core.types.logicalExpression(operator.slice(0, -1), left, _core.types.sequenceExpression([right, throwNode])));
} else {
violation.replaceWith(_core.types.sequenceExpression([_core.types.binaryExpression(operator.slice(0, -1), left, right), throwNode]));
}
} else if (violation.isUpdateExpression()) {
violation.replaceWith(_core.types.sequenceExpression([_core.types.unaryExpression("+", violation.get("argument").node), throwNode]));
} else if (violation.isForXStatement()) {
violation.ensureBlock();
violation.get("left").replaceWith(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(violation.scope.generateUidIdentifier(name))]));
violation.node.body.body.unshift(_core.types.expressionStatement(throwNode));
}
}
}
function getTDZStatus(refPath, bindingPath) {
const executionStatus = bindingPath._guessExecutionStatusRelativeTo(refPath);
if (executionStatus === "before") {
return "outside";
} else if (executionStatus === "after") {
return "inside";
} else {
return "maybe";
}
}
const skipTDZChecks = new WeakSet();
function buildTDZAssert(status, node, state) {
if (status === "maybe") {
const clone = _core.types.cloneNode(node);
skipTDZChecks.add(clone);
return _core.types.callExpression(state.addHelper("temporalRef"), [clone, _core.types.stringLiteral(node.name)]);
} else {
return _core.types.callExpression(state.addHelper("tdz"), [_core.types.stringLiteral(node.name)]);
}
}
function getTDZReplacement(path, state, id = path.node) {
var _path$scope$getBindin;
if (skipTDZChecks.has(id)) return;
skipTDZChecks.add(id);
const bindingPath = (_path$scope$getBindin = path.scope.getBinding(id.name)) == null ? void 0 : _path$scope$getBindin.path;
if (!bindingPath || bindingPath.isFunctionDeclaration()) return;
const status = getTDZStatus(path, bindingPath);
if (status === "outside") return;
if (status === "maybe") {
bindingPath.parent._tdzThis = true;
}
return {
status,
node: buildTDZAssert(status, id, state)
};
}
function injectTDZChecks(binding, state) {
const allUsages = new Set(binding.referencePaths);
binding.constantViolations.forEach(allUsages.add, allUsages);
let dynamicTdz = false;
for (const path of binding.constantViolations) {
const {
node
} = path;
if (skipTDZChecks.has(node)) continue;
skipTDZChecks.add(node);
if (path.isUpdateExpression()) {
const arg = path.get("argument");
const replacement = getTDZReplacement(path, state, arg.node);
if (!replacement) continue;
if (replacement.status === "maybe") {
dynamicTdz = true;
path.insertBefore(replacement.node);
} else {
path.replaceWith(replacement.node);
}
} else if (path.isAssignmentExpression()) {
const nodes = [];
const ids = path.getBindingIdentifiers();
for (const name of Object.keys(ids)) {
const replacement = getTDZReplacement(path, state, ids[name]);
if (replacement) {
nodes.push(_core.types.expressionStatement(replacement.node));
if (replacement.status === "inside") break;
if (replacement.status === "maybe") dynamicTdz = true;
}
}
if (nodes.length > 0) path.insertBefore(nodes);
}
}
for (const path of binding.referencePaths) {
if (path.parentPath.isUpdateExpression()) continue;
if (path.parentPath.isFor({
left: path.node
})) continue;
const replacement = getTDZReplacement(path, state);
if (!replacement) continue;
if (replacement.status === "maybe") dynamicTdz = true;
path.replaceWith(replacement.node);
}
return dynamicTdz;
}
//# sourceMappingURL=validation.js.map
|