added to remote repo
This commit is contained in:
1 parent
8697c9f405
commit
cc599b6e18
8049 files changed
+1096323
No files matched your search
+149
@@ -0,0 +1,149 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports._getTypeAnnotation = _getTypeAnnotation;
|
||||
exports.baseTypeStrictlyMatches = baseTypeStrictlyMatches;
|
||||
exports.couldBeBaseType = couldBeBaseType;
|
||||
exports.getTypeAnnotation = getTypeAnnotation;
|
||||
exports.isBaseType = isBaseType;
|
||||
exports.isGenericType = isGenericType;
|
||||
var inferers = require("./inferers.js");
|
||||
var _t = require("@babel/types");
|
||||
const {
|
||||
anyTypeAnnotation,
|
||||
isAnyTypeAnnotation,
|
||||
isArrayTypeAnnotation,
|
||||
isBooleanTypeAnnotation,
|
||||
isEmptyTypeAnnotation,
|
||||
isFlowBaseAnnotation,
|
||||
isGenericTypeAnnotation,
|
||||
isIdentifier,
|
||||
isMixedTypeAnnotation,
|
||||
isNumberTypeAnnotation,
|
||||
isStringTypeAnnotation,
|
||||
isTSArrayType,
|
||||
isTSTypeAnnotation,
|
||||
isTSTypeReference,
|
||||
isTupleTypeAnnotation,
|
||||
isTypeAnnotation,
|
||||
isUnionTypeAnnotation,
|
||||
isVoidTypeAnnotation,
|
||||
stringTypeAnnotation,
|
||||
voidTypeAnnotation
|
||||
} = _t;
|
||||
function getTypeAnnotation() {
|
||||
let type = this.getData("typeAnnotation");
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
type = _getTypeAnnotation.call(this) || anyTypeAnnotation();
|
||||
if (isTypeAnnotation(type) || isTSTypeAnnotation(type)) {
|
||||
type = type.typeAnnotation;
|
||||
}
|
||||
this.setData("typeAnnotation", type);
|
||||
return type;
|
||||
}
|
||||
const typeAnnotationInferringNodes = new WeakSet();
|
||||
function _getTypeAnnotation() {
|
||||
const node = this.node;
|
||||
if (!node) {
|
||||
if (this.key === "init" && this.parentPath.isVariableDeclarator()) {
|
||||
const declar = this.parentPath.parentPath;
|
||||
const declarParent = declar.parentPath;
|
||||
if (declar.key === "left" && declarParent.isForInStatement()) {
|
||||
return stringTypeAnnotation();
|
||||
}
|
||||
if (declar.key === "left" && declarParent.isForOfStatement()) {
|
||||
return anyTypeAnnotation();
|
||||
}
|
||||
return voidTypeAnnotation();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (node.typeAnnotation) {
|
||||
return node.typeAnnotation;
|
||||
}
|
||||
if (typeAnnotationInferringNodes.has(node)) {
|
||||
return;
|
||||
}
|
||||
typeAnnotationInferringNodes.add(node);
|
||||
try {
|
||||
var _inferer;
|
||||
let inferer = inferers[node.type];
|
||||
if (inferer) {
|
||||
return inferer.call(this, node);
|
||||
}
|
||||
inferer = inferers[this.parentPath.type];
|
||||
if ((_inferer = inferer) != null && _inferer.validParent) {
|
||||
return this.parentPath.getTypeAnnotation();
|
||||
}
|
||||
} finally {
|
||||
typeAnnotationInferringNodes.delete(node);
|
||||
}
|
||||
}
|
||||
function isBaseType(baseName, soft) {
|
||||
return _isBaseType(baseName, this.getTypeAnnotation(), soft);
|
||||
}
|
||||
function _isBaseType(baseName, type, soft) {
|
||||
if (baseName === "string") {
|
||||
return isStringTypeAnnotation(type);
|
||||
} else if (baseName === "number") {
|
||||
return isNumberTypeAnnotation(type);
|
||||
} else if (baseName === "boolean") {
|
||||
return isBooleanTypeAnnotation(type);
|
||||
} else if (baseName === "any") {
|
||||
return isAnyTypeAnnotation(type);
|
||||
} else if (baseName === "mixed") {
|
||||
return isMixedTypeAnnotation(type);
|
||||
} else if (baseName === "empty") {
|
||||
return isEmptyTypeAnnotation(type);
|
||||
} else if (baseName === "void") {
|
||||
return isVoidTypeAnnotation(type);
|
||||
} else {
|
||||
if (soft) {
|
||||
return false;
|
||||
} else {
|
||||
throw new Error(`Unknown base type ${baseName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
function couldBeBaseType(name) {
|
||||
const type = this.getTypeAnnotation();
|
||||
if (isAnyTypeAnnotation(type)) return true;
|
||||
if (isUnionTypeAnnotation(type)) {
|
||||
for (const type2 of type.types) {
|
||||
if (isAnyTypeAnnotation(type2) || _isBaseType(name, type2, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return _isBaseType(name, type, true);
|
||||
}
|
||||
}
|
||||
function baseTypeStrictlyMatches(rightArg) {
|
||||
const left = this.getTypeAnnotation();
|
||||
const right = rightArg.getTypeAnnotation();
|
||||
if (!isAnyTypeAnnotation(left) && isFlowBaseAnnotation(left)) {
|
||||
return right.type === left.type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isGenericType(genericName) {
|
||||
const type = this.getTypeAnnotation();
|
||||
if (genericName === "Array") {
|
||||
if (isTSArrayType(type) || isArrayTypeAnnotation(type) || isTupleTypeAnnotation(type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isGenericTypeAnnotation(type) && isIdentifier(type.id, {
|
||||
name: genericName
|
||||
}) || isTSTypeReference(type) && isIdentifier(type.typeName, {
|
||||
name: genericName
|
||||
});
|
||||
}
|
||||
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"names":["inferers","require","_t","anyTypeAnnotation","isAnyTypeAnnotation","isArrayTypeAnnotation","isBooleanTypeAnnotation","isEmptyTypeAnnotation","isFlowBaseAnnotation","isGenericTypeAnnotation","isIdentifier","isMixedTypeAnnotation","isNumberTypeAnnotation","isStringTypeAnnotation","isTSArrayType","isTSTypeAnnotation","isTSTypeReference","isTupleTypeAnnotation","isTypeAnnotation","isUnionTypeAnnotation","isVoidTypeAnnotation","stringTypeAnnotation","voidTypeAnnotation","getTypeAnnotation","type","getData","_getTypeAnnotation","call","typeAnnotation","setData","typeAnnotationInferringNodes","WeakSet","node","key","parentPath","isVariableDeclarator","declar","declarParent","isForInStatement","isForOfStatement","has","add","_inferer","inferer","validParent","delete","isBaseType","baseName","soft","_isBaseType","Error","couldBeBaseType","name","type2","types","baseTypeStrictlyMatches","rightArg","left","right","isGenericType","genericName","id","typeName"],"sources":["../../../src/path/inference/index.ts"],"sourcesContent":["import type NodePath from \"../index.ts\";\nimport * as inferers from \"./inferers.ts\";\nimport {\n anyTypeAnnotation,\n isAnyTypeAnnotation,\n isArrayTypeAnnotation,\n isBooleanTypeAnnotation,\n isEmptyTypeAnnotation,\n isFlowBaseAnnotation,\n isGenericTypeAnnotation,\n isIdentifier,\n isMixedTypeAnnotation,\n isNumberTypeAnnotation,\n isStringTypeAnnotation,\n isTSArrayType,\n isTSTypeAnnotation,\n isTSTypeReference,\n isTupleTypeAnnotation,\n isTypeAnnotation,\n isUnionTypeAnnotation,\n isVoidTypeAnnotation,\n stringTypeAnnotation,\n voidTypeAnnotation,\n} from \"@babel/types\";\nimport type * as t from \"@babel/types\";\n\n/**\n * Infer the type of the current `NodePath`.\n */\n\nexport function getTypeAnnotation(\n this: NodePath<t.Node | null>,\n): t.FlowType | t.TSType {\n let type = this.getData(\"typeAnnotation\");\n if (type != null) {\n return type;\n }\n type = _getTypeAnnotation.call(this) || anyTypeAnnotation();\n if (isTypeAnnotation(type) || isTSTypeAnnotation(type)) {\n type = type.typeAnnotation;\n }\n this.setData(\"typeAnnotation\", type);\n return type;\n}\n\n// Used to avoid infinite recursion in cases like\n// var b, c; if (0) { c = 1; b = c; } c = b;\n// It also works with indirect recursion.\nconst typeAnnotationInferringNodes = new WeakSet();\n\n/**\n * todo: split up this method\n */\n\nexport function _getTypeAnnotation(this: NodePath): any {\n const node = this.node;\n\n if (!node) {\n // handle initializerless variables, add in checks for loop initializers too\n if (this.key === \"init\" && this.parentPath.isVariableDeclarator()) {\n const declar = this.parentPath.parentPath;\n const declarParent = declar.parentPath;\n\n // for (let NODE in bar) {}\n if (declar.key === \"left\" && declarParent.isForInStatement()) {\n return stringTypeAnnotation();\n }\n\n // for (let NODE of bar) {}\n if (declar.key === \"left\" && declarParent.isForOfStatement()) {\n return anyTypeAnnotation();\n }\n\n return voidTypeAnnotation();\n } else {\n return;\n }\n }\n\n // @ts-expect-error typeAnnotation may not index node\n if (node.typeAnnotation) {\n // @ts-expect-error typeAnnotation may not index node\n return node.typeAnnotation;\n }\n\n if (typeAnnotationInferringNodes.has(node)) {\n // Bail out from type inference to avoid infinite loops\n return;\n }\n typeAnnotationInferringNodes.add(node);\n\n try {\n let inferer =\n // @ts-expect-error inferers do not cover all AST types\n inferers[node.type];\n if (inferer) {\n return inferer.call(this, node);\n }\n\n // @ts-expect-error inferers do not cover all AST types\n inferer = inferers[this.parentPath.type];\n if (inferer?.validParent) {\n return this.parentPath.getTypeAnnotation();\n }\n } finally {\n typeAnnotationInferringNodes.delete(node);\n }\n}\n\nexport function isBaseType(\n this: NodePath,\n baseName: string,\n soft?: boolean,\n): boolean {\n return _isBaseType(baseName, this.getTypeAnnotation(), soft);\n}\n\nfunction _isBaseType(\n baseName: string,\n type?: t.FlowType | t.TSType,\n soft?: boolean,\n): boolean {\n if (baseName === \"string\") {\n return isStringTypeAnnotation(type);\n } else if (baseName === \"number\") {\n return isNumberTypeAnnotation(type);\n } else if (baseName === \"boolean\") {\n return isBooleanTypeAnnotation(type);\n } else if (baseName === \"any\") {\n return isAnyTypeAnnotation(type);\n } else if (baseName === \"mixed\") {\n return isMixedTypeAnnotation(type);\n } else if (baseName === \"empty\") {\n return isEmptyTypeAnnotation(type);\n } else if (baseName === \"void\") {\n return isVoidTypeAnnotation(type);\n } else {\n if (soft) {\n return false;\n } else {\n throw new Error(`Unknown base type ${baseName}`);\n }\n }\n}\n\nexport functioLine truncated
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = _default;
|
||||
var _t = require("@babel/types");
|
||||
var _util = require("./util.js");
|
||||
const {
|
||||
BOOLEAN_NUMBER_BINARY_OPERATORS,
|
||||
createTypeAnnotationBasedOnTypeof,
|
||||
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.includes(path));
|
||||
types.push(testType.typeAnnotation);
|
||||
}
|
||||
if (constantViolations.length) {
|
||||
constantViolations.push(...functionConstantViolations);
|
||||
for (const violation of constantViolations) {
|
||||
types.push(violation.getTypeAnnotation());
|
||||
}
|
||||
}
|
||||
if (!types.length) {
|
||||
return;
|
||||
}
|
||||
return (0, _util.createUnionType)(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.includes(operator)) {
|
||||
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 (name == null || 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) {
|
||||
return {
|
||||
typeAnnotation: (0, _util.createUnionType)(types),
|
||||
ifStatement
|
||||
};
|
||||
}
|
||||
return getConditionalAnnotation(binding, ifStatement, name);
|
||||
}
|
||||
|
||||
//# sourceMappingURL=inferer-reference.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"names":["_t","require","_util","BOOLEAN_NUMBER_BINARY_OPERATORS","createTypeAnnotationBasedOnTypeof","numberTypeAnnotation","voidTypeAnnotation","_default","node","isReferenced","binding","scope","getBinding","name","identifier","typeAnnotation","getTypeAnnotationBindingConstantViolations","path","types","functionConstantViolations","constantViolations","getConstantViolationsBefore","testType","getConditionalAnnotation","testConstantViolations","ifStatement","filter","includes","push","length","violation","getTypeAnnotation","createUnionType","functions","violations","slice","unshift","resolve","status","_guessExecutionStatusRelativeTo","inferAnnotationFromBinaryExpression","operator","right","get","left","target","isIdentifier","typeofPath","typePath","isUnaryExpression","isLiteral","typeValue","value","getParentConditionalPath","parentPath","isIfStatement","isConditionalExpression","key","isFunction","test","paths","i","isLogicalExpression","isBinaryExpression","type"],"sources":["../../../src/path/inference/inferer-reference.ts"],"sourcesContent":["import type NodePath from \"../index.ts\";\nimport {\n BOOLEAN_NUMBER_BINARY_OPERATORS,\n createTypeAnnotationBasedOnTypeof,\n numberTypeAnnotation,\n voidTypeAnnotation,\n} from \"@babel/types\";\nimport type * as t from \"@babel/types\";\nimport type Binding from \"../../scope/binding.ts\";\n\nimport { createUnionType } from \"./util.ts\";\n\nexport default function (this: NodePath<t.Identifier>, node: t.Identifier) {\n if (!this.isReferenced()) return;\n\n // check if a binding exists of this value and if so then return a union type of all\n // possible types that the binding could be\n const binding = this.scope.getBinding(node.name);\n if (binding) {\n if (binding.identifier.typeAnnotation) {\n return binding.identifier.typeAnnotation;\n } else {\n return getTypeAnnotationBindingConstantViolations(\n binding,\n this,\n node.name,\n );\n }\n }\n\n // built-in values\n if (node.name === \"undefined\") {\n return voidTypeAnnotation();\n } else if (node.name === \"NaN\" || node.name === \"Infinity\") {\n return numberTypeAnnotation();\n } else if (node.name === \"arguments\") {\n // todo\n }\n}\n\nfunction getTypeAnnotationBindingConstantViolations(\n binding: Binding,\n path: NodePath<t.Identifier>,\n name: string,\n) {\n const types = [];\n\n const functionConstantViolations: NodePath[] = [];\n let constantViolations = getConstantViolationsBefore(\n binding,\n path,\n functionConstantViolations,\n );\n\n const testType = getConditionalAnnotation(binding, path, name);\n if (testType) {\n const testConstantViolations = getConstantViolationsBefore(\n binding,\n testType.ifStatement,\n );\n\n // remove constant violations observed before the IfStatement\n constantViolations = constantViolations.filter(\n path => !testConstantViolations.includes(path),\n );\n\n // clear current types and add in observed test type\n types.push(testType.typeAnnotation);\n }\n\n if (constantViolations.length) {\n // pick one constant from each scope which will represent the last possible\n // control flow path that it could've taken/been\n /* This code is broken for the following problems:\n * It thinks that assignments can only happen in scopes.\n * What about conditionals, if statements without block,\n * or guarded assignments.\n * It also checks to see if one of the assignments is in the\n * same scope and uses that as the only \"violation\". However,\n * the binding is returned by `getConstantViolationsBefore` so we for\n * sure always going to return that as the only \"violation\".\n let rawConstantViolations = constantViolations.reverse();\n let visitedScopes = [];\n constantViolations = [];\n for (let violation of (rawConstantViolations: Array<NodePath>)) {\n let violationScope = violation.scope;\n if (visitedScopes.indexOf(violationScope) >= 0) continue;\n\n visitedScopes.push(violationScope);\n constantViolations.push(violation);\n\n if (violationScope === path.scope) {\n constantViolations = [violation];\n break;\n }\n }*/\n\n // add back on function constant violations since we can't track calls\n constantViolations.push(...functionConstantViolations);\n\n // push on inferred types of violated paths\n for (const violation of constantViolations) {\n types.push(violation.getTypeAnnotation());\n }\n }\n\n if (!types.length) {\n return;\n }\n\n return createUnionType(types);\n}\n\nfunction getConstantViolationsBefore(\n binding: Binding,\n path: NodePath,\n functions?: NodePath[],\n) {\n const violations = binding.constantViolations.slice();\n violations.unshift(binding.path);\n return violations.filter(violation => {\n violation = violation.resolve();\n const status = violation._guessExecutionStatusRelaLine truncated
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.ArrayExpression = ArrayExpression;
|
||||
exports.AssignmentExpression = AssignmentExpression;
|
||||
exports.BinaryExpression = BinaryExpression;
|
||||
exports.BooleanLiteral = BooleanLiteral;
|
||||
exports.CallExpression = CallExpression;
|
||||
exports.ConditionalExpression = ConditionalExpression;
|
||||
exports.ClassDeclaration = exports.ClassExpression = exports.FunctionDeclaration = exports.ArrowFunctionExpression = exports.FunctionExpression = Func;
|
||||
Object.defineProperty(exports, "Identifier", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _infererReference.default;
|
||||
}
|
||||
});
|
||||
exports.LogicalExpression = LogicalExpression;
|
||||
exports.NewExpression = NewExpression;
|
||||
exports.NullLiteral = NullLiteral;
|
||||
exports.NumericLiteral = NumericLiteral;
|
||||
exports.ObjectExpression = ObjectExpression;
|
||||
exports.ParenthesizedExpression = ParenthesizedExpression;
|
||||
exports.RegExpLiteral = RegExpLiteral;
|
||||
exports.RestElement = RestElement;
|
||||
exports.SequenceExpression = SequenceExpression;
|
||||
exports.StringLiteral = StringLiteral;
|
||||
exports.TSAsExpression = TSAsExpression;
|
||||
exports.TSNonNullExpression = TSNonNullExpression;
|
||||
exports.TaggedTemplateExpression = TaggedTemplateExpression;
|
||||
exports.TemplateLiteral = TemplateLiteral;
|
||||
exports.TypeCastExpression = TypeCastExpression;
|
||||
exports.UnaryExpression = UnaryExpression;
|
||||
exports.UpdateExpression = UpdateExpression;
|
||||
exports.VariableDeclarator = VariableDeclarator;
|
||||
var _t = require("@babel/types");
|
||||
var _infererReference = require("./inferer-reference.js");
|
||||
var _util = require("./util.js");
|
||||
const {
|
||||
BOOLEAN_BINARY_OPERATORS,
|
||||
BOOLEAN_UNARY_OPERATORS,
|
||||
NUMBER_BINARY_OPERATORS,
|
||||
NUMBER_UNARY_OPERATORS,
|
||||
STRING_UNARY_OPERATORS,
|
||||
anyTypeAnnotation,
|
||||
arrayTypeAnnotation,
|
||||
booleanTypeAnnotation,
|
||||
buildMatchMemberExpression,
|
||||
genericTypeAnnotation,
|
||||
identifier,
|
||||
nullLiteralTypeAnnotation,
|
||||
numberTypeAnnotation,
|
||||
stringTypeAnnotation,
|
||||
tupleTypeAnnotation,
|
||||
unionTypeAnnotation,
|
||||
voidTypeAnnotation,
|
||||
isIdentifier
|
||||
} = _t;
|
||||
function VariableDeclarator() {
|
||||
if (!this.get("id").isIdentifier()) return;
|
||||
return this.get("init").getTypeAnnotation();
|
||||
}
|
||||
function TypeCastExpression(node) {
|
||||
return node.typeAnnotation;
|
||||
}
|
||||
TypeCastExpression.validParent = true;
|
||||
function TSAsExpression(node) {
|
||||
return node.typeAnnotation;
|
||||
}
|
||||
TSAsExpression.validParent = true;
|
||||
function TSNonNullExpression() {
|
||||
return this.get("expression").getTypeAnnotation();
|
||||
}
|
||||
function NewExpression(node) {
|
||||
if (node.callee.type === "Identifier") {
|
||||
return genericTypeAnnotation(node.callee);
|
||||
}
|
||||
}
|
||||
function TemplateLiteral() {
|
||||
return stringTypeAnnotation();
|
||||
}
|
||||
function UnaryExpression(node) {
|
||||
const operator = node.operator;
|
||||
if (operator === "void") {
|
||||
return voidTypeAnnotation();
|
||||
} else if (NUMBER_UNARY_OPERATORS.includes(operator)) {
|
||||
return numberTypeAnnotation();
|
||||
} else if (STRING_UNARY_OPERATORS.includes(operator)) {
|
||||
return stringTypeAnnotation();
|
||||
} else if (BOOLEAN_UNARY_OPERATORS.includes(operator)) {
|
||||
return booleanTypeAnnotation();
|
||||
}
|
||||
}
|
||||
function BinaryExpression(node) {
|
||||
const operator = node.operator;
|
||||
if (NUMBER_BINARY_OPERATORS.includes(operator)) {
|
||||
return numberTypeAnnotation();
|
||||
} else if (BOOLEAN_BINARY_OPERATORS.includes(operator)) {
|
||||
return booleanTypeAnnotation();
|
||||
} else if (operator === "+") {
|
||||
const right = this.get("right");
|
||||
const left = this.get("left");
|
||||
if (left.isBaseType("number") && right.isBaseType("number")) {
|
||||
return numberTypeAnnotation();
|
||||
} else if (left.isBaseType("string") || right.isBaseType("string")) {
|
||||
return stringTypeAnnotation();
|
||||
}
|
||||
return unionTypeAnnotation([stringTypeAnnotation(), numberTypeAnnotation()]);
|
||||
}
|
||||
}
|
||||
function LogicalExpression() {
|
||||
const argumentTypes = [this.get("left").getTypeAnnotation(), this.get("right").getTypeAnnotation()];
|
||||
return (0, _util.createUnionType)(argumentTypes);
|
||||
}
|
||||
function ConditionalExpression() {
|
||||
const argumentTypes = [this.get("consequent").getTypeAnnotation(), this.get("alternate").getTypeAnnotation()];
|
||||
return (0, _util.createUnionType)(argumentTypes);
|
||||
}
|
||||
function SequenceExpression() {
|
||||
return this.get("expressions").pop().getTypeAnnotation();
|
||||
}
|
||||
function ParenthesizedExpression() {
|
||||
return this.get("expression").getTypeAnnotation();
|
||||
}
|
||||
function AssignmentExpression() {
|
||||
return this.get("right").getTypeAnnotation();
|
||||
}
|
||||
function UpdateExpression(node) {
|
||||
const operator = node.operator;
|
||||
if (operator === "++" || operator === "--") {
|
||||
return numberTypeAnnotation();
|
||||
}
|
||||
}
|
||||
function StringLiteral() {
|
||||
return stringTypeAnnotation();
|
||||
}
|
||||
function NumericLiteral() {
|
||||
return numberTypeAnnotation();
|
||||
}
|
||||
function BooleanLiteral() {
|
||||
return booleanTypeAnnotation();
|
||||
}
|
||||
function NullLiteral() {
|
||||
return nullLiteralTypeAnnotation();
|
||||
}
|
||||
function RegExpLiteral() {
|
||||
return genericTypeAnnotation(identifier("RegExp"));
|
||||
}
|
||||
function ObjectExpression() {
|
||||
return genericTypeAnnotation(identifier("Object"));
|
||||
}
|
||||
function ArrayExpression() {
|
||||
return genericTypeAnnotation(identifier("Array"));
|
||||
}
|
||||
function RestElement() {
|
||||
return ArrayExpression();
|
||||
}
|
||||
RestElement.validParent = true;
|
||||
function Func() {
|
||||
return genericTypeAnnotation(identifier("Function"));
|
||||
}
|
||||
const isArrayFrom = buildMatchMemberExpression("Array.from");
|
||||
const isObjectKeys = buildMatchMemberExpression("Object.keys");
|
||||
const isObjectValues = buildMatchMemberExpression("Object.values");
|
||||
const isObjectEntries = buildMatchMemberExpression("Object.entries");
|
||||
function CallExpression() {
|
||||
const {
|
||||
callee
|
||||
} = this.node;
|
||||
if (isObjectKeys(callee)) {
|
||||
return arrayTypeAnnotation(stringTypeAnnotation());
|
||||
} else if (isArrayFrom(callee) || isObjectValues(callee) || isIdentifier(callee, {
|
||||
name: "Array"
|
||||
})) {
|
||||
return arrayTypeAnnotation(anyTypeAnnotation());
|
||||
} else if (isObjectEntries(callee)) {
|
||||
return arrayTypeAnnotation(tupleTypeAnnotation([stringTypeAnnotation(), anyTypeAnnotation()]));
|
||||
}
|
||||
return resolveCall(this.get("callee"));
|
||||
}
|
||||
function TaggedTemplateExpression() {
|
||||
return resolveCall(this.get("tag"));
|
||||
}
|
||||
function resolveCall(callee) {
|
||||
callee = callee.resolve();
|
||||
if (callee.isFunction()) {
|
||||
const {
|
||||
node
|
||||
} = callee;
|
||||
if (node.async) {
|
||||
if (node.generator) {
|
||||
return genericTypeAnnotation(identifier("AsyncIterator"));
|
||||
} else {
|
||||
return genericTypeAnnotation(identifier("Promise"));
|
||||
}
|
||||
} else {
|
||||
if (node.generator) {
|
||||
return genericTypeAnnotation(identifier("Iterator"));
|
||||
} else if (callee.node.returnType) {
|
||||
return callee.node.returnType;
|
||||
} else {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//# sourceMappingURL=inferers.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"names":["_t","require","_infererReference","_util","BOOLEAN_BINARY_OPERATORS","BOOLEAN_UNARY_OPERATORS","NUMBER_BINARY_OPERATORS","NUMBER_UNARY_OPERATORS","STRING_UNARY_OPERATORS","anyTypeAnnotation","arrayTypeAnnotation","booleanTypeAnnotation","buildMatchMemberExpression","genericTypeAnnotation","identifier","nullLiteralTypeAnnotation","numberTypeAnnotation","stringTypeAnnotation","tupleTypeAnnotation","unionTypeAnnotation","voidTypeAnnotation","isIdentifier","VariableDeclarator","get","getTypeAnnotation","TypeCastExpression","node","typeAnnotation","validParent","TSAsExpression","TSNonNullExpression","NewExpression","callee","type","TemplateLiteral","UnaryExpression","operator","includes","BinaryExpression","right","left","isBaseType","LogicalExpression","argumentTypes","createUnionType","ConditionalExpression","SequenceExpression","pop","ParenthesizedExpression","AssignmentExpression","UpdateExpression","StringLiteral","NumericLiteral","BooleanLiteral","NullLiteral","RegExpLiteral","ObjectExpression","ArrayExpression","RestElement","Func","isArrayFrom","isObjectKeys","isObjectValues","isObjectEntries","CallExpression","name","resolveCall","TaggedTemplateExpression","resolve","isFunction","async","generator","returnType"],"sources":["../../../src/path/inference/inferers.ts"],"sourcesContent":["import {\n BOOLEAN_BINARY_OPERATORS,\n BOOLEAN_UNARY_OPERATORS,\n NUMBER_BINARY_OPERATORS,\n NUMBER_UNARY_OPERATORS,\n STRING_UNARY_OPERATORS,\n anyTypeAnnotation,\n arrayTypeAnnotation,\n booleanTypeAnnotation,\n buildMatchMemberExpression,\n genericTypeAnnotation,\n identifier,\n nullLiteralTypeAnnotation,\n numberTypeAnnotation,\n stringTypeAnnotation,\n tupleTypeAnnotation,\n unionTypeAnnotation,\n voidTypeAnnotation,\n isIdentifier,\n} from \"@babel/types\";\nimport type * as t from \"@babel/types\";\n\nexport { default as Identifier } from \"./inferer-reference.ts\";\n\nimport { createUnionType } from \"./util.ts\";\nimport type NodePath from \"../index.ts\";\n\nexport function VariableDeclarator(this: NodePath<t.VariableDeclarator>) {\n if (!this.get(\"id\").isIdentifier()) return;\n return this.get(\"init\").getTypeAnnotation();\n}\n\nexport function TypeCastExpression(node: t.TypeCastExpression) {\n return node.typeAnnotation;\n}\n\nTypeCastExpression.validParent = true;\n\nexport function TSAsExpression(node: t.TSAsExpression) {\n return node.typeAnnotation;\n}\n\nTSAsExpression.validParent = true;\n\nexport function TSNonNullExpression(this: NodePath<t.TSNonNullExpression>) {\n return this.get(\"expression\").getTypeAnnotation();\n}\n\nexport function NewExpression(\n this: NodePath<t.NewExpression>,\n node: t.NewExpression,\n) {\n if (node.callee.type === \"Identifier\") {\n // only resolve identifier callee\n return genericTypeAnnotation(node.callee);\n }\n}\n\nexport function TemplateLiteral() {\n return stringTypeAnnotation();\n}\n\nexport function UnaryExpression(node: t.UnaryExpression) {\n const operator = node.operator;\n\n if (operator === \"void\") {\n return voidTypeAnnotation();\n } else if (NUMBER_UNARY_OPERATORS.includes(operator)) {\n return numberTypeAnnotation();\n } else if (STRING_UNARY_OPERATORS.includes(operator)) {\n return stringTypeAnnotation();\n } else if (BOOLEAN_UNARY_OPERATORS.includes(operator)) {\n return booleanTypeAnnotation();\n }\n}\n\nexport function BinaryExpression(\n this: NodePath<t.BinaryExpression>,\n node: t.BinaryExpression,\n) {\n const operator = node.operator;\n\n if (NUMBER_BINARY_OPERATORS.includes(operator)) {\n return numberTypeAnnotation();\n } else if (BOOLEAN_BINARY_OPERATORS.includes(operator)) {\n return booleanTypeAnnotation();\n } else if (operator === \"+\") {\n const right = this.get(\"right\");\n const left = this.get(\"left\");\n\n if (left.isBaseType(\"number\") && right.isBaseType(\"number\")) {\n // both numbers so this will be a number\n return numberTypeAnnotation();\n } else if (left.isBaseType(\"string\") || right.isBaseType(\"string\")) {\n // one is a string so the result will be a string\n return stringTypeAnnotation();\n }\n\n // unsure if left and right are strings or numbers so stay on the safe side\n return unionTypeAnnotation([\n stringTypeAnnotation(),\n numberTypeAnnotation(),\n ]);\n }\n}\n\nexport function LogicalExpression(this: NodePath<t.LogicalExpression>) {\n const argumentTypes = [\n this.get(\"left\").getTypeAnnotation(),\n this.get(\"right\").getTypeAnnotation(),\n ];\n\n return createUnionType(argumentTypes);\n}\n\nexport function ConditionalExpression(this: NodePath<t.ConditionalExpression>) {\n const argumentTypes = [\n this.get(\"consequent\").getTypeAnnotation(),\n this.get(\"alternate\").getTypeAnnotation(),\n ];\n\n return createUnionType(argumentTypes);\n}\n\nexport function SequenceExpression(this: NodePath<t.SequenceExpression>) {\n return this.get(\"expresLine truncated
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createUnionType = createUnionType;
|
||||
var _t = require("@babel/types");
|
||||
const {
|
||||
createFlowUnionType,
|
||||
createTSUnionType,
|
||||
createUnionTypeAnnotation,
|
||||
isFlowType,
|
||||
isTSType
|
||||
} = _t;
|
||||
function createUnionType(types) {
|
||||
if (types.every(v => isFlowType(v))) {
|
||||
if (createFlowUnionType) {
|
||||
return createFlowUnionType(types);
|
||||
}
|
||||
return createUnionTypeAnnotation(types);
|
||||
} else if (types.every(v => isTSType(v))) {
|
||||
if (createTSUnionType) {
|
||||
return createTSUnionType(types);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//# sourceMappingURL=util.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"names":["_t","require","createFlowUnionType","createTSUnionType","createUnionTypeAnnotation","isFlowType","isTSType","createUnionType","types","every","v"],"sources":["../../../src/path/inference/util.ts"],"sourcesContent":["import {\n createFlowUnionType,\n createTSUnionType,\n createUnionTypeAnnotation,\n isFlowType,\n isTSType,\n} from \"@babel/types\";\nimport type * as t from \"@babel/types\";\n\nexport function createUnionType(\n types: (t.FlowType | t.TSType)[],\n): t.FlowType | t.TSType | undefined {\n if (process.env.BABEL_8_BREAKING) {\n if (types.every(v => isFlowType(v))) {\n return createFlowUnionType(types);\n }\n if (types.every(v => isTSType(v))) {\n return createTSUnionType(types);\n }\n } else {\n if (types.every(v => isFlowType(v))) {\n if (createFlowUnionType) {\n return createFlowUnionType(types);\n }\n\n return createUnionTypeAnnotation(types);\n } else if (types.every(v => isTSType(v))) {\n if (createTSUnionType) {\n return createTSUnionType(types);\n }\n }\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,EAAA,GAAAC,OAAA;AAMsB;EALpBC,mBAAmB;EACnBC,iBAAiB;EACjBC,yBAAyB;EACzBC,UAAU;EACVC;AAAQ,IAAAN,EAAA;AAIH,SAASO,eAAeA,CAC7BC,KAAgC,EACG;EASjC,IAAIA,KAAK,CAACC,KAAK,CAACC,CAAC,IAAIL,UAAU,CAACK,CAAC,CAAC,CAAC,EAAE;IACnC,IAAIR,mBAAmB,EAAE;MACvB,OAAOA,mBAAmB,CAACM,KAAK,CAAC;IACnC;IAEA,OAAOJ,yBAAyB,CAACI,KAAK,CAAC;EACzC,CAAC,MAAM,IAAIA,KAAK,CAACC,KAAK,CAACC,CAAC,IAAIJ,QAAQ,CAACI,CAAC,CAAC,CAAC,EAAE;IACxC,IAAIP,iBAAiB,EAAE;MACrB,OAAOA,iBAAiB,CAACK,KAAK,CAAC;IACjC;EACF;AAEJ","ignoreList":[]}
|
||||
Reference in new issue
Block a user