diff options
Diffstat (limited to 'node_modules/@babel/traverse/lib/path/inference')
3 files changed, 623 insertions, 0 deletions
diff --git a/node_modules/@babel/traverse/lib/path/inference/index.js b/node_modules/@babel/traverse/lib/path/inference/index.js new file mode 100644 index 0000000..f7fef25 --- /dev/null +++ b/node_modules/@babel/traverse/lib/path/inference/index.js @@ -0,0 +1,156 @@ +"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"); + +var _t = require("@babel/types"); + +const { + anyTypeAnnotation, + isAnyTypeAnnotation, + isBooleanTypeAnnotation, + isEmptyTypeAnnotation, + isFlowBaseAnnotation, + isGenericTypeAnnotation, + isIdentifier, + isMixedTypeAnnotation, + isNumberTypeAnnotation, + isStringTypeAnnotation, + isTypeAnnotation, + isUnionTypeAnnotation, + isVoidTypeAnnotation, + stringTypeAnnotation, + voidTypeAnnotation +} = _t; + +function getTypeAnnotation() { + if (this.typeAnnotation) return this.typeAnnotation; + let type = this._getTypeAnnotation() || anyTypeAnnotation(); + if (isTypeAnnotation(type)) type = type.typeAnnotation; + return this.typeAnnotation = 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(); + return isGenericTypeAnnotation(type) && isIdentifier(type.id, { + name: genericName + }); +}
\ No newline at end of file diff --git a/node_modules/@babel/traverse/lib/path/inference/inferer-reference.js b/node_modules/@babel/traverse/lib/path/inference/inferer-reference.js new file mode 100644 index 0000000..c328dc1 --- /dev/null +++ b/node_modules/@babel/traverse/lib/path/inference/inferer-reference.js @@ -0,0 +1,206 @@ +"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); +}
\ No newline at end of file diff --git a/node_modules/@babel/traverse/lib/path/inference/inferers.js b/node_modules/@babel/traverse/lib/path/inference/inferers.js new file mode 100644 index 0000000..68180ac --- /dev/null +++ b/node_modules/@babel/traverse/lib/path/inference/inferers.js @@ -0,0 +1,261 @@ +"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.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"); + +const { + BOOLEAN_BINARY_OPERATORS, + BOOLEAN_UNARY_OPERATORS, + NUMBER_BINARY_OPERATORS, + NUMBER_UNARY_OPERATORS, + STRING_UNARY_OPERATORS, + anyTypeAnnotation, + arrayTypeAnnotation, + booleanTypeAnnotation, + buildMatchMemberExpression, + createFlowUnionType, + createTSUnionType, + createUnionTypeAnnotation, + genericTypeAnnotation, + identifier, + isTSTypeAnnotation, + nullLiteralTypeAnnotation, + numberTypeAnnotation, + stringTypeAnnotation, + tupleTypeAnnotation, + unionTypeAnnotation, + voidTypeAnnotation +} = _t; + +function VariableDeclarator() { + var _type; + + const id = this.get("id"); + if (!id.isIdentifier()) return; + const init = this.get("init"); + let type = init.getTypeAnnotation(); + + if (((_type = type) == null ? void 0 : _type.type) === "AnyTypeAnnotation") { + if (init.isCallExpression() && init.get("callee").isIdentifier({ + name: "Array" + }) && !init.scope.hasBinding("Array", true)) { + type = ArrayExpression(); + } + } + + return type; +} + +function TypeCastExpression(node) { + return node.typeAnnotation; +} + +TypeCastExpression.validParent = true; + +function NewExpression(node) { + if (this.get("callee").isIdentifier()) { + 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.indexOf(operator) >= 0) { + return numberTypeAnnotation(); + } else if (STRING_UNARY_OPERATORS.indexOf(operator) >= 0) { + return stringTypeAnnotation(); + } else if (BOOLEAN_UNARY_OPERATORS.indexOf(operator) >= 0) { + return booleanTypeAnnotation(); + } +} + +function BinaryExpression(node) { + const operator = node.operator; + + if (NUMBER_BINARY_OPERATORS.indexOf(operator) >= 0) { + return numberTypeAnnotation(); + } else if (BOOLEAN_BINARY_OPERATORS.indexOf(operator) >= 0) { + 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()]; + + if (isTSTypeAnnotation(argumentTypes[0]) && createTSUnionType) { + return createTSUnionType(argumentTypes); + } + + if (createFlowUnionType) { + return createFlowUnionType(argumentTypes); + } + + return createUnionTypeAnnotation(argumentTypes); +} + +function ConditionalExpression() { + const argumentTypes = [this.get("consequent").getTypeAnnotation(), this.get("alternate").getTypeAnnotation()]; + + if (isTSTypeAnnotation(argumentTypes[0]) && createTSUnionType) { + return createTSUnionType(argumentTypes); + } + + if (createFlowUnionType) { + return createFlowUnionType(argumentTypes); + } + + return createUnionTypeAnnotation(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)) { + 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()) { + if (callee.is("async")) { + if (callee.is("generator")) { + return genericTypeAnnotation(identifier("AsyncIterator")); + } else { + return genericTypeAnnotation(identifier("Promise")); + } + } else { + if (callee.node.returnType) { + return callee.node.returnType; + } else {} + } + } +}
\ No newline at end of file |