inferer-reference.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = _default;
  6. function t() {
  7. var data = _interopRequireWildcard(require("@babel/types"));
  8. t = function t() {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
  14. function _default(node) {
  15. if (!this.isReferenced()) return;
  16. var binding = this.scope.getBinding(node.name);
  17. if (binding) {
  18. if (binding.identifier.typeAnnotation) {
  19. return binding.identifier.typeAnnotation;
  20. } else {
  21. return getTypeAnnotationBindingConstantViolations(binding, this, node.name);
  22. }
  23. }
  24. if (node.name === "undefined") {
  25. return t().voidTypeAnnotation();
  26. } else if (node.name === "NaN" || node.name === "Infinity") {
  27. return t().numberTypeAnnotation();
  28. } else if (node.name === "arguments") {}
  29. }
  30. function getTypeAnnotationBindingConstantViolations(binding, path, name) {
  31. var types = [];
  32. var functionConstantViolations = [];
  33. var constantViolations = getConstantViolationsBefore(binding, path, functionConstantViolations);
  34. var testType = getConditionalAnnotation(binding, path, name);
  35. if (testType) {
  36. var testConstantViolations = getConstantViolationsBefore(binding, testType.ifStatement);
  37. constantViolations = constantViolations.filter(function (path) {
  38. return testConstantViolations.indexOf(path) < 0;
  39. });
  40. types.push(testType.typeAnnotation);
  41. }
  42. if (constantViolations.length) {
  43. constantViolations = constantViolations.concat(functionConstantViolations);
  44. var _arr = constantViolations;
  45. for (var _i = 0; _i < _arr.length; _i++) {
  46. var violation = _arr[_i];
  47. types.push(violation.getTypeAnnotation());
  48. }
  49. }
  50. if (types.length) {
  51. return t().createUnionTypeAnnotation(types);
  52. }
  53. }
  54. function getConstantViolationsBefore(binding, path, functions) {
  55. var violations = binding.constantViolations.slice();
  56. violations.unshift(binding.path);
  57. return violations.filter(function (violation) {
  58. violation = violation.resolve();
  59. var status = violation._guessExecutionStatusRelativeTo(path);
  60. if (functions && status === "function") functions.push(violation);
  61. return status === "before";
  62. });
  63. }
  64. function inferAnnotationFromBinaryExpression(name, path) {
  65. var operator = path.node.operator;
  66. var right = path.get("right").resolve();
  67. var left = path.get("left").resolve();
  68. var target;
  69. if (left.isIdentifier({
  70. name: name
  71. })) {
  72. target = right;
  73. } else if (right.isIdentifier({
  74. name: name
  75. })) {
  76. target = left;
  77. }
  78. if (target) {
  79. if (operator === "===") {
  80. return target.getTypeAnnotation();
  81. }
  82. if (t().BOOLEAN_NUMBER_BINARY_OPERATORS.indexOf(operator) >= 0) {
  83. return t().numberTypeAnnotation();
  84. }
  85. return;
  86. }
  87. if (operator !== "===" && operator !== "==") return;
  88. var typeofPath;
  89. var typePath;
  90. if (left.isUnaryExpression({
  91. operator: "typeof"
  92. })) {
  93. typeofPath = left;
  94. typePath = right;
  95. } else if (right.isUnaryExpression({
  96. operator: "typeof"
  97. })) {
  98. typeofPath = right;
  99. typePath = left;
  100. }
  101. if (!typeofPath) return;
  102. if (!typeofPath.get("argument").isIdentifier({
  103. name: name
  104. })) return;
  105. typePath = typePath.resolve();
  106. if (!typePath.isLiteral()) return;
  107. var typeValue = typePath.node.value;
  108. if (typeof typeValue !== "string") return;
  109. return t().createTypeAnnotationBasedOnTypeof(typeValue);
  110. }
  111. function getParentConditionalPath(binding, path, name) {
  112. var parentPath;
  113. while (parentPath = path.parentPath) {
  114. if (parentPath.isIfStatement() || parentPath.isConditionalExpression()) {
  115. if (path.key === "test") {
  116. return;
  117. }
  118. return parentPath;
  119. }
  120. if (parentPath.isFunction()) {
  121. if (parentPath.parentPath.scope.getBinding(name) !== binding) return;
  122. }
  123. path = parentPath;
  124. }
  125. }
  126. function getConditionalAnnotation(binding, path, name) {
  127. var ifStatement = getParentConditionalPath(binding, path, name);
  128. if (!ifStatement) return;
  129. var test = ifStatement.get("test");
  130. var paths = [test];
  131. var types = [];
  132. for (var i = 0; i < paths.length; i++) {
  133. var _path = paths[i];
  134. if (_path.isLogicalExpression()) {
  135. if (_path.node.operator === "&&") {
  136. paths.push(_path.get("left"));
  137. paths.push(_path.get("right"));
  138. }
  139. } else if (_path.isBinaryExpression()) {
  140. var type = inferAnnotationFromBinaryExpression(name, _path);
  141. if (type) types.push(type);
  142. }
  143. }
  144. if (types.length) {
  145. return {
  146. typeAnnotation: t().createUnionTypeAnnotation(types),
  147. ifStatement: ifStatement
  148. };
  149. }
  150. return getConditionalAnnotation(ifStatement, name);
  151. }