UNPKG

smells-code-analyzer

Version:

CLI tool powered by LSP and tree-sitter for finding dead and smells code from your project

82 lines 2.57 kB
import Parser from 'tree-sitter'; import parser from 'tree-sitter-typescript'; export const Grammars = { typescript: parser.typescript, }; export function findElemPositions(config, sourceCode) { const tree = parse(config, sourceCode); const foundNodes = findNodes(config.referenceNodes, tree); return foundNodes; } function parse(config, sourceCode) { const parser = new Parser(); const grammar = Grammars[config.grammar]; if (!grammar) { console.error(`Grammar ${config.grammar} not found`); } parser.setLanguage(grammar); const tree = parser.parse(sourceCode); return tree; } function findNodes(referenceNodes, tree, parent) { const foundNodeInfos = []; for (const node of traverseTree(tree, parent)) { foundNodeInfos.push(...handleNode(referenceNodes, node)); } return foundNodeInfos; } function handleNode(referenceNodes, node) { const foundNodeInfos = []; referenceNodes.forEach((referenceNode) => { if (node.type === referenceNode.type) { const target = referenceNode.refType ? findTargetNode(node, referenceNode.refType) : node; if (!target) { return; } const foundNode = { name: target.text, type: node.type, startPos: target.startPosition, children: [], }; if (referenceNode.children) { foundNode.children.push(...findNodes(referenceNode.children, node.tree, node)); } foundNodeInfos.push(foundNode); } }); return foundNodeInfos; } function findTargetNode(parentNode, targetRef) { for (const node of traverseTree(parentNode.tree, parentNode)) { if (node.type === targetRef) { return node; } } } function* traverseTree(tree, parentNode) { const cursor = parentNode?.walk() ?? tree.walk(); let reachedRoot = false; while (!reachedRoot) { yield cursor.currentNode; if (cursor.gotoFirstChild()) { continue; } if (cursor.gotoNextSibling()) { continue; } let retracing = true; while (retracing) { if (!cursor.gotoParent() || cursor.currentNode === parentNode) { retracing = false; reachedRoot = true; } if (cursor.gotoNextSibling()) { retracing = false; } } } } //# sourceMappingURL=ts-analyzer.js.map