| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 | "use strict";Object.defineProperty(exports, "__esModule", {  value: true});exports.default = _default;var _t = require("@babel/types");const {  BOOLEAN_NUMBER_BINARY_OPERATORS,  createFlowUnionType,  createTSUnionType,  createTypeAnnotationBasedOnTypeof,  createUnionTypeAnnotation,  isTSTypeAnnotation,  numberTypeAnnotation,  voidTypeAnnotation} = _t;function _default(node) {  if (!this.isReferenced()) return;  const binding = this.scope.getBinding(node.name);  if (binding) {    if (binding.identifier.typeAnnotation) {      return binding.identifier.typeAnnotation;    } else {      return getTypeAnnotationBindingConstantViolations(binding, this, node.name);    }  }  if (node.name === "undefined") {    return voidTypeAnnotation();  } else if (node.name === "NaN" || node.name === "Infinity") {    return numberTypeAnnotation();  } else if (node.name === "arguments") {}}function getTypeAnnotationBindingConstantViolations(binding, path, name) {  const types = [];  const functionConstantViolations = [];  let constantViolations = getConstantViolationsBefore(binding, path, functionConstantViolations);  const testType = getConditionalAnnotation(binding, path, name);  if (testType) {    const testConstantViolations = getConstantViolationsBefore(binding, testType.ifStatement);    constantViolations = constantViolations.filter(path => testConstantViolations.indexOf(path) < 0);    types.push(testType.typeAnnotation);  }  if (constantViolations.length) {    constantViolations.push(...functionConstantViolations);    for (const violation of constantViolations) {      types.push(violation.getTypeAnnotation());    }  }  if (!types.length) {    return;  }  if (isTSTypeAnnotation(types[0]) && createTSUnionType) {    return createTSUnionType(types);  }  if (createFlowUnionType) {    return createFlowUnionType(types);  }  return createUnionTypeAnnotation(types);}function getConstantViolationsBefore(binding, path, functions) {  const violations = binding.constantViolations.slice();  violations.unshift(binding.path);  return violations.filter(violation => {    violation = violation.resolve();    const status = violation._guessExecutionStatusRelativeTo(path);    if (functions && status === "unknown") functions.push(violation);    return status === "before";  });}function inferAnnotationFromBinaryExpression(name, path) {  const operator = path.node.operator;  const right = path.get("right").resolve();  const left = path.get("left").resolve();  let target;  if (left.isIdentifier({    name  })) {    target = right;  } else if (right.isIdentifier({    name  })) {    target = left;  }  if (target) {    if (operator === "===") {      return target.getTypeAnnotation();    }    if (BOOLEAN_NUMBER_BINARY_OPERATORS.indexOf(operator) >= 0) {      return numberTypeAnnotation();    }    return;  }  if (operator !== "===" && operator !== "==") return;  let typeofPath;  let typePath;  if (left.isUnaryExpression({    operator: "typeof"  })) {    typeofPath = left;    typePath = right;  } else if (right.isUnaryExpression({    operator: "typeof"  })) {    typeofPath = right;    typePath = left;  }  if (!typeofPath) return;  if (!typeofPath.get("argument").isIdentifier({    name  })) return;  typePath = typePath.resolve();  if (!typePath.isLiteral()) return;  const typeValue = typePath.node.value;  if (typeof typeValue !== "string") return;  return createTypeAnnotationBasedOnTypeof(typeValue);}function getParentConditionalPath(binding, path, name) {  let parentPath;  while (parentPath = path.parentPath) {    if (parentPath.isIfStatement() || parentPath.isConditionalExpression()) {      if (path.key === "test") {        return;      }      return parentPath;    }    if (parentPath.isFunction()) {      if (parentPath.parentPath.scope.getBinding(name) !== binding) return;    }    path = parentPath;  }}function getConditionalAnnotation(binding, path, name) {  const ifStatement = getParentConditionalPath(binding, path, name);  if (!ifStatement) return;  const test = ifStatement.get("test");  const paths = [test];  const types = [];  for (let i = 0; i < paths.length; i++) {    const path = paths[i];    if (path.isLogicalExpression()) {      if (path.node.operator === "&&") {        paths.push(path.get("left"));        paths.push(path.get("right"));      }    } else if (path.isBinaryExpression()) {      const type = inferAnnotationFromBinaryExpression(name, path);      if (type) types.push(type);    }  }  if (types.length) {    if (isTSTypeAnnotation(types[0]) && createTSUnionType) {      return {        typeAnnotation: createTSUnionType(types),        ifStatement      };    }    if (createFlowUnionType) {      return {        typeAnnotation: createFlowUnionType(types),        ifStatement      };    }    return {      typeAnnotation: createUnionTypeAnnotation(types),      ifStatement    };  }  return getConditionalAnnotation(ifStatement, name);}
 |