@ngommans/codefocus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @ngommans/codefocus might be problematic. Click here for more details.
- package/README.md +124 -0
- package/dist/benchmark-43DOYNYR.js +465 -0
- package/dist/benchmark-43DOYNYR.js.map +1 -0
- package/dist/chunk-6XH2ZLP6.js +127 -0
- package/dist/chunk-6XH2ZLP6.js.map +1 -0
- package/dist/chunk-7RYHZOYF.js +27 -0
- package/dist/chunk-7RYHZOYF.js.map +1 -0
- package/dist/chunk-ITVAEU6K.js +250 -0
- package/dist/chunk-ITVAEU6K.js.map +1 -0
- package/dist/chunk-Q6DOBQ4F.js +231 -0
- package/dist/chunk-Q6DOBQ4F.js.map +1 -0
- package/dist/chunk-X7DRJUEX.js +543 -0
- package/dist/chunk-X7DRJUEX.js.map +1 -0
- package/dist/cli.js +111 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands-ICBN54MT.js +64 -0
- package/dist/commands-ICBN54MT.js.map +1 -0
- package/dist/config-OCBWYENF.js +12 -0
- package/dist/config-OCBWYENF.js.map +1 -0
- package/dist/extended-benchmark-5RUXDG3D.js +323 -0
- package/dist/extended-benchmark-5RUXDG3D.js.map +1 -0
- package/dist/find-W5UDE4US.js +63 -0
- package/dist/find-W5UDE4US.js.map +1 -0
- package/dist/graph-DZNBEATA.js +189 -0
- package/dist/graph-DZNBEATA.js.map +1 -0
- package/dist/map-6WOMDLCP.js +131 -0
- package/dist/map-6WOMDLCP.js.map +1 -0
- package/dist/mcp-7WYTXIQS.js +354 -0
- package/dist/mcp-7WYTXIQS.js.map +1 -0
- package/dist/mcp-server.js +369 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/query-DJNWYYJD.js +427 -0
- package/dist/query-DJNWYYJD.js.map +1 -0
- package/dist/query-PS6QVPXP.js +538 -0
- package/dist/query-PS6QVPXP.js.map +1 -0
- package/dist/root-ODTOXM2J.js +10 -0
- package/dist/root-ODTOXM2J.js.map +1 -0
- package/dist/watcher-LFBZAM5E.js +73 -0
- package/dist/watcher-LFBZAM5E.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
IndexDatabase
|
|
4
|
+
} from "./chunk-Q6DOBQ4F.js";
|
|
5
|
+
|
|
6
|
+
// src/indexer.ts
|
|
7
|
+
import { createRequire as createRequire2 } from "module";
|
|
8
|
+
import { readFileSync } from "fs";
|
|
9
|
+
import { resolve, relative, dirname, extname } from "path";
|
|
10
|
+
import { createHash } from "crypto";
|
|
11
|
+
|
|
12
|
+
// src/parser.ts
|
|
13
|
+
import { createRequire } from "module";
|
|
14
|
+
var require2 = createRequire(import.meta.url);
|
|
15
|
+
var Parser = require2("tree-sitter");
|
|
16
|
+
var TypeScriptLang = require2("tree-sitter-typescript").typescript;
|
|
17
|
+
var parser = null;
|
|
18
|
+
function getParser() {
|
|
19
|
+
if (!parser) {
|
|
20
|
+
parser = new Parser();
|
|
21
|
+
parser.setLanguage(TypeScriptLang);
|
|
22
|
+
}
|
|
23
|
+
return parser;
|
|
24
|
+
}
|
|
25
|
+
function extractSignature(node, source) {
|
|
26
|
+
const kind = node.type;
|
|
27
|
+
if (kind === "function_declaration" || kind === "arrow_function") {
|
|
28
|
+
const nameNode = node.childForFieldName("name");
|
|
29
|
+
const paramsNode = node.childForFieldName("parameters");
|
|
30
|
+
const returnType = node.childForFieldName("return_type");
|
|
31
|
+
if (nameNode && paramsNode) {
|
|
32
|
+
let sig = `function ${nameNode.text}${paramsNode.text}`;
|
|
33
|
+
if (returnType) sig += returnType.text;
|
|
34
|
+
return sig;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (kind === "class_declaration") {
|
|
38
|
+
const nameNode = node.childForFieldName("name");
|
|
39
|
+
if (nameNode) return `class ${nameNode.text}`;
|
|
40
|
+
}
|
|
41
|
+
if (kind === "interface_declaration") {
|
|
42
|
+
const nameNode = node.childForFieldName("name");
|
|
43
|
+
if (nameNode) return `interface ${nameNode.text}`;
|
|
44
|
+
}
|
|
45
|
+
if (kind === "type_alias_declaration") {
|
|
46
|
+
const text = node.text;
|
|
47
|
+
const semiIdx = text.indexOf(";");
|
|
48
|
+
return semiIdx > 0 ? text.slice(0, semiIdx) : text;
|
|
49
|
+
}
|
|
50
|
+
if (kind === "enum_declaration") {
|
|
51
|
+
const nameNode = node.childForFieldName("name");
|
|
52
|
+
if (nameNode) return `enum ${nameNode.text}`;
|
|
53
|
+
}
|
|
54
|
+
if (kind === "method_definition") {
|
|
55
|
+
const nameNode = node.childForFieldName("name");
|
|
56
|
+
const paramsNode = node.childForFieldName("parameters");
|
|
57
|
+
const returnType = node.childForFieldName("return_type");
|
|
58
|
+
if (nameNode && paramsNode) {
|
|
59
|
+
let sig = `${nameNode.text}${paramsNode.text}`;
|
|
60
|
+
if (returnType) sig += returnType.text;
|
|
61
|
+
return sig;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
function getSymbolName(node) {
|
|
67
|
+
const nameNode = node.childForFieldName("name") ?? node.childForFieldName("declarator");
|
|
68
|
+
return nameNode?.text ?? null;
|
|
69
|
+
}
|
|
70
|
+
function extractDeclaration(node, source, exported) {
|
|
71
|
+
const kindMap = {
|
|
72
|
+
function_declaration: "function",
|
|
73
|
+
class_declaration: "class",
|
|
74
|
+
interface_declaration: "interface",
|
|
75
|
+
type_alias_declaration: "type",
|
|
76
|
+
enum_declaration: "enum"
|
|
77
|
+
};
|
|
78
|
+
const kind = kindMap[node.type];
|
|
79
|
+
if (!kind) return null;
|
|
80
|
+
const name = getSymbolName(node);
|
|
81
|
+
if (!name) return null;
|
|
82
|
+
return {
|
|
83
|
+
name,
|
|
84
|
+
kind,
|
|
85
|
+
startByte: node.startIndex,
|
|
86
|
+
endByte: node.endIndex,
|
|
87
|
+
startLine: node.startPosition.row + 1,
|
|
88
|
+
endLine: node.endPosition.row + 1,
|
|
89
|
+
startColumn: node.startPosition.column,
|
|
90
|
+
endColumn: node.endPosition.column,
|
|
91
|
+
signature: extractSignature(node, source),
|
|
92
|
+
exported
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function extractMethods(classNode, source, exported) {
|
|
96
|
+
const methods = [];
|
|
97
|
+
const body = classNode.childForFieldName("body");
|
|
98
|
+
if (!body) return methods;
|
|
99
|
+
for (const child of body.namedChildren) {
|
|
100
|
+
if (child.type === "method_definition") {
|
|
101
|
+
const nameNode = child.childForFieldName("name");
|
|
102
|
+
if (!nameNode) continue;
|
|
103
|
+
methods.push({
|
|
104
|
+
name: nameNode.text,
|
|
105
|
+
kind: "method",
|
|
106
|
+
startByte: child.startIndex,
|
|
107
|
+
endByte: child.endIndex,
|
|
108
|
+
startLine: child.startPosition.row + 1,
|
|
109
|
+
endLine: child.endPosition.row + 1,
|
|
110
|
+
startColumn: child.startPosition.column,
|
|
111
|
+
endColumn: child.endPosition.column,
|
|
112
|
+
signature: extractSignature(child, source),
|
|
113
|
+
exported
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return methods;
|
|
118
|
+
}
|
|
119
|
+
function extractVariableDeclarations(node, exported) {
|
|
120
|
+
const symbols = [];
|
|
121
|
+
for (const child of node.namedChildren) {
|
|
122
|
+
if (child.type === "variable_declarator") {
|
|
123
|
+
const nameNode = child.childForFieldName("name");
|
|
124
|
+
if (nameNode) {
|
|
125
|
+
symbols.push({
|
|
126
|
+
name: nameNode.text,
|
|
127
|
+
kind: "variable",
|
|
128
|
+
startByte: node.startIndex,
|
|
129
|
+
endByte: node.endIndex,
|
|
130
|
+
startLine: node.startPosition.row + 1,
|
|
131
|
+
endLine: node.endPosition.row + 1,
|
|
132
|
+
startColumn: node.startPosition.column,
|
|
133
|
+
endColumn: node.endPosition.column,
|
|
134
|
+
signature: null,
|
|
135
|
+
exported
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return symbols;
|
|
141
|
+
}
|
|
142
|
+
function extractImport(node) {
|
|
143
|
+
let sourceNode = null;
|
|
144
|
+
for (const child of node.children) {
|
|
145
|
+
if (child.type === "string") {
|
|
146
|
+
sourceNode = child;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (!sourceNode) return null;
|
|
151
|
+
const rawSource = sourceNode.text;
|
|
152
|
+
const source = rawSource.replace(/^['"]|['"]$/g, "");
|
|
153
|
+
const specifiers = [];
|
|
154
|
+
const isTypeOnly = node.children.some(
|
|
155
|
+
(c) => c.type === "type" && c.text === "type"
|
|
156
|
+
);
|
|
157
|
+
for (const child of node.children) {
|
|
158
|
+
if (child.type === "import_clause") {
|
|
159
|
+
for (const clause of child.namedChildren) {
|
|
160
|
+
if (clause.type === "named_imports") {
|
|
161
|
+
for (const spec of clause.namedChildren) {
|
|
162
|
+
if (spec.type === "import_specifier") {
|
|
163
|
+
const nameNode = spec.childForFieldName("name");
|
|
164
|
+
const aliasNode = spec.childForFieldName("alias");
|
|
165
|
+
specifiers.push(aliasNode?.text ?? nameNode?.text ?? spec.text);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} else if (clause.type === "identifier") {
|
|
169
|
+
specifiers.push(clause.text);
|
|
170
|
+
} else if (clause.type === "namespace_import") {
|
|
171
|
+
const nameNode = clause.namedChildren.find(
|
|
172
|
+
(c) => c.type === "identifier"
|
|
173
|
+
);
|
|
174
|
+
if (nameNode) specifiers.push(`* as ${nameNode.text}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return { specifiers, source, isTypeOnly };
|
|
180
|
+
}
|
|
181
|
+
function extractReExportSpecifiers(node) {
|
|
182
|
+
const specifiers = [];
|
|
183
|
+
for (const child of node.children) {
|
|
184
|
+
if (child.type === "export_clause") {
|
|
185
|
+
for (const spec of child.namedChildren) {
|
|
186
|
+
if (spec.type === "export_specifier") {
|
|
187
|
+
const nameNode = spec.childForFieldName("name");
|
|
188
|
+
if (nameNode) specifiers.push(nameNode.text);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return specifiers;
|
|
194
|
+
}
|
|
195
|
+
function findIdentifierUsages(source, names) {
|
|
196
|
+
if (names.size === 0) return [];
|
|
197
|
+
const p = getParser();
|
|
198
|
+
const tree = p.parse(source);
|
|
199
|
+
const root = tree.rootNode;
|
|
200
|
+
const usages = [];
|
|
201
|
+
function walk(node) {
|
|
202
|
+
if ((node.type === "identifier" || node.type === "type_identifier") && names.has(node.text)) {
|
|
203
|
+
let parent = node.parent;
|
|
204
|
+
let isImportExport = false;
|
|
205
|
+
while (parent) {
|
|
206
|
+
if (parent.type === "import_statement" || parent.type === "import_clause" || parent.type === "import_specifier" || parent.type === "export_statement" && parent.children.some((c) => c.type === "from")) {
|
|
207
|
+
isImportExport = true;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
parent = parent.parent;
|
|
211
|
+
}
|
|
212
|
+
if (!isImportExport) {
|
|
213
|
+
usages.push({
|
|
214
|
+
name: node.text,
|
|
215
|
+
line: node.startPosition.row + 1,
|
|
216
|
+
column: node.startPosition.column
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
for (const child of node.children) {
|
|
221
|
+
walk(child);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
walk(root);
|
|
225
|
+
return usages;
|
|
226
|
+
}
|
|
227
|
+
function extractDynamicImports(root) {
|
|
228
|
+
const imports = [];
|
|
229
|
+
function walk(node) {
|
|
230
|
+
if (node.type === "call_expression") {
|
|
231
|
+
const fn = node.child(0);
|
|
232
|
+
if (fn && fn.type === "import") {
|
|
233
|
+
const argsNode = node.childForFieldName("arguments");
|
|
234
|
+
if (argsNode) {
|
|
235
|
+
const strArg = argsNode.namedChildren.find(
|
|
236
|
+
(c) => c.type === "string"
|
|
237
|
+
);
|
|
238
|
+
if (strArg) {
|
|
239
|
+
const modulePath = strArg.text.replace(/^['"]|['"]$/g, "");
|
|
240
|
+
const specifiers = extractDynamicImportSpecifiers(node);
|
|
241
|
+
imports.push({ specifiers, source: modulePath, isTypeOnly: false });
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const child of node.children) {
|
|
248
|
+
walk(child);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
walk(root);
|
|
252
|
+
return imports;
|
|
253
|
+
}
|
|
254
|
+
function extractDynamicImportSpecifiers(importCall) {
|
|
255
|
+
let current = importCall.parent;
|
|
256
|
+
if (current && current.type === "await_expression") {
|
|
257
|
+
current = current.parent;
|
|
258
|
+
}
|
|
259
|
+
if (current && current.type === "variable_declarator") {
|
|
260
|
+
const pattern = current.childForFieldName("name");
|
|
261
|
+
if (pattern && pattern.type === "object_pattern") {
|
|
262
|
+
const specs = [];
|
|
263
|
+
for (const child of pattern.namedChildren) {
|
|
264
|
+
if (child.type === "shorthand_property_identifier_pattern") {
|
|
265
|
+
specs.push(child.text);
|
|
266
|
+
} else if (child.type === "pair_pattern") {
|
|
267
|
+
const value = child.childForFieldName("value");
|
|
268
|
+
if (value) specs.push(value.text);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return specs;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
function parseSource(source) {
|
|
277
|
+
const p = getParser();
|
|
278
|
+
const tree = p.parse(source);
|
|
279
|
+
const root = tree.rootNode;
|
|
280
|
+
const symbols = [];
|
|
281
|
+
const imports = [];
|
|
282
|
+
for (const node of root.namedChildren) {
|
|
283
|
+
if (node.type === "import_statement") {
|
|
284
|
+
const imp = extractImport(node);
|
|
285
|
+
if (imp) imports.push(imp);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (node.type === "export_statement") {
|
|
289
|
+
const hasFrom = node.children.some(
|
|
290
|
+
(c) => c.type === "from"
|
|
291
|
+
);
|
|
292
|
+
if (hasFrom) {
|
|
293
|
+
let sourceNode = null;
|
|
294
|
+
for (const child of node.children) {
|
|
295
|
+
if (child.type === "string") {
|
|
296
|
+
sourceNode = child;
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (sourceNode) {
|
|
301
|
+
const rawSource = sourceNode.text;
|
|
302
|
+
const source2 = rawSource.replace(/^['"]|['"]$/g, "");
|
|
303
|
+
const specifiers = extractReExportSpecifiers(node);
|
|
304
|
+
const isTypeOnly = node.children.some(
|
|
305
|
+
(c) => c.type === "type" && c.text === "type"
|
|
306
|
+
);
|
|
307
|
+
imports.push({ specifiers, source: source2, isTypeOnly });
|
|
308
|
+
}
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
for (const child of node.namedChildren) {
|
|
312
|
+
const decl2 = extractDeclaration(child, source, true);
|
|
313
|
+
if (decl2) {
|
|
314
|
+
symbols.push(decl2);
|
|
315
|
+
if (child.type === "class_declaration") {
|
|
316
|
+
symbols.push(...extractMethods(child, source, true));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (child.type === "lexical_declaration" || child.type === "variable_declaration") {
|
|
320
|
+
symbols.push(...extractVariableDeclarations(child, true));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
const decl = extractDeclaration(node, source, false);
|
|
326
|
+
if (decl) {
|
|
327
|
+
symbols.push(decl);
|
|
328
|
+
if (node.type === "class_declaration") {
|
|
329
|
+
symbols.push(...extractMethods(node, source, false));
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (node.type === "lexical_declaration" || node.type === "variable_declaration") {
|
|
333
|
+
symbols.push(...extractVariableDeclarations(node, false));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
imports.push(...extractDynamicImports(root));
|
|
337
|
+
return { symbols, imports };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/indexer.ts
|
|
341
|
+
var require3 = createRequire2(import.meta.url);
|
|
342
|
+
var fg = require3("fast-glob");
|
|
343
|
+
var TS_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx"]);
|
|
344
|
+
var IGNORE_PATTERNS = [
|
|
345
|
+
"**/node_modules/**",
|
|
346
|
+
"**/dist/**",
|
|
347
|
+
"**/.codefocus/**",
|
|
348
|
+
"**/__tests__/**",
|
|
349
|
+
"**/*.test.*",
|
|
350
|
+
"**/*.spec.*",
|
|
351
|
+
"**/*.d.ts"
|
|
352
|
+
];
|
|
353
|
+
function hashContent(content) {
|
|
354
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
355
|
+
}
|
|
356
|
+
function resolveImportPath(importSource, fromFile, rootDir, allFiles) {
|
|
357
|
+
if (!importSource.startsWith(".")) return null;
|
|
358
|
+
const fromDir = dirname(fromFile);
|
|
359
|
+
const basePath = resolve(rootDir, fromDir, importSource);
|
|
360
|
+
const ext = extname(basePath);
|
|
361
|
+
const strippedBase = ext === ".js" || ext === ".jsx" ? basePath.slice(0, -ext.length) : null;
|
|
362
|
+
const candidates = [
|
|
363
|
+
basePath,
|
|
364
|
+
...Array.from(TS_EXTENSIONS).map((e) => basePath + e),
|
|
365
|
+
...Array.from(TS_EXTENSIONS).map((e) => resolve(basePath, "index" + e))
|
|
366
|
+
];
|
|
367
|
+
if (strippedBase) {
|
|
368
|
+
candidates.push(
|
|
369
|
+
...Array.from(TS_EXTENSIONS).map((e) => strippedBase + e),
|
|
370
|
+
...Array.from(TS_EXTENSIONS).map(
|
|
371
|
+
(e) => resolve(strippedBase, "index" + e)
|
|
372
|
+
)
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
for (const candidate of candidates) {
|
|
376
|
+
const rel = relative(rootDir, candidate);
|
|
377
|
+
if (allFiles.has(rel)) return rel;
|
|
378
|
+
}
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
async function indexProject(rootDir, dbPath) {
|
|
382
|
+
const startTime = Date.now();
|
|
383
|
+
const absRoot = resolve(rootDir);
|
|
384
|
+
const files = await fg("**/*.{ts,tsx,js,jsx}", {
|
|
385
|
+
cwd: absRoot,
|
|
386
|
+
ignore: IGNORE_PATTERNS,
|
|
387
|
+
absolute: false
|
|
388
|
+
});
|
|
389
|
+
const allFiles = new Set(files);
|
|
390
|
+
const db = new IndexDatabase(dbPath);
|
|
391
|
+
let filesIndexed = 0;
|
|
392
|
+
let filesSkipped = 0;
|
|
393
|
+
let symbolsExtracted = 0;
|
|
394
|
+
let importsFound = 0;
|
|
395
|
+
let referencesCreated = 0;
|
|
396
|
+
const symbolIdMap = /* @__PURE__ */ new Map();
|
|
397
|
+
const fileImports = /* @__PURE__ */ new Map();
|
|
398
|
+
const fileContents = /* @__PURE__ */ new Map();
|
|
399
|
+
db.transaction(() => {
|
|
400
|
+
for (const filePath of files) {
|
|
401
|
+
const absPath = resolve(absRoot, filePath);
|
|
402
|
+
let content;
|
|
403
|
+
try {
|
|
404
|
+
content = readFileSync(absPath, "utf-8");
|
|
405
|
+
} catch {
|
|
406
|
+
filesSkipped++;
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
const hash = hashContent(content);
|
|
410
|
+
const existingHash = db.getFileHash(filePath);
|
|
411
|
+
const result = parseSource(content);
|
|
412
|
+
if (result.imports.length > 0) {
|
|
413
|
+
fileImports.set(filePath, result.imports);
|
|
414
|
+
fileContents.set(filePath, content);
|
|
415
|
+
}
|
|
416
|
+
if (existingHash === hash) {
|
|
417
|
+
filesSkipped++;
|
|
418
|
+
for (const sym of db.getSymbolsByFile(filePath)) {
|
|
419
|
+
symbolIdMap.set(`${filePath}:${sym.name}`, sym.id);
|
|
420
|
+
}
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
db.clearFile(filePath);
|
|
424
|
+
const ext = extname(filePath);
|
|
425
|
+
const language = ext === ".js" || ext === ".jsx" ? "javascript" : "typescript";
|
|
426
|
+
db.upsertFile({
|
|
427
|
+
path: filePath,
|
|
428
|
+
content_hash: hash,
|
|
429
|
+
language,
|
|
430
|
+
last_indexed: Date.now()
|
|
431
|
+
});
|
|
432
|
+
db.upsertFileContent(filePath, content);
|
|
433
|
+
for (const sym of result.symbols) {
|
|
434
|
+
const id = db.insertSymbol({
|
|
435
|
+
file_path: filePath,
|
|
436
|
+
name: sym.name,
|
|
437
|
+
kind: sym.kind,
|
|
438
|
+
start_byte: sym.startByte,
|
|
439
|
+
end_byte: sym.endByte,
|
|
440
|
+
start_line: sym.startLine,
|
|
441
|
+
end_line: sym.endLine,
|
|
442
|
+
start_column: sym.startColumn,
|
|
443
|
+
end_column: sym.endColumn,
|
|
444
|
+
signature: sym.signature
|
|
445
|
+
});
|
|
446
|
+
symbolIdMap.set(`${filePath}:${sym.name}`, id);
|
|
447
|
+
symbolsExtracted++;
|
|
448
|
+
}
|
|
449
|
+
filesIndexed++;
|
|
450
|
+
}
|
|
451
|
+
db.clearAllImports();
|
|
452
|
+
db.clearAllReferences();
|
|
453
|
+
for (const [filePath, imports] of fileImports) {
|
|
454
|
+
const fileSymbolRows = db.getSymbolsByFile(filePath);
|
|
455
|
+
const sourceSymbols = fileSymbolRows.map((sym) => ({
|
|
456
|
+
name: sym.name,
|
|
457
|
+
id: sym.id,
|
|
458
|
+
startLine: sym.start_line,
|
|
459
|
+
endLine: sym.end_line
|
|
460
|
+
}));
|
|
461
|
+
const allImportedNames = /* @__PURE__ */ new Set();
|
|
462
|
+
for (const imp of imports) {
|
|
463
|
+
for (const specName of imp.specifiers) {
|
|
464
|
+
const cleanName = specName.startsWith("* as ") ? specName.slice(5) : specName;
|
|
465
|
+
allImportedNames.add(cleanName);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
const content = fileContents.get(filePath);
|
|
469
|
+
const usages = content ? findIdentifierUsages(content, allImportedNames) : [];
|
|
470
|
+
for (const imp of imports) {
|
|
471
|
+
const targetFile = resolveImportPath(
|
|
472
|
+
imp.source,
|
|
473
|
+
filePath,
|
|
474
|
+
absRoot,
|
|
475
|
+
allFiles
|
|
476
|
+
);
|
|
477
|
+
for (const specName of imp.specifiers) {
|
|
478
|
+
const cleanName = specName.startsWith("* as ") ? specName.slice(5) : specName;
|
|
479
|
+
db.insertImport({
|
|
480
|
+
file_path: filePath,
|
|
481
|
+
specifier: cleanName,
|
|
482
|
+
source_path: targetFile,
|
|
483
|
+
raw_module: imp.source,
|
|
484
|
+
is_type_only: imp.isTypeOnly ? 1 : 0
|
|
485
|
+
});
|
|
486
|
+
importsFound++;
|
|
487
|
+
}
|
|
488
|
+
if (!targetFile) continue;
|
|
489
|
+
const refType = imp.isTypeOnly ? "type_ref" : "import";
|
|
490
|
+
for (const specName of imp.specifiers) {
|
|
491
|
+
const cleanName = specName.startsWith("* as ") ? specName.slice(5) : specName;
|
|
492
|
+
const targetKey = `${targetFile}:${cleanName}`;
|
|
493
|
+
const targetId = symbolIdMap.get(targetKey);
|
|
494
|
+
if (!targetId) continue;
|
|
495
|
+
const nameUsages = usages.filter((u) => u.name === cleanName);
|
|
496
|
+
if (nameUsages.length > 0) {
|
|
497
|
+
const referencingSymbolIds = /* @__PURE__ */ new Set();
|
|
498
|
+
for (const usage of nameUsages) {
|
|
499
|
+
for (const srcSym of sourceSymbols) {
|
|
500
|
+
if (srcSym.id !== targetId && usage.line >= srcSym.startLine && usage.line <= srcSym.endLine) {
|
|
501
|
+
referencingSymbolIds.add(srcSym.id);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
for (const sourceId of referencingSymbolIds) {
|
|
506
|
+
db.insertReference({
|
|
507
|
+
source_symbol_id: sourceId,
|
|
508
|
+
target_symbol_id: targetId,
|
|
509
|
+
ref_type: refType
|
|
510
|
+
});
|
|
511
|
+
referencesCreated++;
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
for (const srcSym of sourceSymbols) {
|
|
515
|
+
if (srcSym.id !== targetId) {
|
|
516
|
+
db.insertReference({
|
|
517
|
+
source_symbol_id: srcSym.id,
|
|
518
|
+
target_symbol_id: targetId,
|
|
519
|
+
ref_type: refType
|
|
520
|
+
});
|
|
521
|
+
referencesCreated++;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
db.close();
|
|
530
|
+
return {
|
|
531
|
+
filesIndexed,
|
|
532
|
+
filesSkipped,
|
|
533
|
+
symbolsExtracted,
|
|
534
|
+
importsFound,
|
|
535
|
+
referencesCreated,
|
|
536
|
+
timeMs: Date.now() - startTime
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export {
|
|
541
|
+
indexProject
|
|
542
|
+
};
|
|
543
|
+
//# sourceMappingURL=chunk-X7DRJUEX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/indexer.ts","../src/parser.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { readFileSync } from \"node:fs\";\nimport { resolve, relative, dirname, extname } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { IndexDatabase } from \"./db.js\";\nimport { parseSource, findIdentifierUsages, type ImportDef } from \"./parser.js\";\n\nconst require = createRequire(import.meta.url);\nconst fg = require(\"fast-glob\");\n\nconst TS_EXTENSIONS = new Set([\".ts\", \".tsx\", \".js\", \".jsx\"]);\nconst IGNORE_PATTERNS = [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/.codefocus/**\",\n \"**/__tests__/**\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n \"**/*.d.ts\",\n];\n\nexport interface IndexStats {\n filesIndexed: number;\n filesSkipped: number;\n symbolsExtracted: number;\n importsFound: number;\n referencesCreated: number;\n timeMs: number;\n}\n\nfunction hashContent(content: string): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").slice(0, 16);\n}\n\nfunction resolveImportPath(\n importSource: string,\n fromFile: string,\n rootDir: string,\n allFiles: Set<string>,\n): string | null {\n if (!importSource.startsWith(\".\")) return null;\n\n const fromDir = dirname(fromFile);\n const basePath = resolve(rootDir, fromDir, importSource);\n\n // Strip .js/.jsx extension for ESM-style imports (import from \"./foo.js\" → foo.ts)\n const ext = extname(basePath);\n const strippedBase =\n ext === \".js\" || ext === \".jsx\" ? basePath.slice(0, -ext.length) : null;\n\n const candidates = [\n basePath,\n ...Array.from(TS_EXTENSIONS).map((e) => basePath + e),\n ...Array.from(TS_EXTENSIONS).map((e) => resolve(basePath, \"index\" + e)),\n ];\n\n // Also try stripped base with TS extensions (.js → .ts, .tsx, etc.)\n if (strippedBase) {\n candidates.push(\n ...Array.from(TS_EXTENSIONS).map((e) => strippedBase + e),\n ...Array.from(TS_EXTENSIONS).map((e) =>\n resolve(strippedBase, \"index\" + e),\n ),\n );\n }\n\n for (const candidate of candidates) {\n const rel = relative(rootDir, candidate);\n if (allFiles.has(rel)) return rel;\n }\n\n return null;\n}\n\nexport async function indexProject(\n rootDir: string,\n dbPath: string,\n): Promise<IndexStats> {\n const startTime = Date.now();\n const absRoot = resolve(rootDir);\n\n const files: string[] = await fg(\"**/*.{ts,tsx,js,jsx}\", {\n cwd: absRoot,\n ignore: IGNORE_PATTERNS,\n absolute: false,\n });\n\n const allFiles = new Set(files);\n const db = new IndexDatabase(dbPath);\n\n let filesIndexed = 0;\n let filesSkipped = 0;\n let symbolsExtracted = 0;\n let importsFound = 0;\n let referencesCreated = 0;\n\n // Map from \"filePath:symbolName\" → symbolId for reference creation\n const symbolIdMap = new Map<string, number>();\n // Cache imports per file for the reference-creation pass\n const fileImports = new Map<string, ImportDef[]>();\n // Cache file contents for identifier usage extraction\n const fileContents = new Map<string, string>();\n\n db.transaction(() => {\n // Pass 1: parse files, extract and store symbols, collect imports\n for (const filePath of files) {\n const absPath = resolve(absRoot, filePath);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n filesSkipped++;\n continue;\n }\n\n const hash = hashContent(content);\n const existingHash = db.getFileHash(filePath);\n\n // Always parse to collect imports for reference creation\n const result = parseSource(content);\n if (result.imports.length > 0) {\n fileImports.set(filePath, result.imports);\n fileContents.set(filePath, content);\n }\n\n if (existingHash === hash) {\n filesSkipped++;\n // Load existing symbol IDs into the map\n for (const sym of db.getSymbolsByFile(filePath)) {\n symbolIdMap.set(`${filePath}:${sym.name}`, sym.id!);\n }\n continue;\n }\n\n // Clear old data for this file\n db.clearFile(filePath);\n\n const ext = extname(filePath);\n const language =\n ext === \".js\" || ext === \".jsx\" ? \"javascript\" : \"typescript\";\n\n db.upsertFile({\n path: filePath,\n content_hash: hash,\n language,\n last_indexed: Date.now(),\n });\n\n // Populate FTS5 content index\n db.upsertFileContent(filePath, content);\n\n for (const sym of result.symbols) {\n const id = db.insertSymbol({\n file_path: filePath,\n name: sym.name,\n kind: sym.kind,\n start_byte: sym.startByte,\n end_byte: sym.endByte,\n start_line: sym.startLine,\n end_line: sym.endLine,\n start_column: sym.startColumn,\n end_column: sym.endColumn,\n signature: sym.signature,\n });\n symbolIdMap.set(`${filePath}:${sym.name}`, id);\n symbolsExtracted++;\n }\n\n filesIndexed++;\n }\n\n // Pass 2: clear all imports/references and recreate from cached data\n db.clearAllImports();\n db.clearAllReferences();\n\n for (const [filePath, imports] of fileImports) {\n // Cache symbols for this file once (avoid repeated DB queries)\n const fileSymbolRows = db.getSymbolsByFile(filePath);\n const sourceSymbols = fileSymbolRows.map((sym) => ({\n name: sym.name,\n id: sym.id!,\n startLine: sym.start_line,\n endLine: sym.end_line,\n }));\n\n // Collect all imported names across all imports for this file\n const allImportedNames = new Set<string>();\n for (const imp of imports) {\n for (const specName of imp.specifiers) {\n const cleanName = specName.startsWith(\"* as \")\n ? specName.slice(5)\n : specName;\n allImportedNames.add(cleanName);\n }\n }\n\n // Find identifier usages once per file for all imported names\n const content = fileContents.get(filePath);\n const usages = content\n ? findIdentifierUsages(content, allImportedNames)\n : [];\n\n for (const imp of imports) {\n const targetFile = resolveImportPath(\n imp.source,\n filePath,\n absRoot,\n allFiles,\n );\n\n // Store every import declaration in the imports table\n for (const specName of imp.specifiers) {\n const cleanName = specName.startsWith(\"* as \")\n ? specName.slice(5)\n : specName;\n db.insertImport({\n file_path: filePath,\n specifier: cleanName,\n source_path: targetFile,\n raw_module: imp.source,\n is_type_only: imp.isTypeOnly ? 1 : 0,\n });\n importsFound++;\n }\n\n if (!targetFile) continue;\n\n const refType = imp.isTypeOnly ? \"type_ref\" : \"import\";\n\n for (const specName of imp.specifiers) {\n const cleanName = specName.startsWith(\"* as \")\n ? specName.slice(5)\n : specName;\n\n const targetKey = `${targetFile}:${cleanName}`;\n const targetId = symbolIdMap.get(targetKey);\n if (!targetId) continue;\n\n // Find usages of this specific imported name\n const nameUsages = usages.filter((u) => u.name === cleanName);\n\n if (nameUsages.length > 0) {\n // Create references only from symbols that actually use the import\n const referencingSymbolIds = new Set<number>();\n\n for (const usage of nameUsages) {\n for (const srcSym of sourceSymbols) {\n if (\n srcSym.id !== targetId &&\n usage.line >= srcSym.startLine &&\n usage.line <= srcSym.endLine\n ) {\n referencingSymbolIds.add(srcSym.id);\n }\n }\n }\n\n for (const sourceId of referencingSymbolIds) {\n db.insertReference({\n source_symbol_id: sourceId,\n target_symbol_id: targetId,\n ref_type: refType,\n });\n referencesCreated++;\n }\n } else {\n // No usages in code bodies (e.g., re-exports, or type-only imports\n // used only in type positions). Create references from all source\n // symbols for graph connectivity.\n for (const srcSym of sourceSymbols) {\n if (srcSym.id !== targetId) {\n db.insertReference({\n source_symbol_id: srcSym.id,\n target_symbol_id: targetId,\n ref_type: refType,\n });\n referencesCreated++;\n }\n }\n }\n }\n }\n }\n });\n\n db.close();\n\n return {\n filesIndexed,\n filesSkipped,\n symbolsExtracted,\n importsFound,\n referencesCreated,\n timeMs: Date.now() - startTime,\n };\n}\n","import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\nconst Parser = require(\"tree-sitter\");\nconst TypeScriptLang = require(\"tree-sitter-typescript\").typescript;\n\nexport interface SymbolDef {\n name: string;\n kind: string;\n startByte: number;\n endByte: number;\n startLine: number;\n endLine: number;\n startColumn: number;\n endColumn: number;\n signature: string | null;\n exported: boolean;\n}\n\nexport interface ImportDef {\n specifiers: string[];\n source: string;\n isTypeOnly: boolean;\n}\n\nexport interface IdentifierUsage {\n name: string;\n line: number;\n column: number;\n}\n\nexport interface ParseResult {\n symbols: SymbolDef[];\n imports: ImportDef[];\n}\n\ninterface TreeSitterNode {\n type: string;\n text: string;\n startPosition: { row: number; column: number };\n endPosition: { row: number; column: number };\n startIndex: number;\n endIndex: number;\n childCount: number;\n namedChildCount: number;\n child(index: number): TreeSitterNode | null;\n namedChild(index: number): TreeSitterNode | null;\n childForFieldName(name: string): TreeSitterNode | null;\n children: TreeSitterNode[];\n namedChildren: TreeSitterNode[];\n parent: TreeSitterNode | null;\n}\n\nlet parser: InstanceType<typeof Parser> | null = null;\n\nfunction getParser(): InstanceType<typeof Parser> {\n if (!parser) {\n parser = new Parser();\n parser.setLanguage(TypeScriptLang);\n }\n return parser;\n}\n\nfunction extractSignature(node: TreeSitterNode, source: string): string | null {\n const kind = node.type;\n\n if (kind === \"function_declaration\" || kind === \"arrow_function\") {\n const nameNode = node.childForFieldName(\"name\");\n const paramsNode = node.childForFieldName(\"parameters\");\n const returnType = node.childForFieldName(\"return_type\");\n if (nameNode && paramsNode) {\n let sig = `function ${nameNode.text}${paramsNode.text}`;\n if (returnType) sig += returnType.text;\n return sig;\n }\n }\n\n if (kind === \"class_declaration\") {\n const nameNode = node.childForFieldName(\"name\");\n if (nameNode) return `class ${nameNode.text}`;\n }\n\n if (kind === \"interface_declaration\") {\n const nameNode = node.childForFieldName(\"name\");\n if (nameNode) return `interface ${nameNode.text}`;\n }\n\n if (kind === \"type_alias_declaration\") {\n const text = node.text;\n const semiIdx = text.indexOf(\";\");\n return semiIdx > 0 ? text.slice(0, semiIdx) : text;\n }\n\n if (kind === \"enum_declaration\") {\n const nameNode = node.childForFieldName(\"name\");\n if (nameNode) return `enum ${nameNode.text}`;\n }\n\n if (kind === \"method_definition\") {\n const nameNode = node.childForFieldName(\"name\");\n const paramsNode = node.childForFieldName(\"parameters\");\n const returnType = node.childForFieldName(\"return_type\");\n if (nameNode && paramsNode) {\n let sig = `${nameNode.text}${paramsNode.text}`;\n if (returnType) sig += returnType.text;\n return sig;\n }\n }\n\n return null;\n}\n\nfunction getSymbolName(node: TreeSitterNode): string | null {\n const nameNode =\n node.childForFieldName(\"name\") ?? node.childForFieldName(\"declarator\");\n return nameNode?.text ?? null;\n}\n\nfunction extractDeclaration(node: TreeSitterNode, source: string, exported: boolean): SymbolDef | null {\n const kindMap: Record<string, string> = {\n function_declaration: \"function\",\n class_declaration: \"class\",\n interface_declaration: \"interface\",\n type_alias_declaration: \"type\",\n enum_declaration: \"enum\",\n };\n\n const kind = kindMap[node.type];\n if (!kind) return null;\n\n const name = getSymbolName(node);\n if (!name) return null;\n\n return {\n name,\n kind,\n startByte: node.startIndex,\n endByte: node.endIndex,\n startLine: node.startPosition.row + 1,\n endLine: node.endPosition.row + 1,\n startColumn: node.startPosition.column,\n endColumn: node.endPosition.column,\n signature: extractSignature(node, source),\n exported,\n };\n}\n\nfunction extractMethods(classNode: TreeSitterNode, source: string, exported: boolean): SymbolDef[] {\n const methods: SymbolDef[] = [];\n const body = classNode.childForFieldName(\"body\");\n if (!body) return methods;\n\n for (const child of body.namedChildren) {\n if (child.type === \"method_definition\") {\n const nameNode = child.childForFieldName(\"name\");\n if (!nameNode) continue;\n methods.push({\n name: nameNode.text,\n kind: \"method\",\n startByte: child.startIndex,\n endByte: child.endIndex,\n startLine: child.startPosition.row + 1,\n endLine: child.endPosition.row + 1,\n startColumn: child.startPosition.column,\n endColumn: child.endPosition.column,\n signature: extractSignature(child, source),\n exported,\n });\n }\n }\n return methods;\n}\n\nfunction extractVariableDeclarations(node: TreeSitterNode, exported: boolean): SymbolDef[] {\n const symbols: SymbolDef[] = [];\n for (const child of node.namedChildren) {\n if (child.type === \"variable_declarator\") {\n const nameNode = child.childForFieldName(\"name\");\n if (nameNode) {\n symbols.push({\n name: nameNode.text,\n kind: \"variable\",\n startByte: node.startIndex,\n endByte: node.endIndex,\n startLine: node.startPosition.row + 1,\n endLine: node.endPosition.row + 1,\n startColumn: node.startPosition.column,\n endColumn: node.endPosition.column,\n signature: null,\n exported,\n });\n }\n }\n }\n return symbols;\n}\n\nfunction extractImport(node: TreeSitterNode): ImportDef | null {\n let sourceNode: TreeSitterNode | null = null;\n for (const child of node.children) {\n if (child.type === \"string\") {\n sourceNode = child;\n break;\n }\n }\n if (!sourceNode) return null;\n\n const rawSource = sourceNode.text;\n const source = rawSource.replace(/^['\"]|['\"]$/g, \"\");\n\n const specifiers: string[] = [];\n const isTypeOnly = node.children.some(\n (c: TreeSitterNode) => c.type === \"type\" && c.text === \"type\",\n );\n\n for (const child of node.children) {\n if (child.type === \"import_clause\") {\n for (const clause of child.namedChildren) {\n if (clause.type === \"named_imports\") {\n for (const spec of clause.namedChildren) {\n if (spec.type === \"import_specifier\") {\n const nameNode = spec.childForFieldName(\"name\");\n const aliasNode = spec.childForFieldName(\"alias\");\n specifiers.push(aliasNode?.text ?? nameNode?.text ?? spec.text);\n }\n }\n } else if (clause.type === \"identifier\") {\n specifiers.push(clause.text);\n } else if (clause.type === \"namespace_import\") {\n const nameNode = clause.namedChildren.find(\n (c: TreeSitterNode) => c.type === \"identifier\",\n );\n if (nameNode) specifiers.push(`* as ${nameNode.text}`);\n }\n }\n }\n }\n\n return { specifiers, source, isTypeOnly };\n}\n\nfunction extractReExportSpecifiers(node: TreeSitterNode): string[] {\n const specifiers: string[] = [];\n for (const child of node.children) {\n if (child.type === \"export_clause\") {\n for (const spec of child.namedChildren) {\n if (spec.type === \"export_specifier\") {\n const nameNode = spec.childForFieldName(\"name\");\n if (nameNode) specifiers.push(nameNode.text);\n }\n }\n }\n }\n return specifiers;\n}\n\n/**\n * Find all identifier nodes in the AST that match any of the given names.\n * Used to determine which symbols in a file actually reference imported names.\n */\nexport function findIdentifierUsages(source: string, names: Set<string>): IdentifierUsage[] {\n if (names.size === 0) return [];\n\n const p = getParser();\n const tree = p.parse(source);\n const root: TreeSitterNode = tree.rootNode;\n const usages: IdentifierUsage[] = [];\n\n function walk(node: TreeSitterNode): void {\n if (\n (node.type === \"identifier\" || node.type === \"type_identifier\") &&\n names.has(node.text)\n ) {\n // Skip identifiers that are part of import/export declarations\n let parent = node.parent;\n let isImportExport = false;\n while (parent) {\n if (\n parent.type === \"import_statement\" ||\n parent.type === \"import_clause\" ||\n parent.type === \"import_specifier\" ||\n (parent.type === \"export_statement\" &&\n parent.children.some((c: TreeSitterNode) => c.type === \"from\"))\n ) {\n isImportExport = true;\n break;\n }\n parent = parent.parent;\n }\n if (!isImportExport) {\n usages.push({\n name: node.text,\n line: node.startPosition.row + 1,\n column: node.startPosition.column,\n });\n }\n }\n for (const child of node.children) {\n walk(child);\n }\n }\n\n walk(root);\n return usages;\n}\n\n/**\n * Walk the full AST to find dynamic import() calls and extract them as imports.\n * Handles patterns like:\n * const { foo } = await import('./module.js')\n * import('./module.js').then(m => ...)\n */\nfunction extractDynamicImports(root: TreeSitterNode): ImportDef[] {\n const imports: ImportDef[] = [];\n\n function walk(node: TreeSitterNode): void {\n if (node.type === \"call_expression\") {\n // Check if this is an import() call — first child is the `import` keyword\n const fn = node.child(0);\n if (fn && fn.type === \"import\") {\n const argsNode = node.childForFieldName(\"arguments\");\n if (argsNode) {\n // Extract the module path from the first string argument\n const strArg = argsNode.namedChildren.find(\n (c: TreeSitterNode) => c.type === \"string\",\n );\n if (strArg) {\n const modulePath = strArg.text.replace(/^['\"]|['\"]$/g, \"\");\n const specifiers = extractDynamicImportSpecifiers(node);\n imports.push({ specifiers, source: modulePath, isTypeOnly: false });\n }\n }\n // Don't walk into the import() call's children\n return;\n }\n }\n for (const child of node.children) {\n walk(child);\n }\n }\n\n walk(root);\n return imports;\n}\n\n/**\n * Try to extract destructured specifiers from the context around a\n * dynamic import() call_expression, e.g.:\n * const { runIndex } = await import('./commands/index.js')\n * ^^^^^^^^^^^^ these specifiers\n */\nfunction extractDynamicImportSpecifiers(importCall: TreeSitterNode): string[] {\n // Walk up: import() → await_expression → variable_declarator\n let current: TreeSitterNode | null = importCall.parent;\n\n // Skip await_expression wrapper if present\n if (current && current.type === \"await_expression\") {\n current = current.parent;\n }\n\n if (current && current.type === \"variable_declarator\") {\n const pattern = current.childForFieldName(\"name\");\n if (pattern && pattern.type === \"object_pattern\") {\n const specs: string[] = [];\n for (const child of pattern.namedChildren) {\n if (child.type === \"shorthand_property_identifier_pattern\") {\n specs.push(child.text);\n } else if (child.type === \"pair_pattern\") {\n // { original: alias } destructuring — use the alias\n const value = child.childForFieldName(\"value\");\n if (value) specs.push(value.text);\n }\n }\n return specs;\n }\n }\n\n return [];\n}\n\nexport function parseSource(source: string): ParseResult {\n const p = getParser();\n const tree = p.parse(source);\n const root: TreeSitterNode = tree.rootNode;\n\n const symbols: SymbolDef[] = [];\n const imports: ImportDef[] = [];\n\n for (const node of root.namedChildren) {\n if (node.type === \"import_statement\") {\n const imp = extractImport(node);\n if (imp) imports.push(imp);\n continue;\n }\n\n if (node.type === \"export_statement\") {\n // Re-export: export { X } from './foo'\n const hasFrom = node.children.some(\n (c: TreeSitterNode) => c.type === \"from\",\n );\n if (hasFrom) {\n // Treat re-exports as imports from the source module\n let sourceNode: TreeSitterNode | null = null;\n for (const child of node.children) {\n if (child.type === \"string\") {\n sourceNode = child;\n break;\n }\n }\n if (sourceNode) {\n const rawSource = sourceNode.text;\n const source = rawSource.replace(/^['\"]|['\"]$/g, \"\");\n const specifiers = extractReExportSpecifiers(node);\n const isTypeOnly = node.children.some(\n (c: TreeSitterNode) => c.type === \"type\" && c.text === \"type\",\n );\n imports.push({ specifiers, source, isTypeOnly });\n }\n continue;\n }\n\n // Exported declaration: export function foo() {}\n for (const child of node.namedChildren) {\n const decl = extractDeclaration(child, source, true);\n if (decl) {\n symbols.push(decl);\n if (child.type === \"class_declaration\") {\n symbols.push(...extractMethods(child, source, true));\n }\n }\n\n if (\n child.type === \"lexical_declaration\" ||\n child.type === \"variable_declaration\"\n ) {\n symbols.push(...extractVariableDeclarations(child, true));\n }\n }\n continue;\n }\n\n // Top-level declarations (not exported)\n const decl = extractDeclaration(node, source, false);\n if (decl) {\n symbols.push(decl);\n if (node.type === \"class_declaration\") {\n symbols.push(...extractMethods(node, source, false));\n }\n }\n\n if (\n node.type === \"lexical_declaration\" ||\n node.type === \"variable_declaration\"\n ) {\n symbols.push(...extractVariableDeclarations(node, false));\n }\n }\n\n // Extract dynamic import() calls from the full AST\n imports.push(...extractDynamicImports(root));\n\n return { symbols, imports };\n}\n"],"mappings":"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","names":["createRequire","require","source","decl","require","createRequire"]}
|