scip-query 0.2.1 → 0.3.2

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.
Files changed (131) hide show
  1. package/dist/chunk-26DOJ63W.js +161 -0
  2. package/dist/{chunk-PMJKOXOT.js → chunk-4JCSOF2O.js} +2 -2
  3. package/dist/{chunk-AKMBBKWV.js → chunk-5OMVSV6E.js} +12 -4
  4. package/dist/{chunk-R56FJU3E.js → chunk-7KIMF5PV.js} +2 -2
  5. package/dist/chunk-AXQKUYKF.js +1442 -0
  6. package/dist/chunk-C7H5WBTJ.js +46 -0
  7. package/dist/{chunk-AMNISGYR.js → chunk-CHDJXYBG.js} +2 -27
  8. package/dist/{chunk-GPJVPT3U.js → chunk-CPVAQJEC.js} +12 -4
  9. package/dist/{chunk-75RQSBTK.js → chunk-DH7G3DDV.js} +2 -2
  10. package/dist/{chunk-LTJC5ZQL.js → chunk-EOROMIFO.js} +13 -5
  11. package/dist/{chunk-BFLULBEU.js → chunk-EPWLXXBL.js} +2 -2
  12. package/dist/{chunk-MVH45PYK.js → chunk-FYYOWQXK.js} +12 -12
  13. package/dist/chunk-GEXE2T6I.js +87 -0
  14. package/dist/{chunk-IXPHLF6K.js → chunk-GJDHTTR2.js} +10 -3
  15. package/dist/chunk-GSH2FPKV.js +87 -0
  16. package/dist/{chunk-4ACRRQC4.js → chunk-HJZUSUPU.js} +2 -2
  17. package/dist/{chunk-M3NPW3FC.js → chunk-HLKAFWWJ.js} +81 -2
  18. package/dist/{chunk-CU62ZDHI.js → chunk-HLUS2HEB.js} +2 -2
  19. package/dist/{chunk-RFMT7UAZ.js → chunk-J3JSOSUO.js} +8 -5
  20. package/dist/{chunk-HDSRORNV.js → chunk-KKCHYLVI.js} +17 -11
  21. package/dist/{chunk-Y3M323OX.js → chunk-LFJQVJYJ.js} +2 -2
  22. package/dist/{chunk-6WVR5K46.js → chunk-LQJUPXQY.js} +3 -3
  23. package/dist/{chunk-ITZ3DDOG.js → chunk-MPGIHELS.js} +18 -3
  24. package/dist/{chunk-N4C3H7LH.js → chunk-NFS5W3PP.js} +2 -2
  25. package/dist/{chunk-Y4JFVQ7C.js → chunk-O7Q7FDUJ.js} +21 -13
  26. package/dist/{chunk-H6WCPKCX.js → chunk-OIDHN6GD.js} +2 -2
  27. package/dist/{chunk-4BQFSNFI.js → chunk-P3E6L7KW.js} +2 -2
  28. package/dist/{chunk-ORINICIZ.js → chunk-P4WO3BBW.js} +2 -2
  29. package/dist/{chunk-M4QGEKKD.js → chunk-SMDCNPMK.js} +8 -3
  30. package/dist/{chunk-6QSHLFSL.js → chunk-UGQKAVCD.js} +2 -2
  31. package/dist/{chunk-HMYJJ3HY.js → chunk-UQEQ6AHX.js} +3 -3
  32. package/dist/{chunk-WVK7AASK.js → chunk-VIYSWZCO.js} +2 -2
  33. package/dist/chunk-VJJKSGIX.js +121 -0
  34. package/dist/{chunk-N5KEREIA.js → chunk-VT4JBH6L.js} +19 -7
  35. package/dist/{chunk-R2I3M5B4.js → chunk-WGAD3GNR.js} +2 -2
  36. package/dist/{chunk-IJKLB2JW.js → chunk-YDBXNPYU.js} +2 -2
  37. package/dist/{chunk-VO4QI3LS.js → chunk-YY4QGUQ5.js} +2 -2
  38. package/dist/{chunk-3566TKJ5.js → chunk-ZEUCXQBN.js} +2 -2
  39. package/dist/cli.js +2314 -1352
  40. package/dist/{db-BHYam4BK.d.ts → db-ShvwGDKf.d.ts} +6 -1
  41. package/dist/index.d.ts +2 -2
  42. package/dist/index.js +38 -38
  43. package/dist/queries/affected.d.ts +1 -1
  44. package/dist/queries/affected.js +2 -2
  45. package/dist/queries/bottlenecks.d.ts +1 -1
  46. package/dist/queries/by-kind.d.ts +1 -1
  47. package/dist/queries/by-kind.js +1 -1
  48. package/dist/queries/call-graph.d.ts +1 -1
  49. package/dist/queries/call-graph.js +2 -2
  50. package/dist/queries/change-surface.d.ts +1 -1
  51. package/dist/queries/change-surface.js +2 -1
  52. package/dist/queries/code.d.ts +1 -1
  53. package/dist/queries/code.js +2 -2
  54. package/dist/queries/complexity-hotspots.d.ts +1 -1
  55. package/dist/queries/complexity-hotspots.js +2 -2
  56. package/dist/queries/complexity.d.ts +1 -1
  57. package/dist/queries/complexity.js +2 -2
  58. package/dist/queries/convergence.d.ts +1 -1
  59. package/dist/queries/convergence.js +2 -2
  60. package/dist/queries/coupling.d.ts +1 -1
  61. package/dist/queries/coupling.js +3 -1
  62. package/dist/queries/cycles.d.ts +1 -1
  63. package/dist/queries/cycles.js +2 -2
  64. package/dist/queries/dataflow.d.ts +1 -1
  65. package/dist/queries/dataflow.js +2 -2
  66. package/dist/queries/dead.d.ts +1 -1
  67. package/dist/queries/dead.js +3 -3
  68. package/dist/queries/deep-chains.d.ts +1 -1
  69. package/dist/queries/deep-chains.js +2 -2
  70. package/dist/queries/deps.d.ts +1 -1
  71. package/dist/queries/deps.js +3 -1
  72. package/dist/queries/diff-impact.d.ts +1 -1
  73. package/dist/queries/doc-coverage.d.ts +1 -1
  74. package/dist/queries/drift.d.ts +1 -1
  75. package/dist/queries/drift.js +2 -2
  76. package/dist/queries/extract-candidates.d.ts +1 -1
  77. package/dist/queries/extract-candidates.js +2 -2
  78. package/dist/queries/fan.d.ts +1 -1
  79. package/dist/queries/fan.js +2 -1
  80. package/dist/queries/files.d.ts +1 -1
  81. package/dist/queries/health.d.ts +1 -1
  82. package/dist/queries/health.js +13 -13
  83. package/dist/queries/hierarchy.d.ts +1 -1
  84. package/dist/queries/hierarchy.js +2 -2
  85. package/dist/queries/hotspots.d.ts +1 -1
  86. package/dist/queries/imports.d.ts +1 -1
  87. package/dist/queries/imports.js +2 -2
  88. package/dist/queries/index.d.ts +1 -1
  89. package/dist/queries/index.js +38 -38
  90. package/dist/queries/isolated.d.ts +1 -1
  91. package/dist/queries/isolated.js +3 -3
  92. package/dist/queries/members.d.ts +1 -1
  93. package/dist/queries/members.js +2 -2
  94. package/dist/queries/methods.d.ts +1 -1
  95. package/dist/queries/outline.d.ts +1 -1
  96. package/dist/queries/outline.js +2 -1
  97. package/dist/queries/passthrough-candidates.d.ts +1 -1
  98. package/dist/queries/passthrough-candidates.js +2 -2
  99. package/dist/queries/redundant-reexports.d.ts +1 -1
  100. package/dist/queries/redundant-reexports.js +3 -3
  101. package/dist/queries/refs.d.ts +1 -1
  102. package/dist/queries/refs.js +3 -1
  103. package/dist/queries/similar-chains.d.ts +1 -1
  104. package/dist/queries/similar-chains.js +2 -2
  105. package/dist/queries/similar-files.d.ts +1 -1
  106. package/dist/queries/similar-files.js +2 -2
  107. package/dist/queries/similar-signatures.d.ts +1 -1
  108. package/dist/queries/similar.d.ts +1 -1
  109. package/dist/queries/similar.js +2 -2
  110. package/dist/queries/slice.d.ts +2 -2
  111. package/dist/queries/slice.js +2 -2
  112. package/dist/queries/stale-abstractions.d.ts +1 -1
  113. package/dist/queries/stale-abstractions.js +2 -2
  114. package/dist/queries/stats.d.ts +1 -1
  115. package/dist/queries/surface.d.ts +1 -1
  116. package/dist/queries/surface.js +2 -1
  117. package/dist/queries/symbols.d.ts +1 -1
  118. package/dist/queries/symbols.js +2 -1
  119. package/dist/queries/system.d.ts +1 -1
  120. package/dist/queries/system.js +2 -1
  121. package/dist/queries/trace.d.ts +1 -1
  122. package/dist/queries/trace.js +2 -2
  123. package/dist/queries/wrapper-candidates.d.ts +1 -1
  124. package/dist/queries/wrapper-candidates.js +2 -2
  125. package/package.json +1 -1
  126. package/dist/chunk-34JPTNRN.js +0 -601
  127. package/dist/chunk-7JFZSOJ7.js +0 -103
  128. package/dist/chunk-DY4AFG2W.js +0 -48
  129. package/dist/chunk-LLMPAG56.js +0 -221
  130. package/dist/chunk-NVIIM34O.js +0 -65
  131. package/dist/chunk-YAFWL3RA.js +0 -55
@@ -1,601 +0,0 @@
1
- import {
2
- findFirstSymbolMatch
3
- } from "./chunk-LLMPAG56.js";
4
- import {
5
- isModuleLikeSymbol,
6
- leafName,
7
- shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
9
-
10
- // src/source-analysis.ts
11
- import {
12
- existsSync,
13
- readFileSync
14
- } from "fs";
15
- import {
16
- dirname,
17
- extname,
18
- join,
19
- relative,
20
- resolve
21
- } from "path";
22
- var SOURCE_IMPORT_CACHE = /* @__PURE__ */ new WeakMap();
23
- var INDEXED_PATH_CACHE = /* @__PURE__ */ new WeakMap();
24
- var SOURCE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
25
- var PYTHON_SOURCE_EXTENSIONS = [".py", ".pyi"];
26
- function getSourceImports(db, relativePath) {
27
- const cache = getCachedMap(SOURCE_IMPORT_CACHE, db);
28
- const normalized = normalizePath(relativePath);
29
- const cached = cache.get(normalized);
30
- if (cached) {
31
- return cached;
32
- }
33
- const fullPath = join(db.config.projectRoot, normalized);
34
- if (!existsSync(fullPath)) {
35
- cache.set(normalized, []);
36
- return [];
37
- }
38
- const source = readFileSync(fullPath, "utf-8");
39
- const parsed = isPythonSourcePath(normalized) ? parsePythonImports(db, normalized, source) : parseJavaScriptImports(db, normalized, source);
40
- cache.set(normalized, parsed);
41
- return parsed;
42
- }
43
- function parseJavaScriptImports(db, importerPath, source) {
44
- return parseJavaScriptImportStatements(source).flatMap((statement) => parseJavaScriptImportStatement(
45
- db,
46
- importerPath,
47
- statement.clause,
48
- statement.specifier,
49
- statement.start,
50
- statement.end,
51
- source
52
- ));
53
- }
54
- function parseJavaScriptImportStatements(source) {
55
- const statements = [];
56
- const importFromRegex = /^[ \t]*import\s+([\s\S]*?)\s+from\s+['"]([^'"]+)['"]\s*;?/gm;
57
- for (const match of source.matchAll(importFromRegex)) {
58
- const full = match[0];
59
- const clause = match[1];
60
- const specifier = match[2];
61
- if (!full || !specifier || typeof match.index !== "number") continue;
62
- statements.push({
63
- clause,
64
- specifier,
65
- start: match.index,
66
- end: match.index + full.length
67
- });
68
- }
69
- const sideEffectRegex = /^[ \t]*import\s+['"]([^'"]+)['"]\s*;?/gm;
70
- for (const match of source.matchAll(sideEffectRegex)) {
71
- const full = match[0];
72
- const specifier = match[1];
73
- if (!full || !specifier || typeof match.index !== "number") continue;
74
- statements.push({
75
- clause: null,
76
- specifier,
77
- start: match.index,
78
- end: match.index + full.length
79
- });
80
- }
81
- return statements.sort((a, b) => a.start - b.start);
82
- }
83
- function parseJavaScriptImportStatement(db, importerPath, clause, specifier, start, end, source) {
84
- const resolvedSource = resolveImportPath(db, importerPath, specifier);
85
- const body = buildUsageBody(source, start, end);
86
- if (!clause) {
87
- return [{
88
- importedName: "*",
89
- localName: null,
90
- sourcePath: resolvedSource,
91
- kind: "side-effect",
92
- used: true,
93
- usedMembers: []
94
- }];
95
- }
96
- const bindings = parseImportClause(clause).map((binding) => ({
97
- ...binding,
98
- sourcePath: resolvedSource
99
- }));
100
- return bindings.map((binding) => {
101
- if (binding.kind === "namespace") {
102
- const usedMembers = collectNamespaceMembers(body, binding.localName);
103
- return {
104
- ...binding,
105
- used: usedMembers.length > 0 || hasIdentifierUsage(body, binding.localName),
106
- usedMembers
107
- };
108
- }
109
- if (binding.kind === "side-effect") {
110
- return { ...binding, used: true, usedMembers: [] };
111
- }
112
- return {
113
- ...binding,
114
- used: binding.localName ? hasIdentifierUsage(body, binding.localName) : false,
115
- usedMembers: []
116
- };
117
- });
118
- }
119
- function parsePythonImports(db, importerPath, source) {
120
- return collectPythonImportStatements(source).flatMap(
121
- (statement) => parsePythonImportStatement(db, importerPath, statement, source)
122
- );
123
- }
124
- function collectPythonImportStatements(source) {
125
- const lines = source.split("\n");
126
- const statements = [];
127
- let offset = 0;
128
- for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
129
- const line = lines[lineIndex];
130
- const trimmed = line.trimStart();
131
- const lineStart = offset;
132
- offset += line.length + 1;
133
- if (!trimmed.startsWith("import ") && !trimmed.startsWith("from ")) {
134
- continue;
135
- }
136
- let statement = line;
137
- let statementEnd = lineStart + line.length;
138
- let balance = pythonParenBalance(line);
139
- while (lineIndex + 1 < lines.length && (balance > 0 || statement.trimEnd().endsWith("\\"))) {
140
- lineIndex++;
141
- const nextLine = lines[lineIndex];
142
- statement += `
143
- ${nextLine}`;
144
- statementEnd += 1 + nextLine.length;
145
- balance += pythonParenBalance(nextLine);
146
- offset += nextLine.length + 1;
147
- }
148
- const parsed = parsePythonStatementHeader(statement);
149
- if (parsed) {
150
- statements.push({
151
- ...parsed,
152
- start: lineStart,
153
- end: statementEnd
154
- });
155
- }
156
- }
157
- return statements;
158
- }
159
- function parsePythonStatementHeader(statement) {
160
- const normalized = statement.replace(/\\\s*\n/g, " ").trim();
161
- if (normalized.startsWith("import ")) {
162
- return {
163
- kind: "import",
164
- module: null,
165
- clause: normalized.slice("import ".length).trim()
166
- };
167
- }
168
- const fromMatch = normalized.match(/^from\s+([.\w]+)\s+import\s+([\s\S]+)$/);
169
- if (!fromMatch) {
170
- return null;
171
- }
172
- let clause = fromMatch[2].trim();
173
- if (clause.startsWith("(") && clause.endsWith(")")) {
174
- clause = clause.slice(1, -1).trim();
175
- }
176
- return {
177
- kind: "from",
178
- module: fromMatch[1],
179
- clause
180
- };
181
- }
182
- function parsePythonImportStatement(db, importerPath, statement, source) {
183
- const body = buildUsageBody(source, statement.start, statement.end);
184
- const normalizedClause = statement.clause.replace(/\n/g, " ").trim();
185
- if (statement.kind === "import") {
186
- return splitTopLevel(normalizedClause).flatMap((entry) => {
187
- const cleaned = entry.trim().replace(/,$/, "");
188
- if (!cleaned) return [];
189
- const [moduleName, alias] = cleaned.split(/\s+as\s+/);
190
- const importedName = moduleName.trim();
191
- const localName = (alias ?? importedName.split(".")[0] ?? importedName).trim();
192
- const sourcePath2 = resolvePythonImportPath(db, importerPath, importedName);
193
- const usedMembers = collectNamespaceMembers(body, localName);
194
- return [{
195
- importedName,
196
- localName,
197
- sourcePath: sourcePath2,
198
- kind: "namespace",
199
- used: hasIdentifierUsage(body, localName) || usedMembers.length > 0,
200
- usedMembers
201
- }];
202
- });
203
- }
204
- const sourcePath = statement.module ? resolvePythonImportPath(db, importerPath, statement.module) : null;
205
- const results = [];
206
- for (const entry of splitTopLevel(normalizedClause)) {
207
- const cleaned = entry.trim().replace(/,$/, "");
208
- if (!cleaned) continue;
209
- if (cleaned === "*") {
210
- results.push({
211
- importedName: "*",
212
- localName: null,
213
- sourcePath,
214
- kind: "side-effect",
215
- used: true,
216
- usedMembers: []
217
- });
218
- continue;
219
- }
220
- const [importedName, alias] = cleaned.split(/\s+as\s+/);
221
- const localName = (alias ?? importedName).trim();
222
- results.push({
223
- importedName: importedName.trim(),
224
- localName,
225
- sourcePath,
226
- kind: "named",
227
- used: hasIdentifierUsage(body, localName),
228
- usedMembers: []
229
- });
230
- }
231
- return results;
232
- }
233
- function parseImportClause(clause) {
234
- const trimmed = clause.trim().replace(/^type\s+/, "");
235
- const [first, second] = splitImportClause(trimmed);
236
- const entries = [];
237
- if (first) {
238
- entries.push(...parseImportBinding(first));
239
- }
240
- if (second) {
241
- entries.push(...parseImportBinding(second));
242
- }
243
- return entries;
244
- }
245
- function parseImportBinding(binding) {
246
- const trimmed = binding.trim();
247
- if (!trimmed) return [];
248
- if (trimmed.startsWith("{")) {
249
- const inner = trimmed.slice(1, -1).trim();
250
- if (!inner) return [];
251
- return splitTopLevel(inner).map((entry) => {
252
- const cleaned = entry.trim().replace(/^type\s+/, "");
253
- const [importedName, alias] = cleaned.split(/\s+as\s+/);
254
- return {
255
- importedName: importedName.trim(),
256
- localName: (alias ?? importedName).trim(),
257
- kind: "named"
258
- };
259
- });
260
- }
261
- if (trimmed.startsWith("* as ")) {
262
- return [{
263
- importedName: "*",
264
- localName: trimmed.slice(5).trim(),
265
- kind: "namespace"
266
- }];
267
- }
268
- return [{
269
- importedName: "default",
270
- localName: trimmed,
271
- kind: "default"
272
- }];
273
- }
274
- function splitImportClause(clause) {
275
- let depth = 0;
276
- for (let i = 0; i < clause.length; i++) {
277
- const char = clause[i];
278
- if (char === "{") depth++;
279
- if (char === "}") depth--;
280
- if (char === "," && depth === 0) {
281
- return [clause.slice(0, i).trim(), clause.slice(i + 1).trim()];
282
- }
283
- }
284
- return [clause.trim(), null];
285
- }
286
- function splitTopLevel(input) {
287
- const parts = [];
288
- let depth = 0;
289
- let start = 0;
290
- for (let i = 0; i < input.length; i++) {
291
- const char = input[i];
292
- if (char === "{" || char === "[" || char === "(") depth++;
293
- if (char === "}" || char === "]" || char === ")") depth--;
294
- if (char === "," && depth === 0) {
295
- parts.push(input.slice(start, i));
296
- start = i + 1;
297
- }
298
- }
299
- parts.push(input.slice(start));
300
- return parts;
301
- }
302
- function buildUsageBody(source, start, end) {
303
- const masked = `${source.slice(0, start)}${" ".repeat(end - start)}${source.slice(end)}`;
304
- return stripCommentsAndStrings(masked);
305
- }
306
- function stripCommentsAndStrings(source) {
307
- return source.replace(/'''[\s\S]*?'''/g, " ").replace(/"""[\s\S]*?"""/g, " ").replace(/#.*$/gm, " ").replace(/\/\/.*$/gm, " ").replace(/\/\*[\s\S]*?\*\//g, " ").replace(/`(?:\\[\s\S]|[^`])*`/g, " ").replace(/'(?:\\.|[^'\\\r\n])*'/g, " ").replace(/"(?:\\.|[^"\\\r\n])*"/g, " ");
308
- }
309
- function hasIdentifierUsage(body, identifier) {
310
- return new RegExp(`\\b${escapeRegex(identifier)}\\b`, "m").test(body);
311
- }
312
- function collectNamespaceMembers(body, namespaceName) {
313
- const members = /* @__PURE__ */ new Set();
314
- const regex = new RegExp(`\\b${escapeRegex(namespaceName)}\\s*\\.\\s*([A-Za-z_$][\\w$]*)`, "g");
315
- for (const match of body.matchAll(regex)) {
316
- const member = match[1];
317
- if (member) {
318
- members.add(member);
319
- }
320
- }
321
- return [...members];
322
- }
323
- function resolveImportPath(db, importerPath, specifier) {
324
- if (isPythonSourcePath(importerPath)) {
325
- return resolvePythonImportPath(db, importerPath, specifier);
326
- }
327
- return resolveJavaScriptImportPath(db, importerPath, specifier);
328
- }
329
- function resolveJavaScriptImportPath(db, importerPath, specifier) {
330
- if (!specifier.startsWith(".") && !specifier.startsWith("/")) {
331
- return null;
332
- }
333
- const importerDir = dirname(join(db.config.projectRoot, importerPath));
334
- const absolute = resolve(importerDir, specifier);
335
- const indexedPaths = getIndexedPaths(db);
336
- for (const candidate of candidateImportPaths(absolute)) {
337
- const relativeCandidate = normalizePath(relative(db.config.projectRoot, candidate));
338
- if (indexedPaths.has(relativeCandidate) || existsSync(candidate)) {
339
- return relativeCandidate;
340
- }
341
- }
342
- return normalizePath(relative(db.config.projectRoot, absolute));
343
- }
344
- function resolvePythonImportPath(db, importerPath, specifier) {
345
- const indexedPaths = getIndexedPaths(db);
346
- let basePath;
347
- if (specifier.startsWith(".")) {
348
- const match = specifier.match(/^(\.+)(.*)$/);
349
- if (!match) return null;
350
- const dots = match[1].length;
351
- const remainder = match[2].replace(/^\./, "");
352
- let baseDir = dirname(join(db.config.projectRoot, importerPath));
353
- for (let i = 1; i < dots; i++) {
354
- baseDir = dirname(baseDir);
355
- }
356
- basePath = remainder ? resolve(baseDir, remainder.replace(/\./g, "/")) : baseDir;
357
- } else {
358
- basePath = resolve(db.config.projectRoot, specifier.replace(/\./g, "/"));
359
- }
360
- for (const candidate of pythonCandidateImportPaths(basePath)) {
361
- const relativeCandidate = normalizePath(relative(db.config.projectRoot, candidate));
362
- if (indexedPaths.has(relativeCandidate) || existsSync(candidate)) {
363
- return relativeCandidate;
364
- }
365
- }
366
- return null;
367
- }
368
- function pythonCandidateImportPaths(basePath) {
369
- const ext = extname(basePath);
370
- if (PYTHON_SOURCE_EXTENSIONS.includes(ext)) {
371
- return [basePath];
372
- }
373
- return [
374
- `${basePath}.py`,
375
- `${basePath}.pyi`,
376
- join(basePath, "__init__.py"),
377
- join(basePath, "__init__.pyi")
378
- ];
379
- }
380
- function candidateImportPaths(absolute) {
381
- const ext = extname(absolute);
382
- const candidates = /* @__PURE__ */ new Set();
383
- if (ext) {
384
- candidates.add(absolute);
385
- for (const sourceExt of SOURCE_EXTENSIONS) {
386
- candidates.add(absolute.slice(0, -ext.length) + sourceExt);
387
- }
388
- } else {
389
- for (const sourceExt of SOURCE_EXTENSIONS) {
390
- candidates.add(`${absolute}${sourceExt}`);
391
- candidates.add(join(absolute, `index${sourceExt}`));
392
- }
393
- }
394
- return [...candidates];
395
- }
396
- function getIndexedPaths(db) {
397
- const cached = INDEXED_PATH_CACHE.get(db);
398
- if (cached) {
399
- return cached;
400
- }
401
- const paths = new Set(
402
- db.all(
403
- `SELECT relative_path
404
- FROM documents
405
- WHERE 1 = 1
406
- ${db.pathExclusionsFor("documents")}`
407
- ).map((row) => normalizePath(row.relative_path)).filter((relativePath) => !db.isIgnored(relativePath))
408
- );
409
- INDEXED_PATH_CACHE.set(db, paths);
410
- return paths;
411
- }
412
- function getCachedMap(cache, db) {
413
- let map = cache.get(db);
414
- if (!map) {
415
- map = /* @__PURE__ */ new Map();
416
- cache.set(db, map);
417
- }
418
- return map;
419
- }
420
- function normalizePath(path) {
421
- return path.replace(/\\/g, "/");
422
- }
423
- function isPythonSourcePath(relativePath) {
424
- return PYTHON_SOURCE_EXTENSIONS.includes(extname(relativePath).toLowerCase());
425
- }
426
- function pythonParenBalance(value) {
427
- let balance = 0;
428
- for (const char of value) {
429
- if (char === "(") balance++;
430
- if (char === ")") balance--;
431
- }
432
- return balance;
433
- }
434
- function escapeRegex(value) {
435
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
436
- }
437
-
438
- // src/queries/imports.ts
439
- function imports(db, filePattern) {
440
- const rows = db.all(
441
- `SELECT DISTINCT gs.symbol, def_d.relative_path AS from_file, imp_d.relative_path AS importer
442
- FROM mentions m
443
- JOIN chunks c ON m.chunk_id = c.id
444
- JOIN documents imp_d ON c.document_id = imp_d.id
445
- JOIN global_symbols gs ON m.symbol_id = gs.id
446
- LEFT JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
447
- LEFT JOIN documents def_d ON der.document_id = def_d.id
448
- WHERE imp_d.relative_path LIKE ?
449
- AND m.role = 2
450
- ORDER BY def_d.relative_path, gs.symbol`,
451
- `%${filePattern}%`
452
- );
453
- const indexedResults = rows.filter((row) => !db.isIgnored(row.importer)).map((r) => ({
454
- symbol: r.symbol,
455
- shortName: shortenSymbol(r.symbol),
456
- fromFile: r.from_file ?? "(external)"
457
- }));
458
- if (indexedResults.length > 0) {
459
- return indexedResults;
460
- }
461
- const importer = findIndexedFile(db, filePattern);
462
- if (!importer) return [];
463
- return getSourceImports(db, importer).map((entry) => ({
464
- symbol: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
465
- shortName: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
466
- fromFile: entry.sourcePath ?? "(external)"
467
- }));
468
- }
469
- function importedBy(db, symbolPattern) {
470
- const rows = db.all(
471
- `SELECT DISTINCT gs.symbol, d.relative_path AS importer
472
- FROM mentions m
473
- JOIN chunks c ON m.chunk_id = c.id
474
- JOIN documents d ON c.document_id = d.id
475
- JOIN global_symbols gs ON m.symbol_id = gs.id
476
- WHERE gs.symbol LIKE ?
477
- AND m.role = 2
478
- ORDER BY d.relative_path`,
479
- `%${symbolPattern}%`
480
- );
481
- const indexedResults = rows.filter((r) => !db.isIgnored(r.importer)).map((r) => ({
482
- symbol: r.symbol,
483
- shortName: shortenSymbol(r.symbol),
484
- fromFile: r.importer
485
- }));
486
- if (indexedResults.length > 0) {
487
- return indexedResults;
488
- }
489
- const target = findFirstSymbolMatch(db, symbolPattern);
490
- const targetFile = target?.relativePath ?? null;
491
- const targetLeaf = target ? leafName(target.symbol) : symbolPattern.replace(/\(\)$/, "");
492
- const targetIsModule = target ? isModuleLikeSymbol(target.symbol) : false;
493
- const files = db.all(
494
- `SELECT relative_path
495
- FROM documents
496
- WHERE 1 = 1
497
- ${db.pathExclusionsFor("documents")}
498
- ORDER BY relative_path`
499
- );
500
- const importers = /* @__PURE__ */ new Set();
501
- for (const row of files) {
502
- if (db.isIgnored(row.relative_path)) continue;
503
- for (const entry of getSourceImports(db, row.relative_path)) {
504
- if (!entry.sourcePath) continue;
505
- if (targetFile && normalizePath2(entry.sourcePath) !== normalizePath2(targetFile)) {
506
- continue;
507
- }
508
- if (targetIsModule) {
509
- importers.add(row.relative_path);
510
- continue;
511
- }
512
- if (entry.kind === "named" && entry.importedName === targetLeaf) {
513
- importers.add(row.relative_path);
514
- continue;
515
- }
516
- if (entry.kind === "namespace" && entry.usedMembers.includes(targetLeaf)) {
517
- importers.add(row.relative_path);
518
- }
519
- }
520
- }
521
- return [...importers].sort().map((importer) => ({
522
- symbol: target?.symbol ?? targetLeaf,
523
- shortName: target ? shortenSymbol(target.symbol) : targetLeaf,
524
- fromFile: importer
525
- }));
526
- }
527
- function unusedImports(db, filePattern) {
528
- const rows = db.all(
529
- `SELECT gs.symbol, d.relative_path AS imported_in, d.relative_path AS importer
530
- FROM mentions m
531
- JOIN chunks c ON m.chunk_id = c.id
532
- JOIN documents d ON c.document_id = d.id
533
- JOIN global_symbols gs ON m.symbol_id = gs.id
534
- WHERE d.relative_path LIKE ?
535
- AND m.role = 2
536
- AND NOT EXISTS (
537
- SELECT 1
538
- FROM mentions ref_m
539
- JOIN chunks ref_c ON ref_m.chunk_id = ref_c.id
540
- WHERE ref_m.symbol_id = gs.id
541
- AND ref_m.role != 1
542
- AND ref_c.document_id = d.id
543
- )
544
- ORDER BY d.relative_path, gs.symbol`,
545
- `%${filePattern}%`
546
- );
547
- const indexedResults = rows.filter((row) => !db.isIgnored(row.importer)).map((r) => ({
548
- symbol: r.symbol,
549
- shortName: shortenSymbol(r.symbol),
550
- importedIn: r.imported_in
551
- }));
552
- if (indexedResults.length > 0) {
553
- return indexedResults;
554
- }
555
- const importer = findIndexedFile(db, filePattern);
556
- if (!importer) return [];
557
- return getSourceImports(db, importer).filter((entry) => entry.kind !== "side-effect" && !entry.used).map((entry) => ({
558
- symbol: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
559
- shortName: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
560
- importedIn: importer
561
- }));
562
- }
563
- function findIndexedFile(db, filePattern) {
564
- const doc = db.get(
565
- `SELECT relative_path
566
- FROM documents
567
- WHERE relative_path LIKE ?
568
- ${db.pathExclusionsFor("documents")}
569
- LIMIT 1`,
570
- `%${filePattern}%`
571
- );
572
- if (!doc || db.isIgnored(doc.relative_path)) {
573
- return null;
574
- }
575
- return doc.relative_path;
576
- }
577
- function renderImportSymbol(importedName, localName, kind) {
578
- if (kind === "namespace" && importedName === "*" && localName) {
579
- return `* as ${localName}`;
580
- }
581
- if (kind === "default" && localName) {
582
- return `default as ${localName}`;
583
- }
584
- if (kind === "side-effect") {
585
- return "(side effect import)";
586
- }
587
- if (localName && localName !== importedName) {
588
- return `${importedName} as ${localName}`;
589
- }
590
- return importedName;
591
- }
592
- function normalizePath2(path) {
593
- return path.replace(/\\/g, "/");
594
- }
595
-
596
- export {
597
- imports,
598
- importedBy,
599
- unusedImports
600
- };
601
- //# sourceMappingURL=chunk-34JPTNRN.js.map
@@ -1,103 +0,0 @@
1
- import {
2
- findFirstSymbolMatch
3
- } from "./chunk-LLMPAG56.js";
4
- import {
5
- shortenSymbol
6
- } from "./chunk-QIXNAB5K.js";
7
-
8
- // src/queries/dataflow.ts
9
- function dataflow(db, symbolPattern) {
10
- const match = findFirstSymbolMatch(db, symbolPattern);
11
- if (!match) return null;
12
- const defSites = db.all(
13
- `SELECT d.relative_path AS file, c.start_line AS line
14
- FROM mentions m
15
- JOIN chunks c ON m.chunk_id = c.id
16
- JOIN documents d ON c.document_id = d.id
17
- WHERE m.symbol_id = ? AND m.role = 1
18
- ORDER BY d.relative_path, c.start_line`,
19
- match.symbolId
20
- );
21
- const usageSites = db.all(
22
- `SELECT d.relative_path AS file, c.start_line AS line,
23
- (SELECT enc_gs.symbol
24
- FROM defn_enclosing_ranges enc_der
25
- JOIN global_symbols enc_gs ON enc_der.symbol_id = enc_gs.id
26
- WHERE enc_der.document_id = d.id
27
- AND enc_der.start_line <= c.start_line
28
- AND enc_der.end_line >= c.end_line
29
- ORDER BY (enc_der.end_line - enc_der.start_line) ASC
30
- LIMIT 1
31
- ) AS enclosing_symbol
32
- FROM mentions m
33
- JOIN chunks c ON m.chunk_id = c.id
34
- JOIN documents d ON c.document_id = d.id
35
- WHERE m.symbol_id = ? AND m.role != 1
36
- ${db.pathExclusionsFor("d")}
37
- ORDER BY d.relative_path, c.start_line`,
38
- match.symbolId
39
- );
40
- const producers = db.all(
41
- `SELECT DISTINCT other_gs.symbol, other_d.relative_path AS file
42
- FROM mentions other_m
43
- JOIN chunks other_c ON other_m.chunk_id = other_c.id
44
- JOIN global_symbols other_gs ON other_m.symbol_id = other_gs.id
45
- JOIN defn_enclosing_ranges other_der ON other_gs.id = other_der.symbol_id
46
- JOIN documents other_d ON other_der.document_id = other_d.id
47
- WHERE other_c.document_id = ?
48
- AND other_c.start_line >= ? AND other_c.end_line <= ?
49
- AND other_m.role != 1
50
- AND other_gs.id != ?
51
- ${db.symbolNoiseFor("other_gs")}
52
- ${db.pathExclusionsFor("other_d")}
53
- ORDER BY other_d.relative_path
54
- LIMIT 30`,
55
- match.documentId,
56
- match.startLine,
57
- match.endLine,
58
- match.symbolId
59
- );
60
- const consumers = db.all(
61
- `SELECT DISTINCT consumer_gs.symbol, consumer_d.relative_path AS file
62
- FROM mentions ref_m
63
- JOIN chunks ref_c ON ref_m.chunk_id = ref_c.id
64
- JOIN documents ref_d ON ref_c.document_id = ref_d.id
65
- -- Find the enclosing function at each usage site
66
- JOIN defn_enclosing_ranges enc_der
67
- ON enc_der.document_id = ref_d.id
68
- AND enc_der.start_line <= ref_c.start_line
69
- AND enc_der.end_line >= ref_c.end_line
70
- JOIN global_symbols enc_gs ON enc_der.symbol_id = enc_gs.id
71
- -- Find other symbols defined by that enclosing function's file
72
- JOIN mentions consumer_m ON consumer_m.symbol_id = enc_gs.id AND consumer_m.role != 1
73
- JOIN chunks consumer_c ON consumer_m.chunk_id = consumer_c.id
74
- JOIN documents consumer_d ON consumer_c.document_id = consumer_d.id
75
- JOIN global_symbols consumer_gs ON consumer_m.symbol_id = consumer_gs.id
76
- WHERE ref_m.symbol_id = ? AND ref_m.role != 1
77
- AND consumer_d.id != ref_d.id
78
- ${db.symbolNoiseFor("consumer_gs")}
79
- ${db.pathExclusionsFor("consumer_d")}
80
- ORDER BY consumer_d.relative_path
81
- LIMIT 30`,
82
- match.symbolId
83
- );
84
- return {
85
- symbol: match.symbol,
86
- shortName: shortenSymbol(match.symbol),
87
- relativePath: match.relativePath,
88
- definitionSites: defSites.filter((s) => !db.isIgnored(s.file)),
89
- usageSites: usageSites.filter((s) => !db.isIgnored(s.file)).map((s) => ({
90
- file: s.file,
91
- line: s.line,
92
- enclosingSymbol: s.enclosing_symbol ?? "(top-level)",
93
- enclosingShort: s.enclosing_symbol ? shortenSymbol(s.enclosing_symbol) : "(top-level)"
94
- })),
95
- producers: producers.filter((p) => !db.isIgnored(p.file)).map((p) => ({ symbol: p.symbol, shortName: shortenSymbol(p.symbol), file: p.file })),
96
- consumers: consumers.filter((c) => !db.isIgnored(c.file)).map((c) => ({ symbol: c.symbol, shortName: shortenSymbol(c.symbol), file: c.file }))
97
- };
98
- }
99
-
100
- export {
101
- dataflow
102
- };
103
- //# sourceMappingURL=chunk-7JFZSOJ7.js.map