Skip to content

Commit fb6a139

Browse files
perf: replace manual AST walk with tree-sitter Query API for JS/TS/TSX extraction
WASM build speed regressed from 5.0 ms/file (v2.0.0) to 6.6 ms/file (v2.1.0+) due to excessive WASM-JS boundary crossings in the JS extractor — every node.type, .text, .childForFieldName() call crosses the boundary. Phase 1 — cache redundant boundary crossings: - Fix findChild() calling node.child(i) twice per match - Cache node.type, node.startPosition.row, prop.text into locals across class_declaration, export_statement, extractCallInfo, walkCallChain, findParentClass, and variable_declaration cases Phase 2 — tree-sitter Query API extraction: - Import Query from web-tree-sitter, compile S-expression patterns per language (JS vs TS/TSX) during createParsers(), cache in module-level Map - New extractSymbolsQuery() uses query.matches(rootNode) to run pattern matching entirely inside WASM, reducing boundary crossings from O(nodes × properties) to O(matches × captures) - Post-processing only runs on matched nodes (tens per file) not all AST nodes (thousands per file) - Manual tree walk preserved as fallback for backward compatibility when query is not provided Result: 6.6 → 4.4 ms/file (−33%), below v2.0.0 baseline of 5.0 ms/file. All 536 tests pass, node/edge counts identical. Impact: 12 functions changed, 20 affected
1 parent ab0d3a0 commit fb6a139

3 files changed

Lines changed: 335 additions & 81 deletions

File tree

src/extractors/helpers.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ export function nodeEndLine(node) {
44

55
export function findChild(node, type) {
66
for (let i = 0; i < node.childCount; i++) {
7-
if (node.child(i).type === type) return node.child(i);
7+
const child = node.child(i);
8+
if (child.type === type) return child;
89
}
910
return null;
1011
}

0 commit comments

Comments
 (0)