UNPKG

knip

Version:

Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects

72 lines (71 loc) 2.52 kB
import ts from 'typescript'; import { timerify } from "../util/Performance.js"; import { isIdChar } from "../util/regex.js"; const findInFlow = (flowNode, targetSymbol) => { if (!flowNode?.node) return false; if (flowNode.node.symbol === targetSymbol) return true; return findInFlow(flowNode.antecedent, targetSymbol); }; const hasRefsInFile = (item, sourceFile, typeChecker) => { if (!item.symbol) return false; if (item.identifier === '') return true; if (item.symbol.flags & ts.SymbolFlags.AliasExcludes) return true; const text = sourceFile.text; const id = item.identifier; const symbols = new Set(); const pos = item.pos; const declarationRanges = []; for (const decl of item.symbol.declarations ?? []) { const name = decl.name; if (name) declarationRanges.push({ start: name.pos, end: name.end }); } let index = 0; while (index < text.length && (index = text.indexOf(id, index)) !== -1) { if (isIdChar(text.charAt(index - 1)) || isIdChar(text.charAt(index + id.length))) { index += id.length; continue; } if (index === pos || index === pos + 1) { index += id.length; continue; } let skip = false; for (const range of declarationRanges) { if (index >= range.start && index < range.end) { skip = true; break; } } if (skip) { index += id.length; continue; } const symbol = typeChecker.getSymbolAtLocation(ts.getTokenAtPosition(sourceFile, index)); if (symbol && id === symbol.escapedName) { if (item.symbol === symbol) return true; const declaration = symbol.declarations?.[0]; if (declaration) { if (findInFlow(declaration.name?.flowNode, item.symbol)) return true; if (ts.isImportSpecifier(declaration) && symbols.has(symbol)) return true; } if (symbol.flags & ts.SymbolFlags.Property) { const type = typeChecker.getTypeOfSymbol(symbol); if (type?.symbol && item.symbol === type.symbol) return true; } symbols.add(symbol); } index += id.length; } return false; }; export const _hasRefsInFile = timerify(hasRefsInFile);