MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / extractWithTreeSitter

Function extractWithTreeSitter

src/codegraph/extractor.ts:77–159  ·  view source on GitHub ↗
(
  parserResult: { parser: any; language: any },
  lang: string,
  source: string,
)

Source from the content-addressed store, hash-verified

75}
76
77function extractWithTreeSitter(
78 parserResult: { parser: any; language: any },
79 lang: string,
80 source: string,
81): ExtractedSymbol[] {
82 const tree = parserResult.parser.parse(source);
83 const root = tree.rootNode;
84 const nodeMap = SYMBOL_NODE_TYPES[lang];
85 if (!nodeMap) return [];
86
87 const symbols: ExtractedSymbol[] = [];
88 // Build a flat reverse lookup: node type → kind name
89 const typeToKind = new Map<string, string>();
90 for (const [kind, types] of Object.entries(nodeMap)) {
91 for (const t of types) typeToKind.set(t, kind);
92 }
93
94 function getName(node: any): string | null {
95 const nameNode = node.childForFieldName('name');
96 if (nameNode) return nameNode.text;
97 for (let i = 0; i < node.childCount; i++) {
98 const c = node.child(i);
99 if (c && (c.type === 'identifier' || c.type === 'property_identifier' || c.type === 'type_identifier')) {
100 return c.text;
101 }
102 }
103 return null;
104 }
105
106 function getEnclosingNamedSymbol(node: any): string | null {
107 let cur = node.parent;
108 while (cur) {
109 const kind = typeToKind.get(cur.type);
110 if (kind) {
111 const name = getName(cur);
112 if (name) return name;
113 }
114 cur = cur.parent;
115 }
116 return null;
117 }
118
119 function visit(node: any) {
120 let kind = typeToKind.get(node.type);
121 // Rust maps `function_item` to BOTH `function` and `method`, so the flat
122 // type→kind map can't tell them apart (last write wins). Disambiguate by
123 // context: a `fn` enclosed in an impl/trait block is a method, otherwise a
124 // free function.
125 if (lang === 'rust' && node.type === 'function_item') {
126 let cur = node.parent;
127 let insideImplOrTrait = false;
128 while (cur) {
129 if (cur.type === 'impl_item' || cur.type === 'trait_item') { insideImplOrTrait = true; break; }
130 cur = cur.parent;
131 }
132 kind = insideImplOrTrait ? 'method' : 'function';
133 }
134 if (kind) {

Callers 1

extractSymbolsFunction · 0.85

Calls 2

visitFunction · 0.70
setMethod · 0.45

Tested by

no test coverage detected