UNPKG

tsd

Version:

Check TypeScript type definitions

89 lines (88 loc) 3.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseErrorAssertionToLocation = exports.extractAssertions = void 0; const typescript_1 = require("@tsd/typescript"); const assertions_1 = require("./assertions"); const assertionFnNames = new Set(Object.values(assertions_1.Assertion)); /** * Extract all assertions. * * @param program - TypeScript program. */ const extractAssertions = (program) => { const assertions = new Map(); const checker = program.getTypeChecker(); /** * Checks if the given node is semantically valid and is an assertion. */ function handleNode(node) { var _a; const expression = (0, typescript_1.isPropertyAccessExpression)(node.expression) ? node.expression.name : node.expression; const maybeSymbol = checker.getSymbolAtLocation(expression); if (!maybeSymbol) { // Bail out if a Symbol doesn't exist for this Node // This either means a symbol could not be resolved // for an identifier, or that the expression is // syntactically valid, but not semantically valid. return; } const symbol = maybeSymbol.flags & typescript_1.SymbolFlags.Alias ? checker.getAliasedSymbol(maybeSymbol) : maybeSymbol; const identifier = symbol.getName(); // Check if the call type is a valid assertion if (assertionFnNames.has(identifier)) { const assertion = identifier; const nodes = (_a = assertions.get(assertion)) !== null && _a !== void 0 ? _a : new Set(); nodes.add(node); assertions.set(assertion, nodes); } } /** * Recursively loop over all the nodes and extract all the assertions out of the source files. */ function walkNodes(node) { if ((0, typescript_1.isCallExpression)(node)) { handleNode(node); } (0, typescript_1.forEachChild)(node, walkNodes); } for (const sourceFile of program.getSourceFiles()) { walkNodes(sourceFile); } return assertions; }; exports.extractAssertions = extractAssertions; /** * Loop over all the error assertion nodes and convert them to a location map. * * @param assertions - Assertion map. */ const parseErrorAssertionToLocation = (assertions) => { const nodes = assertions.get(assertions_1.Assertion.EXPECT_ERROR); const expectedErrors = new Map(); if (!nodes) { // Bail out if we don't have any error nodes return expectedErrors; } // Iterate over the nodes and add the node range to the map for (const node of nodes) { const location = { fileName: node.getSourceFile().fileName, start: node.getStart(), end: node.getEnd() + 1 }; const pos = node .getSourceFile() .getLineAndCharacterOfPosition(node.getStart()); expectedErrors.set(location, { fileName: location.fileName, line: pos.line + 1, column: pos.character }); } return expectedErrors; }; exports.parseErrorAssertionToLocation = parseErrorAssertionToLocation;