diff options
Diffstat (limited to 'node_modules/@babel/plugin-transform-block-scoping/lib/validation.js')
| -rw-r--r-- | node_modules/@babel/plugin-transform-block-scoping/lib/validation.js | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/node_modules/@babel/plugin-transform-block-scoping/lib/validation.js b/node_modules/@babel/plugin-transform-block-scoping/lib/validation.js new file mode 100644 index 00000000..3985a42b --- /dev/null +++ b/node_modules/@babel/plugin-transform-block-scoping/lib/validation.js @@ -0,0 +1,133 @@ +"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 |
