scip-query 0.4.2 → 0.4.3
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.
- package/dist/{chunk-JHVQB4Y5.js → chunk-334PCFO3.js} +12 -12
- package/dist/{chunk-OXX3QF24.js → chunk-46ZTW4AI.js} +2 -2
- package/dist/{chunk-24LF6IZB.js → chunk-4YN3PE57.js} +3 -3
- package/dist/{chunk-3NJSJ7TE.js → chunk-5YB6UXQ3.js} +4 -15
- package/dist/{chunk-Z5VSUOEE.js → chunk-6PVHJ332.js} +2 -2
- package/dist/{chunk-EAGKJFDX.js → chunk-7KGTWDAX.js} +3 -3
- package/dist/{chunk-PU2254N2.js → chunk-7OGXSMLY.js} +5 -15
- package/dist/{chunk-R7HPHMRZ.js → chunk-AEBM56CO.js} +3 -3
- package/dist/{chunk-SYQR4QGK.js → chunk-B747RITP.js} +3 -3
- package/dist/{chunk-A6XLXV6W.js → chunk-B7LDMCUS.js} +3 -3
- package/dist/{chunk-KLNKDX6A.js → chunk-C2VSV54P.js} +4 -4
- package/dist/{chunk-VKBOLNYN.js → chunk-DIYEUFVP.js} +10 -8
- package/dist/{chunk-RE7POFGI.js → chunk-E74RY6AQ.js} +2 -2
- package/dist/{chunk-RL74LF47.js → chunk-FIMTTUGE.js} +2 -2
- package/dist/{chunk-ALUFWH3U.js → chunk-FMAYH7GS.js} +116 -269
- package/dist/{chunk-MGNMHKX3.js → chunk-FO2CBB7U.js} +10 -2
- package/dist/{chunk-7BS4CPJX.js → chunk-HESWGDIV.js} +3 -3
- package/dist/{chunk-FVJE4MQL.js → chunk-HL2LXSBW.js} +5 -8
- package/dist/{chunk-KG4OFQEN.js → chunk-HW76DVE4.js} +3 -3
- package/dist/{chunk-RJ5GULL6.js → chunk-IC5NTO47.js} +2 -2
- package/dist/{chunk-VY2L4TP6.js → chunk-J34HAAEQ.js} +3 -3
- package/dist/{chunk-PCU455MX.js → chunk-JSXGC2EH.js} +2 -2
- package/dist/{chunk-NXUIWD6K.js → chunk-LQXBFCP2.js} +3 -3
- package/dist/{chunk-GNAMV3JC.js → chunk-NML6M5AS.js} +3 -3
- package/dist/{chunk-UJWI5CBB.js → chunk-NNFP4ZRF.js} +4 -7
- package/dist/{chunk-6ECR2FLR.js → chunk-NWXTQGUE.js} +4 -15
- package/dist/{chunk-ZVZAIIB5.js → chunk-NYZ6INK3.js} +3 -3
- package/dist/{chunk-JKXHHV4B.js → chunk-OMVF3BHY.js} +2 -2
- package/dist/{chunk-CBIWNZZZ.js → chunk-PGQXIAJF.js} +3 -3
- package/dist/{chunk-J47VSL6I.js → chunk-PKDFXASW.js} +3 -3
- package/dist/{chunk-POLELLNM.js → chunk-PSK5BPFE.js} +3 -3
- package/dist/{chunk-6CH23IAS.js → chunk-QZ4FRB65.js} +9 -7
- package/dist/{chunk-TWVXFKJA.js → chunk-R2QBMQQN.js} +4 -4
- package/dist/{chunk-5GCORUNV.js → chunk-T3ALCNCP.js} +30 -17
- package/dist/{chunk-QMXSLHZP.js → chunk-T6UVM534.js} +2 -2
- package/dist/{chunk-6UZU7DFL.js → chunk-U74VYTLX.js} +3 -3
- package/dist/{chunk-XUVPQDXW.js → chunk-UIRCHPOU.js} +4 -4
- package/dist/{chunk-43A4UCS7.js → chunk-UNS6ZQVX.js} +3 -3
- package/dist/{chunk-J6QXMYAQ.js → chunk-VJMTX3OR.js} +3 -3
- package/dist/{chunk-SVLUJSY7.js → chunk-XJSPWHNT.js} +4 -15
- package/dist/{chunk-W46L2BXT.js → chunk-XMZAC2VU.js} +2 -2
- package/dist/{chunk-ELFGD5EW.js → chunk-Y7FKURZG.js} +3 -3
- package/dist/{chunk-TO3L4YNK.js → chunk-YMSJCSRG.js} +5 -1
- package/dist/{chunk-DUJNJQPO.js → chunk-YQIWS5V6.js} +3 -3
- package/dist/{chunk-KYPXKV64.js → chunk-ZPEI7DRJ.js} +30 -15
- package/dist/cli.js +200 -373
- package/dist/{db-C4rPbKkI.d.ts → db-6F9R9e_t.d.ts} +0 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +45 -57
- package/dist/queries/affected.d.ts +1 -1
- package/dist/queries/affected.js +3 -3
- package/dist/queries/bottlenecks.d.ts +1 -1
- package/dist/queries/bottlenecks.js +3 -3
- package/dist/queries/by-kind.d.ts +1 -1
- package/dist/queries/by-kind.js +3 -3
- package/dist/queries/call-graph.d.ts +1 -1
- package/dist/queries/call-graph.js +3 -3
- package/dist/queries/change-surface.d.ts +1 -1
- package/dist/queries/change-surface.js +3 -3
- package/dist/queries/code.d.ts +1 -1
- package/dist/queries/code.js +3 -3
- package/dist/queries/complexity-hotspots.d.ts +1 -1
- package/dist/queries/complexity-hotspots.js +3 -3
- package/dist/queries/complexity.d.ts +1 -1
- package/dist/queries/complexity.js +3 -3
- package/dist/queries/convergence.d.ts +1 -1
- package/dist/queries/convergence.js +3 -3
- package/dist/queries/coupling.d.ts +1 -1
- package/dist/queries/coupling.js +3 -3
- package/dist/queries/cycles.d.ts +1 -1
- package/dist/queries/cycles.js +3 -3
- package/dist/queries/dataflow.d.ts +1 -1
- package/dist/queries/dataflow.js +3 -3
- package/dist/queries/dead.d.ts +1 -1
- package/dist/queries/dead.js +4 -4
- package/dist/queries/deep-chains.d.ts +1 -1
- package/dist/queries/deep-chains.js +3 -3
- package/dist/queries/deps.d.ts +1 -1
- package/dist/queries/deps.js +3 -3
- package/dist/queries/diff-impact.d.ts +1 -1
- package/dist/queries/diff-impact.js +2 -2
- package/dist/queries/drift.d.ts +1 -1
- package/dist/queries/drift.js +3 -3
- package/dist/queries/extract-candidates.d.ts +1 -1
- package/dist/queries/extract-candidates.js +3 -3
- package/dist/queries/fan.d.ts +1 -1
- package/dist/queries/fan.js +3 -3
- package/dist/queries/files.d.ts +1 -1
- package/dist/queries/files.js +1 -1
- package/dist/queries/health.d.ts +1 -1
- package/dist/queries/health.js +14 -14
- package/dist/queries/hierarchy.d.ts +1 -1
- package/dist/queries/hierarchy.js +3 -3
- package/dist/queries/hotspots.d.ts +1 -1
- package/dist/queries/hotspots.js +3 -3
- package/dist/queries/imports.d.ts +1 -1
- package/dist/queries/imports.js +3 -3
- package/dist/queries/index.d.ts +1 -1
- package/dist/queries/index.js +45 -45
- package/dist/queries/isolated.d.ts +1 -1
- package/dist/queries/isolated.js +4 -4
- package/dist/queries/members.d.ts +1 -1
- package/dist/queries/members.js +3 -3
- package/dist/queries/methods.d.ts +1 -1
- package/dist/queries/methods.js +3 -3
- package/dist/queries/outline.d.ts +1 -1
- package/dist/queries/outline.js +3 -3
- package/dist/queries/passthrough-candidates.d.ts +1 -1
- package/dist/queries/passthrough-candidates.js +3 -3
- package/dist/queries/redundant-reexports.d.ts +1 -1
- package/dist/queries/redundant-reexports.js +4 -4
- package/dist/queries/refs.d.ts +1 -1
- package/dist/queries/refs.js +3 -3
- package/dist/queries/similar-chains.d.ts +1 -1
- package/dist/queries/similar-chains.js +3 -3
- package/dist/queries/similar-files.d.ts +1 -1
- package/dist/queries/similar-files.js +3 -3
- package/dist/queries/similar-signatures.d.ts +1 -1
- package/dist/queries/similar-signatures.js +3 -3
- package/dist/queries/similar.d.ts +2 -1
- package/dist/queries/similar.js +3 -3
- package/dist/queries/slice.d.ts +4 -3
- package/dist/queries/slice.js +3 -3
- package/dist/queries/stale-abstractions.d.ts +1 -1
- package/dist/queries/stale-abstractions.js +3 -3
- package/dist/queries/stats.d.ts +1 -1
- package/dist/queries/surface.d.ts +1 -1
- package/dist/queries/surface.js +3 -3
- package/dist/queries/symbols.d.ts +1 -1
- package/dist/queries/symbols.js +3 -3
- package/dist/queries/system.d.ts +1 -1
- package/dist/queries/system.js +3 -3
- package/dist/queries/trace.d.ts +1 -1
- package/dist/queries/trace.js +3 -3
- package/dist/queries/wrapper-candidates.d.ts +1 -1
- package/dist/queries/wrapper-candidates.js +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -20,18 +20,10 @@ var ScipDatabase = class {
|
|
|
20
20
|
this.db = new Database(config.dbPath, { readonly: true });
|
|
21
21
|
this.db.pragma("busy_timeout = 5000");
|
|
22
22
|
}
|
|
23
|
-
/** Attach a gitignore-based path filter for query results */
|
|
24
|
-
setPathFilter(filter) {
|
|
25
|
-
this.pathFilter = filter;
|
|
26
|
-
}
|
|
27
23
|
/** Check if a path should be excluded based on .gitignore rules */
|
|
28
24
|
isIgnored(relativePath) {
|
|
29
25
|
return this.pathFilter?.isIgnored(relativePath) ?? false;
|
|
30
26
|
}
|
|
31
|
-
/** Filter an array of paths using the gitignore filter */
|
|
32
|
-
filterPaths(paths) {
|
|
33
|
-
return this.pathFilter?.filter(paths) ?? paths;
|
|
34
|
-
}
|
|
35
27
|
/**
|
|
36
28
|
* The local-symbol predicate: only match symbols that are defined
|
|
37
29
|
* in files NOT excluded by gitignore. This replaces the old hardcoded
|
|
@@ -1323,10 +1315,6 @@ var Watcher = class {
|
|
|
1323
1315
|
if (this.cooldownTimer) clearTimeout(this.cooldownTimer);
|
|
1324
1316
|
this.setStatus({ state: "idle" });
|
|
1325
1317
|
}
|
|
1326
|
-
/** Get current watcher status */
|
|
1327
|
-
getStatus() {
|
|
1328
|
-
return this.status;
|
|
1329
|
-
}
|
|
1330
1318
|
// ── Internal ─────────────────────────────────────────────
|
|
1331
1319
|
handleFileChange(filename) {
|
|
1332
1320
|
const rel = relative2(this.projectRoot, join7(this.projectRoot, filename));
|
|
@@ -1479,12 +1467,20 @@ function stats(db) {
|
|
|
1479
1467
|
}
|
|
1480
1468
|
|
|
1481
1469
|
// src/queries/files.ts
|
|
1470
|
+
function globToLike(pattern) {
|
|
1471
|
+
const hasGlobChars = /[*?]/.test(pattern);
|
|
1472
|
+
if (!hasGlobChars) {
|
|
1473
|
+
return `%${pattern}%`;
|
|
1474
|
+
}
|
|
1475
|
+
return pattern.replace(/\*\*/g, "%").replace(/\*/g, "%").replace(/\?/g, "_");
|
|
1476
|
+
}
|
|
1482
1477
|
function files(db, pattern) {
|
|
1478
|
+
const likePattern = globToLike(pattern);
|
|
1483
1479
|
const rows = db.all(
|
|
1484
1480
|
`SELECT relative_path FROM documents
|
|
1485
1481
|
WHERE relative_path LIKE ?
|
|
1486
1482
|
ORDER BY relative_path`,
|
|
1487
|
-
|
|
1483
|
+
likePattern
|
|
1488
1484
|
);
|
|
1489
1485
|
return rows.filter((r) => !db.isIgnored(r.relative_path)).map((r) => ({ relativePath: r.relative_path }));
|
|
1490
1486
|
}
|
|
@@ -2539,44 +2535,55 @@ function getCachedMap(cache, db) {
|
|
|
2539
2535
|
function normalizePath(path2) {
|
|
2540
2536
|
return path2.replace(/\\/g, "/");
|
|
2541
2537
|
}
|
|
2538
|
+
var LANGUAGE_EXTENSION_FAMILIES = [
|
|
2539
|
+
SOURCE_EXTENSIONS,
|
|
2540
|
+
PYTHON_SOURCE_EXTENSIONS,
|
|
2541
|
+
JVM_SOURCE_EXTENSIONS,
|
|
2542
|
+
RUST_SOURCE_EXTENSIONS,
|
|
2543
|
+
RUBY_SOURCE_EXTENSIONS,
|
|
2544
|
+
C_LIKE_SOURCE_EXTENSIONS,
|
|
2545
|
+
DOTNET_SOURCE_EXTENSIONS,
|
|
2546
|
+
DART_SOURCE_EXTENSIONS,
|
|
2547
|
+
PHP_SOURCE_EXTENSIONS
|
|
2548
|
+
];
|
|
2549
|
+
function hasExtensionIn(relativePath, extensions) {
|
|
2550
|
+
return extensions.includes(extname3(relativePath).toLowerCase());
|
|
2551
|
+
}
|
|
2542
2552
|
function isJavaScriptSourcePath(relativePath) {
|
|
2543
|
-
return
|
|
2553
|
+
return hasExtensionIn(relativePath, SOURCE_EXTENSIONS);
|
|
2544
2554
|
}
|
|
2545
2555
|
function isPythonSourcePath(relativePath) {
|
|
2546
|
-
return
|
|
2556
|
+
return hasExtensionIn(relativePath, PYTHON_SOURCE_EXTENSIONS);
|
|
2547
2557
|
}
|
|
2548
2558
|
function isJvmSourcePath(relativePath) {
|
|
2549
|
-
return
|
|
2559
|
+
return hasExtensionIn(relativePath, JVM_SOURCE_EXTENSIONS);
|
|
2550
2560
|
}
|
|
2551
2561
|
function isRustSourcePath(relativePath) {
|
|
2552
|
-
return
|
|
2562
|
+
return hasExtensionIn(relativePath, RUST_SOURCE_EXTENSIONS);
|
|
2553
2563
|
}
|
|
2554
2564
|
function isRubySourcePath(relativePath) {
|
|
2555
|
-
return
|
|
2565
|
+
return hasExtensionIn(relativePath, RUBY_SOURCE_EXTENSIONS);
|
|
2556
2566
|
}
|
|
2557
2567
|
function isCLikeSourcePath(relativePath) {
|
|
2558
|
-
return
|
|
2568
|
+
return hasExtensionIn(relativePath, C_LIKE_SOURCE_EXTENSIONS);
|
|
2559
2569
|
}
|
|
2560
2570
|
function isDotNetSourcePath(relativePath) {
|
|
2561
|
-
return
|
|
2571
|
+
return hasExtensionIn(relativePath, DOTNET_SOURCE_EXTENSIONS);
|
|
2562
2572
|
}
|
|
2563
2573
|
function isVisualBasicSourcePath(relativePath) {
|
|
2564
2574
|
return extname3(relativePath).toLowerCase() === ".vb";
|
|
2565
2575
|
}
|
|
2566
2576
|
function isDartSourcePath(relativePath) {
|
|
2567
|
-
return
|
|
2577
|
+
return hasExtensionIn(relativePath, DART_SOURCE_EXTENSIONS);
|
|
2568
2578
|
}
|
|
2569
2579
|
function isPhpSourcePath(relativePath) {
|
|
2570
|
-
return
|
|
2580
|
+
return hasExtensionIn(relativePath, PHP_SOURCE_EXTENSIONS);
|
|
2571
2581
|
}
|
|
2572
2582
|
function extensionFamilyFor(relativePath) {
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
if (isCLikeSourcePath(relativePath)) return C_LIKE_SOURCE_EXTENSIONS;
|
|
2578
|
-
if (isRustSourcePath(relativePath)) return RUST_SOURCE_EXTENSIONS;
|
|
2579
|
-
if (isRubySourcePath(relativePath)) return RUBY_SOURCE_EXTENSIONS;
|
|
2583
|
+
const ext = extname3(relativePath).toLowerCase();
|
|
2584
|
+
for (const family of LANGUAGE_EXTENSION_FAMILIES) {
|
|
2585
|
+
if (family.includes(ext)) return family;
|
|
2586
|
+
}
|
|
2580
2587
|
return SOURCE_EXTENSIONS;
|
|
2581
2588
|
}
|
|
2582
2589
|
function getSourceText(db, relativePath) {
|
|
@@ -2778,6 +2785,9 @@ function leafSuffix(raw) {
|
|
|
2778
2785
|
const last = sym.descriptors[sym.descriptors.length - 1];
|
|
2779
2786
|
return last?.suffix ?? null;
|
|
2780
2787
|
}
|
|
2788
|
+
function isCallableSymbol(raw) {
|
|
2789
|
+
return raw.endsWith("().") || leafSuffix(raw) === "method";
|
|
2790
|
+
}
|
|
2781
2791
|
function isFunctionLikeSymbol(raw) {
|
|
2782
2792
|
const suffix = leafSuffix(raw);
|
|
2783
2793
|
return suffix === "method" || suffix === "term";
|
|
@@ -3231,56 +3241,41 @@ function findEnclosingDefinition(definitions, line) {
|
|
|
3231
3241
|
}
|
|
3232
3242
|
return best;
|
|
3233
3243
|
}
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
}
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
)
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
if (seen.has(key)) continue;
|
|
3270
|
-
seen.add(key);
|
|
3271
|
-
rows.push({
|
|
3272
|
-
symbol: resolved.symbol,
|
|
3273
|
-
file: resolved.relativePath,
|
|
3274
|
-
chunkId
|
|
3275
|
-
});
|
|
3276
|
-
}
|
|
3277
|
-
return applyLimit(rows, limit);
|
|
3278
|
-
}
|
|
3279
|
-
function getJavaScriptSourceCalleeRows(db, symbol, limit) {
|
|
3280
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3281
|
-
if (!match || !isJavaScriptDocument(db, match.relativePath)) {
|
|
3282
|
-
return [];
|
|
3283
|
-
}
|
|
3244
|
+
var LANGUAGE_CALLEE_CONFIGS = [
|
|
3245
|
+
// Python (index 0) — complex resolver
|
|
3246
|
+
{ kind: "complex", languageIndex: 0, resolver: resolvePythonCallTarget },
|
|
3247
|
+
// JavaScript/TypeScript (index 1) — complex resolver
|
|
3248
|
+
{ kind: "complex", languageIndex: 1, resolver: resolveJavaScriptCallTarget },
|
|
3249
|
+
// Java (index 2) — simple with field bindings
|
|
3250
|
+
{ kind: "simple", languageIndex: 2, parseBindings: (_db, source) => parseJavaFieldBindings(source) },
|
|
3251
|
+
// Kotlin (index 3) — simple with field bindings
|
|
3252
|
+
{ kind: "simple", languageIndex: 3, parseBindings: (_db, source) => parseKotlinFieldBindings(source) },
|
|
3253
|
+
// Scala (index 4) — simple, no bindings
|
|
3254
|
+
{ kind: "simple", languageIndex: 4, parseBindings: null },
|
|
3255
|
+
// C# (index 5) — simple, no bindings
|
|
3256
|
+
{ kind: "simple", languageIndex: 5, parseBindings: null },
|
|
3257
|
+
// Visual Basic (index 6) — simple, no bindings
|
|
3258
|
+
{ kind: "simple", languageIndex: 6, parseBindings: null },
|
|
3259
|
+
// C++ (index 7) — simple with receiver bindings
|
|
3260
|
+
{ kind: "simple", languageIndex: 7, parseBindings: (_db, source) => parseCppReceiverBindings(source) },
|
|
3261
|
+
// Rust (index 8) — simple, no bindings
|
|
3262
|
+
{ kind: "simple", languageIndex: 8, parseBindings: null },
|
|
3263
|
+
// Ruby (index 9) — simple with dual-attempt logic
|
|
3264
|
+
{
|
|
3265
|
+
kind: "simple",
|
|
3266
|
+
languageIndex: 9,
|
|
3267
|
+
parseBindings: (db, source) => parseRubyReceiverBindings(db, source),
|
|
3268
|
+
dualAttempt: {
|
|
3269
|
+
baseOpts: { allowInstanceVariables: true },
|
|
3270
|
+
extendedOpts: { allowInstanceVariables: true, allowBareMemberCalls: true }
|
|
3271
|
+
}
|
|
3272
|
+
},
|
|
3273
|
+
// Dart (index 10) — simple, no bindings
|
|
3274
|
+
{ kind: "simple", languageIndex: 10, parseBindings: null },
|
|
3275
|
+
// PHP (index 11) — simple, no bindings
|
|
3276
|
+
{ kind: "simple", languageIndex: 11, parseBindings: null }
|
|
3277
|
+
];
|
|
3278
|
+
function getComplexSourceCalleeRows(db, match, config, limit) {
|
|
3284
3279
|
const definitions = getDefinitionsForFile(db, match.relativePath);
|
|
3285
3280
|
const current = definitions.find((definition) => definition.symbolId === match.symbolId);
|
|
3286
3281
|
if (!current) {
|
|
@@ -3299,7 +3294,7 @@ function getJavaScriptSourceCalleeRows(db, symbol, limit) {
|
|
|
3299
3294
|
startLine: match.startLine,
|
|
3300
3295
|
endLine: match.endLine
|
|
3301
3296
|
})) {
|
|
3302
|
-
const resolved =
|
|
3297
|
+
const resolved = config.resolver(
|
|
3303
3298
|
db,
|
|
3304
3299
|
current,
|
|
3305
3300
|
definitions,
|
|
@@ -3321,134 +3316,31 @@ function getJavaScriptSourceCalleeRows(db, symbol, limit) {
|
|
|
3321
3316
|
}
|
|
3322
3317
|
return applyLimit(rows, limit);
|
|
3323
3318
|
}
|
|
3324
|
-
function
|
|
3325
|
-
|
|
3326
|
-
if (
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
}
|
|
3333
|
-
function getKotlinSourceCalleeRows(db, symbol, limit) {
|
|
3334
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3335
|
-
if (!match || !isKotlinDocument(db, match.relativePath)) {
|
|
3336
|
-
return [];
|
|
3337
|
-
}
|
|
3338
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine);
|
|
3339
|
-
const bindings = parseKotlinFieldBindings(getSourceText(db, match.relativePath));
|
|
3340
|
-
return resolveSimpleSourceCallees(db, match, calls, bindings, limit);
|
|
3341
|
-
}
|
|
3342
|
-
function getScalaSourceCalleeRows(db, symbol, limit) {
|
|
3343
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3344
|
-
if (!match || !isScalaDocument(db, match.relativePath)) {
|
|
3345
|
-
return [];
|
|
3346
|
-
}
|
|
3347
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine);
|
|
3348
|
-
return resolveSimpleSourceCallees(db, match, calls, /* @__PURE__ */ new Map(), limit);
|
|
3349
|
-
}
|
|
3350
|
-
function getCSharpSourceCalleeRows(db, symbol, limit) {
|
|
3351
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3352
|
-
if (!match || !isCSharpDocument(db, match.relativePath)) {
|
|
3353
|
-
return [];
|
|
3354
|
-
}
|
|
3355
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine);
|
|
3356
|
-
return resolveSimpleSourceCallees(db, match, calls, /* @__PURE__ */ new Map(), limit);
|
|
3357
|
-
}
|
|
3358
|
-
function getVisualBasicSourceCalleeRows(db, symbol, limit) {
|
|
3359
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3360
|
-
if (!match || !isVisualBasicDocument(db, match.relativePath)) {
|
|
3361
|
-
return [];
|
|
3362
|
-
}
|
|
3363
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine);
|
|
3364
|
-
return resolveSimpleSourceCallees(db, match, calls, /* @__PURE__ */ new Map(), limit);
|
|
3365
|
-
}
|
|
3366
|
-
function getCppSourceCalleeRows(db, symbol, limit) {
|
|
3367
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3368
|
-
if (!match || !isCppDocument(db, match.relativePath)) {
|
|
3369
|
-
return [];
|
|
3319
|
+
function getSimpleLanguageCalleeRows(db, match, config, limit) {
|
|
3320
|
+
let calls;
|
|
3321
|
+
if (config.dualAttempt) {
|
|
3322
|
+
const baseCalls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine, config.dualAttempt.baseOpts);
|
|
3323
|
+
const extendedCalls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine, config.dualAttempt.extendedOpts);
|
|
3324
|
+
calls = extendedCalls.length > 0 ? extendedCalls : baseCalls;
|
|
3325
|
+
} else {
|
|
3326
|
+
calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine, config.sourceCallOpts);
|
|
3370
3327
|
}
|
|
3371
|
-
const
|
|
3372
|
-
const bindings = parseCppReceiverBindings(getSourceText(db, match.relativePath));
|
|
3328
|
+
const bindings = config.parseBindings ? config.parseBindings(db, getSourceText(db, match.relativePath)) : /* @__PURE__ */ new Map();
|
|
3373
3329
|
return resolveSimpleSourceCallees(db, match, calls, bindings, limit);
|
|
3374
3330
|
}
|
|
3375
|
-
function getRustSourceCalleeRows(db, symbol, limit) {
|
|
3376
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3377
|
-
if (!match || !isRustDocument(db, match.relativePath)) {
|
|
3378
|
-
return [];
|
|
3379
|
-
}
|
|
3380
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine);
|
|
3381
|
-
return resolveSimpleSourceCallees(db, match, calls, /* @__PURE__ */ new Map(), limit);
|
|
3382
|
-
}
|
|
3383
|
-
function getRubySourceCalleeRows(db, symbol, limit) {
|
|
3384
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3385
|
-
if (!match || !isRubyDocument(db, match.relativePath)) {
|
|
3386
|
-
return [];
|
|
3387
|
-
}
|
|
3388
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine, { allowInstanceVariables: true });
|
|
3389
|
-
const rubyCalls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine, {
|
|
3390
|
-
allowInstanceVariables: true,
|
|
3391
|
-
allowBareMemberCalls: true
|
|
3392
|
-
});
|
|
3393
|
-
const bindings = parseRubyReceiverBindings(db, getSourceText(db, match.relativePath));
|
|
3394
|
-
return resolveSimpleSourceCallees(db, match, rubyCalls.length > 0 ? rubyCalls : calls, bindings, limit);
|
|
3395
|
-
}
|
|
3396
|
-
function getDartSourceCalleeRows(db, symbol, limit) {
|
|
3397
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3398
|
-
if (!match || !isDartDocument(db, match.relativePath)) {
|
|
3399
|
-
return [];
|
|
3400
|
-
}
|
|
3401
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine);
|
|
3402
|
-
return resolveSimpleSourceCallees(db, match, calls, /* @__PURE__ */ new Map(), limit);
|
|
3403
|
-
}
|
|
3404
|
-
function getPhpSourceCalleeRows(db, symbol, limit) {
|
|
3405
|
-
const match = getFullSymbolMatch(db, symbol);
|
|
3406
|
-
if (!match || !isPhpDocument(db, match.relativePath)) {
|
|
3407
|
-
return [];
|
|
3408
|
-
}
|
|
3409
|
-
const calls = getSimpleSourceCalls(db, match.relativePath, match.startLine, match.endLine);
|
|
3410
|
-
return resolveSimpleSourceCallees(db, match, calls, /* @__PURE__ */ new Map(), limit);
|
|
3411
|
-
}
|
|
3412
3331
|
function getSourceBackedCalleeRows(db, symbol, limit) {
|
|
3413
3332
|
const match = getFullSymbolMatch(db, symbol);
|
|
3414
3333
|
if (!match) {
|
|
3415
3334
|
return [];
|
|
3416
3335
|
}
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
return
|
|
3425
|
-
}
|
|
3426
|
-
if (isScalaDocument(db, match.relativePath)) {
|
|
3427
|
-
return getScalaSourceCalleeRows(db, match, limit);
|
|
3428
|
-
}
|
|
3429
|
-
if (isKotlinDocument(db, match.relativePath)) {
|
|
3430
|
-
return getKotlinSourceCalleeRows(db, match, limit);
|
|
3431
|
-
}
|
|
3432
|
-
if (isCSharpDocument(db, match.relativePath)) {
|
|
3433
|
-
return getCSharpSourceCalleeRows(db, match, limit);
|
|
3434
|
-
}
|
|
3435
|
-
if (isVisualBasicDocument(db, match.relativePath)) {
|
|
3436
|
-
return getVisualBasicSourceCalleeRows(db, match, limit);
|
|
3437
|
-
}
|
|
3438
|
-
if (isCppDocument(db, match.relativePath)) {
|
|
3439
|
-
return getCppSourceCalleeRows(db, match, limit);
|
|
3440
|
-
}
|
|
3441
|
-
if (isRustDocument(db, match.relativePath)) {
|
|
3442
|
-
return getRustSourceCalleeRows(db, match, limit);
|
|
3443
|
-
}
|
|
3444
|
-
if (isRubyDocument(db, match.relativePath)) {
|
|
3445
|
-
return getRubySourceCalleeRows(db, match, limit);
|
|
3446
|
-
}
|
|
3447
|
-
if (isDartDocument(db, match.relativePath)) {
|
|
3448
|
-
return getDartSourceCalleeRows(db, match, limit);
|
|
3449
|
-
}
|
|
3450
|
-
if (isPhpDocument(db, match.relativePath)) {
|
|
3451
|
-
return getPhpSourceCalleeRows(db, match, limit);
|
|
3336
|
+
for (const config of LANGUAGE_CALLEE_CONFIGS) {
|
|
3337
|
+
if (!isDocumentLanguage(db, match.relativePath, DOCUMENT_LANGUAGE_TABLE[config.languageIndex])) {
|
|
3338
|
+
continue;
|
|
3339
|
+
}
|
|
3340
|
+
if (config.kind === "complex") {
|
|
3341
|
+
return getComplexSourceCalleeRows(db, match, config, limit);
|
|
3342
|
+
}
|
|
3343
|
+
return getSimpleLanguageCalleeRows(db, match, config, limit);
|
|
3452
3344
|
}
|
|
3453
3345
|
return [];
|
|
3454
3346
|
}
|
|
@@ -3458,9 +3350,11 @@ function getPythonSourceCallerRows(db, target, limit) {
|
|
|
3458
3350
|
}
|
|
3459
3351
|
const rows = [];
|
|
3460
3352
|
const seen = /* @__PURE__ */ new Set();
|
|
3353
|
+
const pythonConfig = LANGUAGE_CALLEE_CONFIGS[0];
|
|
3461
3354
|
for (const candidate of getAllFunctionLikeDefinitions(db)) {
|
|
3462
3355
|
if (candidate.symbolId === target.symbolId) continue;
|
|
3463
|
-
|
|
3356
|
+
if (!isDocumentLanguage(db, candidate.relativePath, DOCUMENT_LANGUAGE_TABLE[pythonConfig.languageIndex])) continue;
|
|
3357
|
+
const callees = getComplexSourceCalleeRows(db, candidate, pythonConfig);
|
|
3464
3358
|
if (!callees.some((callee) => callee.symbol === target.symbol)) continue;
|
|
3465
3359
|
const key = `${candidate.symbol}|${candidate.relativePath}`;
|
|
3466
3360
|
if (seen.has(key) || db.isIgnored(candidate.relativePath)) continue;
|
|
@@ -3802,6 +3696,17 @@ function getAllDefinitions(db, opts = {}) {
|
|
|
3802
3696
|
);
|
|
3803
3697
|
return rows.filter((row) => !db.isIgnored(row.relative_path)).flatMap((row) => getDefinitionsForFile(db, row.relative_path));
|
|
3804
3698
|
}
|
|
3699
|
+
function getScopedDefinitions(db, scope) {
|
|
3700
|
+
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
3701
|
+
return db.all(
|
|
3702
|
+
`SELECT relative_path
|
|
3703
|
+
FROM documents
|
|
3704
|
+
WHERE 1 = 1
|
|
3705
|
+
${db.pathExclusionsFor("documents")}
|
|
3706
|
+
${scopeFilter}
|
|
3707
|
+
ORDER BY relative_path`
|
|
3708
|
+
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
3709
|
+
}
|
|
3805
3710
|
function getAllFunctionLikeDefinitions(db) {
|
|
3806
3711
|
return getAllDefinitions(db).filter((definition) => definition.isFunctionLike);
|
|
3807
3712
|
}
|
|
@@ -4219,89 +4124,29 @@ function parentTypeName(rawSymbol) {
|
|
|
4219
4124
|
}
|
|
4220
4125
|
return null;
|
|
4221
4126
|
}
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
)
|
|
4227
|
-
|
|
4228
|
-
}
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
function
|
|
4237
|
-
const row = db.get(
|
|
4238
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4239
|
-
relativePath
|
|
4240
|
-
);
|
|
4241
|
-
return row?.language === "java" || relativePath.endsWith(".java");
|
|
4242
|
-
}
|
|
4243
|
-
function isKotlinDocument(db, relativePath) {
|
|
4244
|
-
const row = db.get(
|
|
4245
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4246
|
-
relativePath
|
|
4247
|
-
);
|
|
4248
|
-
return row?.language === "kotlin" || relativePath.endsWith(".kt") || relativePath.endsWith(".kts");
|
|
4249
|
-
}
|
|
4250
|
-
function isScalaDocument(db, relativePath) {
|
|
4251
|
-
const row = db.get(
|
|
4252
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4253
|
-
relativePath
|
|
4254
|
-
);
|
|
4255
|
-
return row?.language === "scala" || relativePath.endsWith(".scala");
|
|
4256
|
-
}
|
|
4257
|
-
function isCSharpDocument(db, relativePath) {
|
|
4258
|
-
const row = db.get(
|
|
4259
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4260
|
-
relativePath
|
|
4261
|
-
);
|
|
4262
|
-
return row?.language === "C#" || relativePath.endsWith(".cs");
|
|
4263
|
-
}
|
|
4264
|
-
function isVisualBasicDocument(db, relativePath) {
|
|
4265
|
-
const row = db.get(
|
|
4266
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4267
|
-
relativePath
|
|
4268
|
-
);
|
|
4269
|
-
return row?.language === "Visual Basic" || relativePath.endsWith(".vb");
|
|
4270
|
-
}
|
|
4271
|
-
function isCppDocument(db, relativePath) {
|
|
4272
|
-
const row = db.get(
|
|
4273
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4274
|
-
relativePath
|
|
4275
|
-
);
|
|
4276
|
-
return row?.language === "CPP" || /\.(?:cc|cpp|cxx|hpp|hh|hxx)$/.test(relativePath);
|
|
4277
|
-
}
|
|
4278
|
-
function isRustDocument(db, relativePath) {
|
|
4279
|
-
const row = db.get(
|
|
4280
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4281
|
-
relativePath
|
|
4282
|
-
);
|
|
4283
|
-
return row?.language === "Rust" || relativePath.endsWith(".rs");
|
|
4284
|
-
}
|
|
4285
|
-
function isRubyDocument(db, relativePath) {
|
|
4286
|
-
const row = db.get(
|
|
4287
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4288
|
-
relativePath
|
|
4289
|
-
);
|
|
4290
|
-
return row?.language === "ruby" || relativePath.endsWith(".rb");
|
|
4291
|
-
}
|
|
4292
|
-
function isDartDocument(db, relativePath) {
|
|
4127
|
+
var DOCUMENT_LANGUAGE_TABLE = [
|
|
4128
|
+
{ languages: ["python"], extensionPattern: /\.(?:py|pyi)$/ },
|
|
4129
|
+
{ languages: ["typescript", "javascript"], extensionPattern: /\.(?:[cm]?[jt]sx?)$/ },
|
|
4130
|
+
{ languages: ["java"], extensionPattern: /\.java$/ },
|
|
4131
|
+
{ languages: ["kotlin"], extensionPattern: /\.(?:kt|kts)$/ },
|
|
4132
|
+
{ languages: ["scala"], extensionPattern: /\.scala$/ },
|
|
4133
|
+
{ languages: ["C#"], extensionPattern: /\.cs$/ },
|
|
4134
|
+
{ languages: ["Visual Basic"], extensionPattern: /\.vb$/ },
|
|
4135
|
+
{ languages: ["CPP"], extensionPattern: /\.(?:cc|cpp|cxx|hpp|hh|hxx)$/ },
|
|
4136
|
+
{ languages: ["Rust"], extensionPattern: /\.rs$/ },
|
|
4137
|
+
{ languages: ["ruby"], extensionPattern: /\.rb$/ },
|
|
4138
|
+
{ languages: ["Dart"], extensionPattern: /\.dart$/ },
|
|
4139
|
+
{ languages: ["PHP"], extensionPattern: /\.php$/ }
|
|
4140
|
+
];
|
|
4141
|
+
function isDocumentLanguage(db, relativePath, entry) {
|
|
4293
4142
|
const row = db.get(
|
|
4294
4143
|
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4295
4144
|
relativePath
|
|
4296
4145
|
);
|
|
4297
|
-
return row?.language
|
|
4146
|
+
return entry.languages.includes(row?.language ?? "") || entry.extensionPattern.test(relativePath);
|
|
4298
4147
|
}
|
|
4299
|
-
function
|
|
4300
|
-
|
|
4301
|
-
`SELECT language FROM documents WHERE relative_path = ? LIMIT 1`,
|
|
4302
|
-
relativePath
|
|
4303
|
-
);
|
|
4304
|
-
return row?.language === "PHP" || relativePath.endsWith(".php");
|
|
4148
|
+
function isPythonDocument(db, relativePath) {
|
|
4149
|
+
return isDocumentLanguage(db, relativePath, DOCUMENT_LANGUAGE_TABLE[0]);
|
|
4305
4150
|
}
|
|
4306
4151
|
function applyLimit(values, limit) {
|
|
4307
4152
|
return typeof limit === "number" ? values.slice(0, limit) : values;
|
|
@@ -4403,9 +4248,6 @@ function methods(db, className) {
|
|
|
4403
4248
|
name: leafName(definition.symbol)
|
|
4404
4249
|
}));
|
|
4405
4250
|
}
|
|
4406
|
-
function isCallableSymbol(rawSymbol) {
|
|
4407
|
-
return rawSymbol.endsWith("().") || leafSuffix(rawSymbol) === "method";
|
|
4408
|
-
}
|
|
4409
4251
|
function stripExtension(relativePath) {
|
|
4410
4252
|
return relativePath.replace(/\.[^.]+$/, "");
|
|
4411
4253
|
}
|
|
@@ -4743,7 +4585,7 @@ function surface(db, modulePattern) {
|
|
|
4743
4585
|
...matchedPaths
|
|
4744
4586
|
);
|
|
4745
4587
|
const exposedDefinitions = matchedPaths.flatMap(
|
|
4746
|
-
(relativePath) => getDefinitionsForFile(db, relativePath).filter((definition) =>
|
|
4588
|
+
(relativePath) => getDefinitionsForFile(db, relativePath).filter((definition) => isCallableSymbol(definition.symbol)).map((definition) => ({
|
|
4747
4589
|
relative_path: relativePath,
|
|
4748
4590
|
symbol: definition.symbol
|
|
4749
4591
|
}))
|
|
@@ -4760,9 +4602,6 @@ function surface(db, modulePattern) {
|
|
|
4760
4602
|
shortName: shortenSymbol(r.symbol)
|
|
4761
4603
|
}));
|
|
4762
4604
|
}
|
|
4763
|
-
function isCallableSymbol2(rawSymbol) {
|
|
4764
|
-
return rawSymbol.endsWith("().") || leafSuffix(rawSymbol) === "method";
|
|
4765
|
-
}
|
|
4766
4605
|
|
|
4767
4606
|
// src/entry-surfaces.ts
|
|
4768
4607
|
var liveBarrelCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -5148,22 +4987,37 @@ function outline(db, filePattern) {
|
|
|
5148
4987
|
ORDER BY d.relative_path, der.start_line`,
|
|
5149
4988
|
...resolvedPaths
|
|
5150
4989
|
);
|
|
4990
|
+
const nodes = rows.map((r) => ({
|
|
4991
|
+
symbol: r.symbol,
|
|
4992
|
+
shortName: shortenSymbol(r.symbol),
|
|
4993
|
+
startLine: r.start_line,
|
|
4994
|
+
endLine: r.end_line,
|
|
4995
|
+
children: []
|
|
4996
|
+
}));
|
|
5151
4997
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
4998
|
+
for (const n of nodes) nodeMap.set(n.symbol, n);
|
|
5152
4999
|
const roots = [];
|
|
5153
|
-
for (
|
|
5154
|
-
const
|
|
5155
|
-
|
|
5156
|
-
shortName: shortenSymbol(r.symbol),
|
|
5157
|
-
startLine: r.start_line,
|
|
5158
|
-
endLine: r.end_line,
|
|
5159
|
-
children: []
|
|
5160
|
-
};
|
|
5161
|
-
nodeMap.set(r.symbol, node);
|
|
5162
|
-
}
|
|
5163
|
-
for (const r of rows) {
|
|
5164
|
-
const node = nodeMap.get(r.symbol);
|
|
5000
|
+
for (let i = 0; i < rows.length; i++) {
|
|
5001
|
+
const r = rows[i];
|
|
5002
|
+
const node = nodes[i];
|
|
5165
5003
|
if (r.enclosing_symbol && nodeMap.has(r.enclosing_symbol)) {
|
|
5166
5004
|
nodeMap.get(r.enclosing_symbol).children.push(node);
|
|
5005
|
+
continue;
|
|
5006
|
+
}
|
|
5007
|
+
let bestParent = null;
|
|
5008
|
+
let bestSize = Infinity;
|
|
5009
|
+
for (const candidate of nodes) {
|
|
5010
|
+
if (candidate === node) continue;
|
|
5011
|
+
if (candidate.startLine <= node.startLine && candidate.endLine >= node.endLine) {
|
|
5012
|
+
const size = candidate.endLine - candidate.startLine;
|
|
5013
|
+
if (size < bestSize) {
|
|
5014
|
+
bestSize = size;
|
|
5015
|
+
bestParent = candidate;
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
}
|
|
5019
|
+
if (bestParent) {
|
|
5020
|
+
bestParent.children.push(node);
|
|
5167
5021
|
} else {
|
|
5168
5022
|
roots.push(node);
|
|
5169
5023
|
}
|
|
@@ -5885,7 +5739,7 @@ function similar(db, symbolPattern, opts = {}) {
|
|
|
5885
5739
|
return similarBySourceShape(db, symbolPattern, { minSimilarity, limit });
|
|
5886
5740
|
}
|
|
5887
5741
|
function similarAll(db, opts = {}) {
|
|
5888
|
-
const { minSimilarity = 0.5, limit = 20, scope, minCallees = 4 } = opts;
|
|
5742
|
+
const { minSimilarity = 0.5, limit = 20, scope, minCallees = 4, crossFileOnly = false } = opts;
|
|
5889
5743
|
const all = getAllCalleeFingerprints(db, { minCallees, scope });
|
|
5890
5744
|
const idfWeights = computeIdf(all);
|
|
5891
5745
|
const results = [];
|
|
@@ -5893,14 +5747,16 @@ function similarAll(db, opts = {}) {
|
|
|
5893
5747
|
for (let j = i + 1; j < all.length; j++) {
|
|
5894
5748
|
const a = all[i];
|
|
5895
5749
|
const b = all[j];
|
|
5896
|
-
if (a.file === b.file) continue;
|
|
5750
|
+
if (crossFileOnly && a.file === b.file) continue;
|
|
5897
5751
|
const { similarity, significantShared } = weightedSimilarity(
|
|
5898
5752
|
a.callees,
|
|
5899
5753
|
b.callees,
|
|
5900
5754
|
idfWeights
|
|
5901
5755
|
);
|
|
5902
5756
|
if (similarity < minSimilarity) continue;
|
|
5903
|
-
|
|
5757
|
+
const sharedCount = intersection(a.callees, b.callees).size;
|
|
5758
|
+
if (significantShared.length < 2 && sharedCount < 4) continue;
|
|
5759
|
+
const displayShared = significantShared.length > 0 ? significantShared : [...intersection(a.callees, b.callees)];
|
|
5904
5760
|
results.push({
|
|
5905
5761
|
symbolA: a.symbol,
|
|
5906
5762
|
shortNameA: shortenSymbol(a.symbol),
|
|
@@ -5909,7 +5765,7 @@ function similarAll(db, opts = {}) {
|
|
|
5909
5765
|
shortNameB: shortenSymbol(b.symbol),
|
|
5910
5766
|
fileB: b.file,
|
|
5911
5767
|
similarity,
|
|
5912
|
-
sharedCallees:
|
|
5768
|
+
sharedCallees: displayShared.map(shortenSymbol),
|
|
5913
5769
|
uniqueToA: [...difference(a.callees, b.callees)].map(shortenSymbol),
|
|
5914
5770
|
uniqueToB: [...difference(b.callees, a.callees)].map(shortenSymbol)
|
|
5915
5771
|
});
|
|
@@ -6539,17 +6395,6 @@ function extractCandidates(db, opts = {}) {
|
|
|
6539
6395
|
results.sort((a, b) => b.clusters.length - a.clusters.length || b.loc - a.loc);
|
|
6540
6396
|
return results.slice(0, limit);
|
|
6541
6397
|
}
|
|
6542
|
-
function getScopedDefinitions(db, scope) {
|
|
6543
|
-
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
6544
|
-
return db.all(
|
|
6545
|
-
`SELECT relative_path
|
|
6546
|
-
FROM documents
|
|
6547
|
-
WHERE 1 = 1
|
|
6548
|
-
${db.pathExclusionsFor("documents")}
|
|
6549
|
-
${scopeFilter}
|
|
6550
|
-
ORDER BY relative_path`
|
|
6551
|
-
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
6552
|
-
}
|
|
6553
6398
|
function definitionLoc(definition) {
|
|
6554
6399
|
return definition.endLine - definition.startLine + 1;
|
|
6555
6400
|
}
|
|
@@ -6993,7 +6838,7 @@ import { basename as basename5, extname as extname4 } from "path";
|
|
|
6993
6838
|
function wrapperCandidates(db, opts) {
|
|
6994
6839
|
const { scope, maxLoc = 15, limit = 30 } = opts ?? {};
|
|
6995
6840
|
const reverseFanIn = buildReverseFileFanIn(buildFileDepGraph(db, scope));
|
|
6996
|
-
const symbols2 =
|
|
6841
|
+
const symbols2 = getScopedDefinitions(db, scope).filter((definition) => definitionLoc2(definition) <= maxLoc && definitionLoc2(definition) >= 2);
|
|
6997
6842
|
const results = [];
|
|
6998
6843
|
for (const symbol of symbols2) {
|
|
6999
6844
|
if (db.isIgnored(symbol.relativePath) || !isFunctionLikeSymbol(symbol.symbol)) continue;
|
|
@@ -7032,17 +6877,6 @@ function wrapperCandidates(db, opts) {
|
|
|
7032
6877
|
function definitionLoc2(definition) {
|
|
7033
6878
|
return definition.endLine - definition.startLine + 1;
|
|
7034
6879
|
}
|
|
7035
|
-
function getScopedDefinitions2(db, scope) {
|
|
7036
|
-
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
7037
|
-
return db.all(
|
|
7038
|
-
`SELECT relative_path
|
|
7039
|
-
FROM documents
|
|
7040
|
-
WHERE 1 = 1
|
|
7041
|
-
${db.pathExclusionsFor("documents")}
|
|
7042
|
-
${scopeFilter}
|
|
7043
|
-
ORDER BY relative_path`
|
|
7044
|
-
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
7045
|
-
}
|
|
7046
6880
|
function dedupeRows(rows) {
|
|
7047
6881
|
const seen = /* @__PURE__ */ new Set();
|
|
7048
6882
|
const unique = [];
|
|
@@ -7092,7 +6926,7 @@ function fallbackCallerFanIn(db, reverseFanIn, callerFile) {
|
|
|
7092
6926
|
// src/queries/passthrough-candidates.ts
|
|
7093
6927
|
function passthroughCandidates(db, opts) {
|
|
7094
6928
|
const { scope, maxLoc = 15, limit = 30 } = opts ?? {};
|
|
7095
|
-
const symbols2 =
|
|
6929
|
+
const symbols2 = getScopedDefinitions(db, scope).filter((definition) => definitionLoc3(definition) >= 3 && definitionLoc3(definition) <= maxLoc);
|
|
7096
6930
|
const results = [];
|
|
7097
6931
|
for (const sym of symbols2) {
|
|
7098
6932
|
if (db.isIgnored(sym.relativePath) || !isFunctionLikeSymbol(sym.symbol)) continue;
|
|
@@ -7121,17 +6955,6 @@ function passthroughCandidates(db, opts) {
|
|
|
7121
6955
|
results.sort((a, b) => a.loc - b.loc || a.file.localeCompare(b.file));
|
|
7122
6956
|
return results.slice(0, limit);
|
|
7123
6957
|
}
|
|
7124
|
-
function getScopedDefinitions3(db, scope) {
|
|
7125
|
-
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
7126
|
-
return db.all(
|
|
7127
|
-
`SELECT relative_path
|
|
7128
|
-
FROM documents
|
|
7129
|
-
WHERE 1 = 1
|
|
7130
|
-
${db.pathExclusionsFor("documents")}
|
|
7131
|
-
${scopeFilter}
|
|
7132
|
-
ORDER BY relative_path`
|
|
7133
|
-
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
7134
|
-
}
|
|
7135
6958
|
function definitionLoc3(definition) {
|
|
7136
6959
|
return definition.endLine - definition.startLine + 1;
|
|
7137
6960
|
}
|
|
@@ -7139,7 +6962,7 @@ function definitionLoc3(definition) {
|
|
|
7139
6962
|
// src/queries/stale-abstractions.ts
|
|
7140
6963
|
function staleAbstractions(db, opts) {
|
|
7141
6964
|
const { scope, minLoc = 3, limit = 30 } = opts ?? {};
|
|
7142
|
-
const rows =
|
|
6965
|
+
const rows = getScopedDefinitions(db, scope).filter((definition) => definition.isTypeLike && definitionLoc4(definition) >= minLoc).map((definition) => ({
|
|
7143
6966
|
symbol: definition.symbol,
|
|
7144
6967
|
file: definition.relativePath,
|
|
7145
6968
|
start_line: definition.startLine,
|
|
@@ -7159,7 +6982,7 @@ function staleAbstractions(db, opts) {
|
|
|
7159
6982
|
})).slice(0, limit);
|
|
7160
6983
|
}
|
|
7161
6984
|
function getFilesWithFunctions(db, scope) {
|
|
7162
|
-
return new Set(
|
|
6985
|
+
return new Set(getScopedDefinitions(db, scope).filter((definition) => definition.isFunctionLike).map((definition) => definition.relativePath));
|
|
7163
6986
|
}
|
|
7164
6987
|
function isTrueStaleAbstraction(row, filesWithFunctions) {
|
|
7165
6988
|
const basename6 = row.file.split("/").pop() ?? "";
|
|
@@ -7172,17 +6995,6 @@ function isTrueStaleAbstraction(row, filesWithFunctions) {
|
|
|
7172
6995
|
}
|
|
7173
6996
|
return true;
|
|
7174
6997
|
}
|
|
7175
|
-
function getScopedDefinitions4(db, scope) {
|
|
7176
|
-
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
7177
|
-
return db.all(
|
|
7178
|
-
`SELECT relative_path
|
|
7179
|
-
FROM documents
|
|
7180
|
-
WHERE 1 = 1
|
|
7181
|
-
${db.pathExclusionsFor("documents")}
|
|
7182
|
-
${scopeFilter}
|
|
7183
|
-
ORDER BY relative_path`
|
|
7184
|
-
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
7185
|
-
}
|
|
7186
6998
|
function countCrossFileConsumers(db, definition) {
|
|
7187
6999
|
const callers = db.all(
|
|
7188
7000
|
`SELECT DISTINCT d.relative_path
|
|
@@ -7590,9 +7402,11 @@ function code(db, symbolPattern, opts = {}) {
|
|
|
7590
7402
|
symbol: match.symbol,
|
|
7591
7403
|
shortName: shortenSymbol(match.symbol),
|
|
7592
7404
|
relativePath: match.relativePath,
|
|
7593
|
-
|
|
7594
|
-
// 1-indexed
|
|
7595
|
-
|
|
7405
|
+
// 0-indexed, like every other query result. The CLI's displayLine()
|
|
7406
|
+
// converts once at render time. Returning 1-indexed here caused a
|
|
7407
|
+
// double-conversion in the CLI and printed labels off by +1.
|
|
7408
|
+
startLine,
|
|
7409
|
+
endLine,
|
|
7596
7410
|
language: doc?.language ?? null,
|
|
7597
7411
|
source
|
|
7598
7412
|
};
|
|
@@ -7620,8 +7434,8 @@ function readFileRange(db, filePath, startLine, endLine, context) {
|
|
|
7620
7434
|
symbol: `${doc.relative_path}:${startLine}-${endLine}`,
|
|
7621
7435
|
shortName: `${doc.relative_path}:${startLine}-${endLine}`,
|
|
7622
7436
|
relativePath: doc.relative_path,
|
|
7623
|
-
startLine: start
|
|
7624
|
-
endLine: end
|
|
7437
|
+
startLine: start,
|
|
7438
|
+
endLine: end,
|
|
7625
7439
|
language: doc.language,
|
|
7626
7440
|
source
|
|
7627
7441
|
};
|
|
@@ -7801,28 +7615,40 @@ function uniqueSymbolRows(rows) {
|
|
|
7801
7615
|
|
|
7802
7616
|
// src/queries/slice.ts
|
|
7803
7617
|
function slice(db, symbolPattern, opts = {}) {
|
|
7804
|
-
const { direction = "backward" } = opts;
|
|
7618
|
+
const { direction = "backward", maxDepth = 3 } = opts;
|
|
7805
7619
|
const match = findFirstSymbolMatch(db, symbolPattern);
|
|
7806
7620
|
if (!match) return null;
|
|
7807
7621
|
if (direction === "backward") {
|
|
7808
|
-
return backwardSlice(db, match);
|
|
7622
|
+
return backwardSlice(db, match, maxDepth);
|
|
7809
7623
|
} else {
|
|
7810
7624
|
return forwardSlice(db, match);
|
|
7811
7625
|
}
|
|
7812
7626
|
}
|
|
7813
|
-
function backwardSlice(db, match) {
|
|
7814
|
-
const callees = getCalleeRowsForSymbol(db, match);
|
|
7815
|
-
const seen = /* @__PURE__ */ new Set();
|
|
7627
|
+
function backwardSlice(db, match, maxDepth) {
|
|
7816
7628
|
const connected = [];
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7629
|
+
const visited = /* @__PURE__ */ new Set([match.symbol]);
|
|
7630
|
+
let frontier = [match];
|
|
7631
|
+
for (let depth = 1; depth <= maxDepth; depth++) {
|
|
7632
|
+
if (frontier.length === 0) break;
|
|
7633
|
+
const nextFrontier = [];
|
|
7634
|
+
for (const current of frontier) {
|
|
7635
|
+
const callees = getCalleeRowsForSymbol(db, current);
|
|
7636
|
+
for (const c of callees) {
|
|
7637
|
+
if (visited.has(c.symbol)) continue;
|
|
7638
|
+
visited.add(c.symbol);
|
|
7639
|
+
connected.push({
|
|
7640
|
+
symbol: c.symbol,
|
|
7641
|
+
shortName: shortenSymbol(c.symbol),
|
|
7642
|
+
file: c.file,
|
|
7643
|
+
relationship: depth === 1 ? "referenced within definition (callee)" : `depth ${depth} callee`
|
|
7644
|
+
});
|
|
7645
|
+
const calleeMatch = findExactSymbolMatch(db, c.symbol);
|
|
7646
|
+
if (calleeMatch && !db.isIgnored(calleeMatch.relativePath)) {
|
|
7647
|
+
nextFrontier.push(calleeMatch);
|
|
7648
|
+
}
|
|
7649
|
+
}
|
|
7650
|
+
}
|
|
7651
|
+
frontier = nextFrontier;
|
|
7826
7652
|
}
|
|
7827
7653
|
return {
|
|
7828
7654
|
symbol: match.symbol,
|
|
@@ -8833,7 +8659,7 @@ program.command("call-graph <symbol>").description("Show incoming callers and ou
|
|
|
8833
8659
|
}
|
|
8834
8660
|
);
|
|
8835
8661
|
});
|
|
8836
|
-
program.command("similar [symbol]").description("Find functions with similar callee fingerprints (consolidation candidates)").option("--min-similarity <n>", "Minimum Jaccard similarity (0-1)", parseFloat, 0.4).option("-n, --limit <n>", "Number of results", parseIntSafe, 20).option("-s, --scope <path>", "Limit to files matching path").option("--min-callees <n>", "Minimum callees to consider", parseIntSafe, 4).action((symbol, opts) => {
|
|
8662
|
+
program.command("similar [symbol]").description("Find functions with similar callee fingerprints (consolidation candidates)").option("--min-similarity <n>", "Minimum Jaccard similarity (0-1)", parseFloat, 0.4).option("-n, --limit <n>", "Number of results", parseIntSafe, 20).option("-s, --scope <path>", "Limit to files matching path").option("--min-callees <n>", "Minimum callees to consider", parseIntSafe, 4).option("--cross-file-only", "Only show cross-file pairs (skip same-file matches)").action((symbol, opts) => {
|
|
8837
8663
|
withDb((db) => {
|
|
8838
8664
|
if (symbol) {
|
|
8839
8665
|
const results = queries.similar(db, symbol, {
|
|
@@ -8858,7 +8684,8 @@ ${Math.round(r.similarity * 100)}% similar:`);
|
|
|
8858
8684
|
minSimilarity: opts.minSimilarity,
|
|
8859
8685
|
limit: opts.limit,
|
|
8860
8686
|
scope: opts.scope,
|
|
8861
|
-
minCallees: opts.minCallees
|
|
8687
|
+
minCallees: opts.minCallees,
|
|
8688
|
+
crossFileOnly: opts.crossFileOnly
|
|
8862
8689
|
});
|
|
8863
8690
|
if (results.length === 0) {
|
|
8864
8691
|
console.log("No similar symbol pairs found.");
|
|
@@ -9253,10 +9080,10 @@ program.command("dataflow <symbol>").description("Reference-level dataflow: defi
|
|
|
9253
9080
|
}
|
|
9254
9081
|
db.close();
|
|
9255
9082
|
});
|
|
9256
|
-
program.command("slice <symbol>").description("Reference-level program slice: what affects this (backward) or what this affects (forward)").option("--forward", "Forward slice (what does this affect). Default is backward.").action((symbol, opts) => {
|
|
9083
|
+
program.command("slice <symbol>").description("Reference-level program slice: what affects this (backward) or what this affects (forward)").option("--forward", "Forward slice (what does this affect). Default is backward.").option("--depth <n>", "Max transitive depth for backward slice", parseIntSafe, 3).action((symbol, opts) => {
|
|
9257
9084
|
const db = openDb();
|
|
9258
9085
|
const direction = opts.forward ? "forward" : "backward";
|
|
9259
|
-
const result = queries.slice(db, symbol, { direction });
|
|
9086
|
+
const result = queries.slice(db, symbol, { direction, maxDepth: opts.depth });
|
|
9260
9087
|
if (!result) {
|
|
9261
9088
|
console.log("Symbol not found.");
|
|
9262
9089
|
db.close();
|