You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					137 lines
				
				4.9 KiB
			
		
		
			
		
	
	
					137 lines
				
				4.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"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
							 |