scip-query 0.3.4 → 0.4.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.
- package/README.md +2 -26
- package/dist/{chunk-FYYOWQXK.js → chunk-2F2WH5WQ.js} +19 -36
- package/dist/{chunk-C7H5WBTJ.js → chunk-2UISVZGQ.js} +2 -2
- package/dist/{chunk-HLKAFWWJ.js → chunk-4ZT7UGWW.js} +56 -91
- package/dist/chunk-5AJJGPZE.js +60 -0
- package/dist/chunk-5RKYZSQ6.js +75 -0
- package/dist/chunk-7YBLWIXY.js +115 -0
- package/dist/{chunk-O7Q7FDUJ.js → chunk-A4GWYETB.js} +2 -2
- package/dist/{chunk-CHDJXYBG.js → chunk-A5BGEBM7.js} +2 -2
- package/dist/{chunk-KKCHYLVI.js → chunk-A7YY7IDA.js} +2 -2
- package/dist/chunk-AS7N27JK.js +115 -0
- package/dist/{chunk-F7XU27LU.js → chunk-CQRYLK33.js} +26 -2
- package/dist/{chunk-NFS5W3PP.js → chunk-CQUNEJYM.js} +2 -2
- package/dist/chunk-D4I3ZMN5.js +38 -0
- package/dist/{chunk-J3JSOSUO.js → chunk-E7J7Q7UW.js} +2 -2
- package/dist/{chunk-GEXE2T6I.js → chunk-EOHPASDV.js} +22 -14
- package/dist/chunk-FVH3Y44U.js +1 -0
- package/dist/chunk-GIBETK3W.js +37 -0
- package/dist/{chunk-SMDCNPMK.js → chunk-H3FPW5YN.js} +2 -2
- package/dist/{chunk-GJDHTTR2.js → chunk-HNURMDF4.js} +32 -17
- package/dist/{chunk-7KIMF5PV.js → chunk-HRDPUTIQ.js} +2 -2
- package/dist/{chunk-OIDHN6GD.js → chunk-I2JM34UV.js} +146 -5
- package/dist/{chunk-EPWLXXBL.js → chunk-IV6NZ426.js} +27 -29
- package/dist/{chunk-VT4JBH6L.js → chunk-KDCQJTYW.js} +2 -2
- package/dist/{chunk-5OMVSV6E.js → chunk-LOVDB4C6.js} +2 -2
- package/dist/chunk-MA3B3IUT.js +75 -0
- package/dist/{chunk-26DOJ63W.js → chunk-N2LH3M2P.js} +13 -2
- package/dist/chunk-NWCJWA36.js +162 -0
- package/dist/{chunk-NG5F43OU.js → chunk-P3VCDYMJ.js} +70 -1
- package/dist/{chunk-P3E6L7KW.js → chunk-P42KQKJZ.js} +83 -3
- package/dist/{chunk-YDBXNPYU.js → chunk-PGHN5UTM.js} +2 -2
- package/dist/{chunk-UGQKAVCD.js → chunk-QCYR4S6T.js} +2 -2
- package/dist/chunk-QGCEAVJD.js +2529 -0
- package/dist/{chunk-KBOQX573.js → chunk-RIEA5DOB.js} +19 -2
- package/dist/{chunk-VIYSWZCO.js → chunk-SL674KAW.js} +31 -3
- package/dist/chunk-SRELHCMG.js +110 -0
- package/dist/chunk-UTRKBUCB.js +87 -0
- package/dist/{chunk-HJZUSUPU.js → chunk-VCOJRQPP.js} +5 -5
- package/dist/chunk-VISMEWYP.js +34 -0
- package/dist/{chunk-LFJQVJYJ.js → chunk-VU7FDTWV.js} +2 -2
- package/dist/{chunk-HLUS2HEB.js → chunk-VUBLUTMU.js} +5 -4
- package/dist/{chunk-WGAD3GNR.js → chunk-WNPF2I25.js} +5 -5
- package/dist/{chunk-YY4QGUQ5.js → chunk-X3J4VPWM.js} +2 -2
- package/dist/{chunk-GSH2FPKV.js → chunk-XH56HXLC.js} +2 -2
- package/dist/{chunk-DH7G3DDV.js → chunk-ZU2AQQB5.js} +2 -2
- package/dist/cli.js +2722 -1036
- package/dist/{db-ShvwGDKf.d.ts → db-C4rPbKkI.d.ts} +7 -14
- package/dist/index.d.ts +4 -5
- package/dist/index.js +378 -149
- package/dist/postinstall.js +9 -3
- package/dist/queries/affected.d.ts +1 -1
- package/dist/queries/affected.js +2 -2
- package/dist/queries/bottlenecks.d.ts +1 -1
- package/dist/queries/bottlenecks.js +2 -1
- package/dist/queries/by-kind.d.ts +1 -1
- package/dist/queries/by-kind.js +2 -1
- package/dist/queries/call-graph.d.ts +1 -1
- package/dist/queries/call-graph.js +2 -2
- package/dist/queries/change-surface.d.ts +1 -1
- package/dist/queries/change-surface.js +2 -2
- package/dist/queries/code.d.ts +1 -1
- package/dist/queries/code.js +2 -2
- package/dist/queries/complexity-hotspots.d.ts +1 -1
- package/dist/queries/complexity-hotspots.js +2 -2
- package/dist/queries/complexity.d.ts +1 -1
- package/dist/queries/complexity.js +2 -2
- package/dist/queries/convergence.d.ts +1 -1
- package/dist/queries/convergence.js +2 -2
- package/dist/queries/coupling.d.ts +1 -1
- package/dist/queries/coupling.js +2 -2
- package/dist/queries/cycles.d.ts +1 -1
- package/dist/queries/cycles.js +2 -2
- package/dist/queries/dataflow.d.ts +1 -1
- package/dist/queries/dataflow.js +2 -2
- package/dist/queries/dead.d.ts +1 -1
- package/dist/queries/dead.js +3 -3
- package/dist/queries/deep-chains.d.ts +1 -1
- package/dist/queries/deep-chains.js +2 -2
- package/dist/queries/deps.d.ts +1 -1
- package/dist/queries/deps.js +2 -2
- package/dist/queries/diff-impact.d.ts +1 -1
- package/dist/queries/drift.d.ts +1 -1
- package/dist/queries/drift.js +2 -2
- package/dist/queries/extract-candidates.d.ts +1 -1
- package/dist/queries/extract-candidates.js +2 -2
- package/dist/queries/fan.d.ts +1 -1
- package/dist/queries/fan.js +2 -2
- package/dist/queries/files.d.ts +1 -1
- package/dist/queries/health.d.ts +1 -1
- package/dist/queries/health.js +13 -13
- package/dist/queries/hierarchy.d.ts +1 -1
- package/dist/queries/hierarchy.js +2 -2
- package/dist/queries/hotspots.d.ts +1 -1
- package/dist/queries/hotspots.js +2 -1
- package/dist/queries/imports.d.ts +1 -1
- package/dist/queries/imports.js +2 -2
- package/dist/queries/index.d.ts +1 -2
- package/dist/queries/index.js +49 -53
- package/dist/queries/isolated.d.ts +3 -4
- package/dist/queries/isolated.js +3 -3
- package/dist/queries/members.d.ts +1 -1
- package/dist/queries/members.js +2 -2
- package/dist/queries/methods.d.ts +1 -1
- package/dist/queries/methods.js +2 -1
- package/dist/queries/outline.d.ts +1 -1
- package/dist/queries/outline.js +2 -2
- package/dist/queries/passthrough-candidates.d.ts +1 -1
- package/dist/queries/passthrough-candidates.js +2 -2
- package/dist/queries/redundant-reexports.d.ts +1 -1
- package/dist/queries/redundant-reexports.js +3 -3
- package/dist/queries/refs.d.ts +1 -1
- package/dist/queries/refs.js +2 -2
- package/dist/queries/similar-chains.d.ts +1 -1
- package/dist/queries/similar-chains.js +2 -2
- package/dist/queries/similar-files.d.ts +1 -1
- package/dist/queries/similar-files.js +2 -2
- package/dist/queries/similar-signatures.d.ts +5 -3
- package/dist/queries/similar-signatures.js +2 -1
- package/dist/queries/similar.d.ts +1 -1
- package/dist/queries/similar.js +2 -2
- package/dist/queries/slice.d.ts +1 -1
- package/dist/queries/slice.js +2 -2
- package/dist/queries/stale-abstractions.d.ts +1 -1
- package/dist/queries/stale-abstractions.js +2 -2
- package/dist/queries/stats.d.ts +1 -1
- package/dist/queries/surface.d.ts +1 -1
- package/dist/queries/surface.js +2 -2
- package/dist/queries/symbols.d.ts +1 -1
- package/dist/queries/symbols.js +2 -2
- package/dist/queries/system.d.ts +1 -1
- package/dist/queries/system.js +2 -2
- package/dist/queries/trace.d.ts +1 -1
- package/dist/queries/trace.js +2 -2
- package/dist/queries/wrapper-candidates.d.ts +1 -1
- package/dist/queries/wrapper-candidates.js +2 -2
- package/dist/reindex-worker.js +213 -62
- package/package.json +1 -1
- package/skills/scip-language-playbook/SKILL.md +371 -0
- package/dist/chunk-2UELLEBI.js +0 -1
- package/dist/chunk-4JCSOF2O.js +0 -97
- package/dist/chunk-AXQKUYKF.js +0 -1442
- package/dist/chunk-CPVAQJEC.js +0 -46
- package/dist/chunk-EOROMIFO.js +0 -41
- package/dist/chunk-GU2H5QRN.js +0 -28
- package/dist/chunk-LQJUPXQY.js +0 -109
- package/dist/chunk-MPGIHELS.js +0 -39
- package/dist/chunk-P4WO3BBW.js +0 -64
- package/dist/chunk-TOIEB3LG.js +0 -78
- package/dist/chunk-UQEQ6AHX.js +0 -60
- package/dist/chunk-VJJKSGIX.js +0 -121
- package/dist/chunk-YZ6L7GFO.js +0 -73
- package/dist/chunk-ZEUCXQBN.js +0 -71
- package/dist/queries/doc-coverage.d.ts +0 -14
- package/dist/queries/doc-coverage.js +0 -8
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildFileDepGraph,
|
|
3
|
+
getCallerRowsForSymbol,
|
|
4
|
+
getDefinitionsForFile
|
|
5
|
+
} from "./chunk-QGCEAVJD.js";
|
|
6
|
+
import {
|
|
7
|
+
isFunctionLikeSymbol,
|
|
8
|
+
shortenSymbol
|
|
9
|
+
} from "./chunk-QIXNAB5K.js";
|
|
10
|
+
|
|
11
|
+
// src/queries/wrapper-candidates.ts
|
|
12
|
+
import { basename, extname } from "path";
|
|
13
|
+
function wrapperCandidates(db, opts) {
|
|
14
|
+
const { scope, maxLoc = 15, limit = 30 } = opts ?? {};
|
|
15
|
+
const reverseFanIn = buildReverseFileFanIn(buildFileDepGraph(db, scope));
|
|
16
|
+
const symbols = getScopedDefinitions(db, scope).filter((definition) => definitionLoc(definition) <= maxLoc && definitionLoc(definition) >= 2);
|
|
17
|
+
const results = [];
|
|
18
|
+
for (const symbol of symbols) {
|
|
19
|
+
if (db.isIgnored(symbol.relativePath) || !isFunctionLikeSymbol(symbol.symbol)) continue;
|
|
20
|
+
const symbolStem = basename(symbol.relativePath, extname(symbol.relativePath));
|
|
21
|
+
const callerRows = dedupeRows(
|
|
22
|
+
getCallerRowsForSymbol(db, symbol, { limit: 200 }).filter((row) => row.file !== symbol.relativePath)
|
|
23
|
+
).filter((row) => basename(row.file, extname(row.file)) !== symbolStem);
|
|
24
|
+
if (callerRows.length !== 1) continue;
|
|
25
|
+
const caller = callerRows[0];
|
|
26
|
+
const callerDefinition = getDefinitionsForFile(db, caller.file).find((definition) => definition.symbol === caller.symbol);
|
|
27
|
+
const useDefinitionFanIn = callerDefinition?.isFunctionLike ?? false;
|
|
28
|
+
let callerFanIn;
|
|
29
|
+
if (useDefinitionFanIn && callerDefinition) {
|
|
30
|
+
callerFanIn = new Set(
|
|
31
|
+
getCallerRowsForSymbol(db, callerDefinition, { limit: 500 }).filter((row) => row.file !== callerDefinition.relativePath).map((row) => row.file)
|
|
32
|
+
).size;
|
|
33
|
+
} else {
|
|
34
|
+
callerFanIn = fallbackCallerFanIn(db, reverseFanIn, caller.file);
|
|
35
|
+
}
|
|
36
|
+
if (callerFanIn <= 3) continue;
|
|
37
|
+
results.push({
|
|
38
|
+
symbol: symbol.symbol,
|
|
39
|
+
shortName: shortenSymbol(symbol.symbol),
|
|
40
|
+
file: symbol.relativePath,
|
|
41
|
+
startLine: symbol.startLine,
|
|
42
|
+
endLine: symbol.endLine,
|
|
43
|
+
loc: definitionLoc(symbol),
|
|
44
|
+
singleCaller: caller.symbol,
|
|
45
|
+
singleCallerShort: useDefinitionFanIn ? shortenSymbol(caller.symbol) : basename(caller.file),
|
|
46
|
+
callerFanIn
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
results.sort((left, right) => right.callerFanIn - left.callerFanIn || right.loc - left.loc);
|
|
50
|
+
return results.slice(0, limit);
|
|
51
|
+
}
|
|
52
|
+
function definitionLoc(definition) {
|
|
53
|
+
return definition.endLine - definition.startLine + 1;
|
|
54
|
+
}
|
|
55
|
+
function getScopedDefinitions(db, scope) {
|
|
56
|
+
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
57
|
+
return db.all(
|
|
58
|
+
`SELECT relative_path
|
|
59
|
+
FROM documents
|
|
60
|
+
WHERE 1 = 1
|
|
61
|
+
${db.pathExclusionsFor("documents")}
|
|
62
|
+
${scopeFilter}
|
|
63
|
+
ORDER BY relative_path`
|
|
64
|
+
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
65
|
+
}
|
|
66
|
+
function dedupeRows(rows) {
|
|
67
|
+
const seen = /* @__PURE__ */ new Set();
|
|
68
|
+
const unique = [];
|
|
69
|
+
for (const row of rows) {
|
|
70
|
+
const key = `${row.symbol}|${row.file}`;
|
|
71
|
+
if (seen.has(key)) continue;
|
|
72
|
+
seen.add(key);
|
|
73
|
+
unique.push(row);
|
|
74
|
+
}
|
|
75
|
+
return unique;
|
|
76
|
+
}
|
|
77
|
+
function buildReverseFileFanIn(graph) {
|
|
78
|
+
const reverse = /* @__PURE__ */ new Map();
|
|
79
|
+
for (const [fromFile, deps] of graph) {
|
|
80
|
+
if (!reverse.has(fromFile)) {
|
|
81
|
+
reverse.set(fromFile, reverse.get(fromFile) ?? 0);
|
|
82
|
+
}
|
|
83
|
+
for (const dep of deps) {
|
|
84
|
+
reverse.set(dep, (reverse.get(dep) ?? 0) + 1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return reverse;
|
|
88
|
+
}
|
|
89
|
+
function fallbackCallerFanIn(db, reverseFanIn, callerFile) {
|
|
90
|
+
const functionLikeFanIn = getDefinitionsForFile(db, callerFile).filter((definition) => definition.isFunctionLike).map((definition) => new Set(
|
|
91
|
+
getCallerRowsForSymbol(db, definition, { limit: 500 }).filter((row) => row.file !== definition.relativePath).map((row) => row.file)
|
|
92
|
+
).size).sort((left, right) => right - left)[0] ?? 0;
|
|
93
|
+
if (functionLikeFanIn > 0) {
|
|
94
|
+
return functionLikeFanIn;
|
|
95
|
+
}
|
|
96
|
+
const direct = reverseFanIn.get(callerFile) ?? 0;
|
|
97
|
+
if (direct > 0) {
|
|
98
|
+
return direct;
|
|
99
|
+
}
|
|
100
|
+
const stem = basename(callerFile, extname(callerFile));
|
|
101
|
+
let best = 0;
|
|
102
|
+
for (const [file, fanIn] of reverseFanIn) {
|
|
103
|
+
if (file === callerFile) continue;
|
|
104
|
+
if (basename(file, extname(file)) !== stem) continue;
|
|
105
|
+
if (fanIn > best) {
|
|
106
|
+
best = fanIn;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return best;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
wrapperCandidates
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=chunk-AS7N27JK.js.map
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAllDefinitions,
|
|
3
|
+
getCalleeRowsForSymbol,
|
|
4
|
+
getCallerRowsForSymbol
|
|
5
|
+
} from "./chunk-QGCEAVJD.js";
|
|
1
6
|
import {
|
|
2
7
|
shortenSymbol
|
|
3
8
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -39,7 +44,7 @@ function bottlenecks(db, opts = {}) {
|
|
|
39
44
|
minFanOut,
|
|
40
45
|
limit
|
|
41
46
|
);
|
|
42
|
-
|
|
47
|
+
const indexedResults = rows.filter((r) => !db.isIgnored(r.defined_in)).map((r) => ({
|
|
43
48
|
symbol: r.symbol,
|
|
44
49
|
shortName: shortenSymbol(r.symbol),
|
|
45
50
|
fanIn: r.fan_in,
|
|
@@ -47,9 +52,28 @@ function bottlenecks(db, opts = {}) {
|
|
|
47
52
|
score: r.fan_in * r.fan_out,
|
|
48
53
|
definedIn: r.defined_in
|
|
49
54
|
}));
|
|
55
|
+
if (indexedResults.length > 0) {
|
|
56
|
+
return indexedResults;
|
|
57
|
+
}
|
|
58
|
+
return getAllDefinitions(db, { scope }).filter((definition) => !db.isIgnored(definition.relativePath)).map((definition) => {
|
|
59
|
+
const fanIn = new Set(
|
|
60
|
+
getCallerRowsForSymbol(db, definition, { limit: 500 }).map((row) => row.file)
|
|
61
|
+
).size;
|
|
62
|
+
const fanOut = new Set(
|
|
63
|
+
getCalleeRowsForSymbol(db, definition, { limit: 500 }).filter((row) => row.file !== definition.relativePath).map((row) => `${row.symbol}|${row.file}`)
|
|
64
|
+
).size;
|
|
65
|
+
return {
|
|
66
|
+
symbol: definition.symbol,
|
|
67
|
+
shortName: shortenSymbol(definition.symbol),
|
|
68
|
+
fanIn,
|
|
69
|
+
fanOut,
|
|
70
|
+
score: fanIn * fanOut,
|
|
71
|
+
definedIn: definition.relativePath
|
|
72
|
+
};
|
|
73
|
+
}).filter((row) => row.fanIn >= minFanIn && row.fanOut >= minFanOut).sort((left, right) => right.score - left.score || right.fanIn - left.fanIn).slice(0, limit);
|
|
50
74
|
}
|
|
51
75
|
|
|
52
76
|
export {
|
|
53
77
|
bottlenecks
|
|
54
78
|
};
|
|
55
|
-
//# sourceMappingURL=chunk-
|
|
79
|
+
//# sourceMappingURL=chunk-CQRYLK33.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findFirstSymbolMatch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QGCEAVJD.js";
|
|
4
4
|
import {
|
|
5
5
|
isDirectChildSymbol,
|
|
6
6
|
leafSuffix,
|
|
@@ -34,4 +34,4 @@ function members(db, symbolPattern) {
|
|
|
34
34
|
export {
|
|
35
35
|
members
|
|
36
36
|
};
|
|
37
|
-
//# sourceMappingURL=chunk-
|
|
37
|
+
//# sourceMappingURL=chunk-CQUNEJYM.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cleanSignature
|
|
3
|
+
} from "./chunk-4TYLS5XX.js";
|
|
4
|
+
import {
|
|
5
|
+
getDefinitionsForFile,
|
|
6
|
+
resolveIndexedPaths
|
|
7
|
+
} from "./chunk-QGCEAVJD.js";
|
|
8
|
+
import {
|
|
9
|
+
shortenSymbol
|
|
10
|
+
} from "./chunk-QIXNAB5K.js";
|
|
11
|
+
|
|
12
|
+
// src/queries/symbols.ts
|
|
13
|
+
function symbols(db, filePattern) {
|
|
14
|
+
const resolvedPaths = resolveIndexedPaths(db, filePattern);
|
|
15
|
+
if (resolvedPaths.length === 0) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
return resolvedPaths.flatMap((relativePath) => getDefinitionsForFile(db, relativePath)).filter((row) => !db.isIgnored(row.relativePath)).map((row) => {
|
|
19
|
+
const docRow = db.get(
|
|
20
|
+
`SELECT REPLACE(SUBSTR(documentation, INSTR(documentation, '|') + 1), char(10), ' ') AS sig
|
|
21
|
+
FROM global_symbols
|
|
22
|
+
WHERE id = ?`,
|
|
23
|
+
row.symbolId
|
|
24
|
+
);
|
|
25
|
+
return {
|
|
26
|
+
startLine: row.startLine,
|
|
27
|
+
endLine: row.endLine,
|
|
28
|
+
symbol: row.symbol,
|
|
29
|
+
shortName: shortenSymbol(row.symbol),
|
|
30
|
+
signature: cleanSignature(docRow?.sig ?? null)
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
symbols
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=chunk-D4I3ZMN5.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findFirstSymbolMatch,
|
|
3
3
|
resolveIndexedFile
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QGCEAVJD.js";
|
|
5
5
|
import {
|
|
6
6
|
shortenSymbol
|
|
7
7
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -76,4 +76,4 @@ function readFileRange(db, filePath, startLine, endLine, context) {
|
|
|
76
76
|
export {
|
|
77
77
|
code
|
|
78
78
|
};
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
79
|
+
//# sourceMappingURL=chunk-E7J7Q7UW.js.map
|
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
} from "./chunk-4TYLS5XX.js";
|
|
4
4
|
import {
|
|
5
5
|
findFirstSymbolMatch,
|
|
6
|
-
getSourceReferenceSites
|
|
7
|
-
|
|
6
|
+
getSourceReferenceSites,
|
|
7
|
+
getSourceText
|
|
8
|
+
} from "./chunk-QGCEAVJD.js";
|
|
8
9
|
import {
|
|
9
10
|
isFunctionLikeSymbol,
|
|
10
11
|
shortenSymbol
|
|
@@ -16,24 +17,22 @@ function trace(db, symbolPattern) {
|
|
|
16
17
|
if (!match) {
|
|
17
18
|
return { definitions: [], referencedBy: [] };
|
|
18
19
|
}
|
|
19
|
-
const
|
|
20
|
-
`SELECT
|
|
20
|
+
const definitionMeta = db.get(
|
|
21
|
+
`SELECT
|
|
21
22
|
gs.display_name,
|
|
22
23
|
REPLACE(SUBSTR(gs.documentation, INSTR(gs.documentation, '|') + 1), char(10), ' ') AS sig
|
|
23
24
|
FROM global_symbols gs
|
|
24
|
-
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
25
|
-
JOIN documents d ON der.document_id = d.id
|
|
26
25
|
WHERE gs.id = ?
|
|
27
|
-
ORDER BY d.relative_path, der.start_line
|
|
28
26
|
LIMIT 10`,
|
|
29
27
|
match.symbolId
|
|
30
28
|
);
|
|
31
|
-
const definitions =
|
|
32
|
-
relativePath:
|
|
33
|
-
startLine:
|
|
34
|
-
endLine:
|
|
35
|
-
signature: buildTraceSignature(
|
|
36
|
-
|
|
29
|
+
const definitions = db.isIgnored(match.relativePath) ? [] : [{
|
|
30
|
+
relativePath: match.relativePath,
|
|
31
|
+
startLine: match.startLine,
|
|
32
|
+
endLine: match.endLine,
|
|
33
|
+
signature: buildTraceSignature(definitionMeta?.sig ?? null, definitionMeta?.display_name ?? null, match.symbol),
|
|
34
|
+
source: definitionSource(db, match.relativePath, match.startLine, match.endLine)
|
|
35
|
+
}];
|
|
37
36
|
const sourceSites = getSourceReferenceSites(db, match);
|
|
38
37
|
const referencedBy = sourceSites.length > 0 ? sourceSites.filter((site) => !db.isIgnored(site.file)).map((site) => ({
|
|
39
38
|
relativePath: site.file,
|
|
@@ -66,6 +65,15 @@ function trace(db, symbolPattern) {
|
|
|
66
65
|
}));
|
|
67
66
|
return { definitions, referencedBy };
|
|
68
67
|
}
|
|
68
|
+
function definitionSource(db, relativePath, startLine, endLine) {
|
|
69
|
+
const source = getSourceText(db, relativePath);
|
|
70
|
+
if (!source) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const lines = source.split("\n");
|
|
74
|
+
const slice = lines.slice(startLine, endLine + 1).join("\n").trimEnd();
|
|
75
|
+
return slice.length > 0 ? slice : null;
|
|
76
|
+
}
|
|
69
77
|
function buildTraceSignature(signature, displayName, rawSymbol) {
|
|
70
78
|
const cleaned = cleanSignature(signature);
|
|
71
79
|
if (cleaned && !looksBogusSignature(cleaned)) {
|
|
@@ -84,4 +92,4 @@ function looksBogusSignature(signature) {
|
|
|
84
92
|
export {
|
|
85
93
|
trace
|
|
86
94
|
};
|
|
87
|
-
//# sourceMappingURL=chunk-
|
|
95
|
+
//# sourceMappingURL=chunk-EOHPASDV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-FVH3Y44U.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findFirstSymbolMatch,
|
|
3
|
+
getDefinitionsForFile
|
|
4
|
+
} from "./chunk-QGCEAVJD.js";
|
|
5
|
+
import {
|
|
6
|
+
leafName,
|
|
7
|
+
leafSuffix
|
|
8
|
+
} from "./chunk-QIXNAB5K.js";
|
|
9
|
+
|
|
10
|
+
// src/queries/methods.ts
|
|
11
|
+
import { basename } from "path";
|
|
12
|
+
function methods(db, className) {
|
|
13
|
+
const classMatch = findFirstSymbolMatch(db, className);
|
|
14
|
+
if (!classMatch) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
const ownerName = leafName(classMatch.symbol);
|
|
18
|
+
const definitions = getDefinitionsForFile(db, classMatch.relativePath).filter((definition) => isCallableSymbol(definition.symbol));
|
|
19
|
+
const directMethods = definitions.filter((definition) => definition.parentTypeName === ownerName || definition.symbol.includes(ownerName));
|
|
20
|
+
const fileScopedMethods = directMethods.length > 0 ? directMethods : stripExtension(basename(classMatch.relativePath)) === ownerName ? definitions.filter((definition) => definition.symbol.includes("<invalid-global-code>")) : [];
|
|
21
|
+
return fileScopedMethods.map((definition) => ({
|
|
22
|
+
startLine: definition.startLine,
|
|
23
|
+
endLine: definition.endLine,
|
|
24
|
+
name: leafName(definition.symbol)
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
function isCallableSymbol(rawSymbol) {
|
|
28
|
+
return rawSymbol.endsWith("().") || leafSuffix(rawSymbol) === "method";
|
|
29
|
+
}
|
|
30
|
+
function stripExtension(relativePath) {
|
|
31
|
+
return relativePath.replace(/\.[^.]+$/, "");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export {
|
|
35
|
+
methods
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=chunk-GIBETK3W.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveIndexedFile
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QGCEAVJD.js";
|
|
4
4
|
import {
|
|
5
5
|
shortenSymbol
|
|
6
6
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -68,4 +68,4 @@ function changeSurface(db, filePattern) {
|
|
|
68
68
|
export {
|
|
69
69
|
changeSurface
|
|
70
70
|
};
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-H3FPW5YN.js.map
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
|
+
buildFileDepGraph,
|
|
3
|
+
findFirstSymbolMatch,
|
|
2
4
|
resolveIndexedFile
|
|
3
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QGCEAVJD.js";
|
|
4
6
|
import {
|
|
5
7
|
shortenSymbol
|
|
6
8
|
} from "./chunk-QIXNAB5K.js";
|
|
7
9
|
|
|
8
10
|
// src/queries/fan.ts
|
|
9
11
|
function fanIn(db, symbolPattern) {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
const match = findFirstSymbolMatch(db, symbolPattern);
|
|
13
|
+
if (!match) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const row = db.get(
|
|
17
|
+
`SELECT COUNT(DISTINCT c.document_id) AS file_count
|
|
18
|
+
FROM mentions m
|
|
19
|
+
JOIN chunks c ON m.chunk_id = c.id
|
|
20
|
+
WHERE m.symbol_id = ?
|
|
21
|
+
AND m.role != 1`,
|
|
22
|
+
match.symbolId
|
|
20
23
|
);
|
|
21
|
-
return
|
|
22
|
-
name: shortenSymbol(
|
|
23
|
-
count:
|
|
24
|
-
}
|
|
24
|
+
return [{
|
|
25
|
+
name: shortenSymbol(match.symbol),
|
|
26
|
+
count: row?.file_count ?? 0
|
|
27
|
+
}];
|
|
25
28
|
}
|
|
26
29
|
function fanOut(db, filePattern) {
|
|
27
30
|
const resolvedFile = resolveIndexedFile(db, filePattern);
|
|
@@ -43,10 +46,22 @@ function fanOut(db, filePattern) {
|
|
|
43
46
|
ORDER BY symbol_count DESC`,
|
|
44
47
|
resolvedFile
|
|
45
48
|
);
|
|
46
|
-
|
|
49
|
+
const indexedResults = rows.filter((r) => !db.isIgnored(r.relative_path)).map((r) => ({
|
|
47
50
|
name: r.relative_path,
|
|
48
51
|
count: r.symbol_count
|
|
49
52
|
}));
|
|
53
|
+
if (indexedResults.length > 0) {
|
|
54
|
+
return indexedResults;
|
|
55
|
+
}
|
|
56
|
+
const graph = buildFileDepGraph(db);
|
|
57
|
+
const deps = graph.get(resolvedFile);
|
|
58
|
+
if (!deps || deps.size === 0) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
return [{
|
|
62
|
+
name: resolvedFile,
|
|
63
|
+
count: deps.size
|
|
64
|
+
}];
|
|
50
65
|
}
|
|
51
66
|
function topFanIn(db, opts = {}) {
|
|
52
67
|
const { limit = 30, scope } = opts;
|
|
@@ -106,4 +121,4 @@ export {
|
|
|
106
121
|
topFanIn,
|
|
107
122
|
topFanOut
|
|
108
123
|
};
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
124
|
+
//# sourceMappingURL=chunk-HNURMDF4.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildFileDepGraph
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QGCEAVJD.js";
|
|
4
4
|
|
|
5
5
|
// src/queries/drift.ts
|
|
6
6
|
import path from "path";
|
|
@@ -162,4 +162,4 @@ function isTestLikePath(filePath) {
|
|
|
162
162
|
export {
|
|
163
163
|
drift
|
|
164
164
|
};
|
|
165
|
-
//# sourceMappingURL=chunk-
|
|
165
|
+
//# sourceMappingURL=chunk-HRDPUTIQ.js.map
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findFirstSymbolMatch,
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
getAllDefinitions,
|
|
4
|
+
getCalleeRowsForSymbol,
|
|
5
|
+
getSourceText
|
|
6
|
+
} from "./chunk-QGCEAVJD.js";
|
|
5
7
|
import {
|
|
6
8
|
isFunctionLikeSymbol,
|
|
9
|
+
leafName,
|
|
7
10
|
shortenSymbol
|
|
8
11
|
} from "./chunk-QIXNAB5K.js";
|
|
9
12
|
|
|
@@ -11,7 +14,7 @@ import {
|
|
|
11
14
|
function similar(db, symbolPattern, opts = {}) {
|
|
12
15
|
const { minSimilarity = 0.4, limit = 20 } = opts;
|
|
13
16
|
const target = findCallees(db, symbolPattern);
|
|
14
|
-
if (!target
|
|
17
|
+
if (!target) return [];
|
|
15
18
|
if (!isFunctionLikeSymbol(target.symbol)) return [];
|
|
16
19
|
const candidates = getAllCalleeFingerprints(db, {
|
|
17
20
|
minCallees: 3,
|
|
@@ -43,7 +46,10 @@ function similar(db, symbolPattern, opts = {}) {
|
|
|
43
46
|
});
|
|
44
47
|
}
|
|
45
48
|
results.sort((a, b) => b.similarity - a.similarity);
|
|
46
|
-
|
|
49
|
+
if (results.length > 0) {
|
|
50
|
+
return results.slice(0, limit);
|
|
51
|
+
}
|
|
52
|
+
return similarBySourceShape(db, symbolPattern, { minSimilarity, limit });
|
|
47
53
|
}
|
|
48
54
|
function similarAll(db, opts = {}) {
|
|
49
55
|
const { minSimilarity = 0.5, limit = 20, scope, minCallees = 4 } = opts;
|
|
@@ -190,9 +196,144 @@ function difference(a, b) {
|
|
|
190
196
|
}
|
|
191
197
|
return result;
|
|
192
198
|
}
|
|
199
|
+
function similarBySourceShape(db, symbolPattern, opts) {
|
|
200
|
+
const target = findSourceFingerprint(db, symbolPattern);
|
|
201
|
+
if (!target || target.tokens.size < 3) {
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
const minSimilarity = opts.minSimilarity >= 0.5 ? opts.minSimilarity : 0.3;
|
|
205
|
+
const results = [];
|
|
206
|
+
for (const candidate of getAllSourceFingerprints(db)) {
|
|
207
|
+
if (candidate.symbol === target.symbol || candidate.tokens.size < 3) continue;
|
|
208
|
+
const shared = intersection(target.tokens, candidate.tokens);
|
|
209
|
+
if (shared.size < 2) continue;
|
|
210
|
+
const union = /* @__PURE__ */ new Set([...target.tokens, ...candidate.tokens]);
|
|
211
|
+
const similarity = union.size > 0 ? shared.size / union.size : 0;
|
|
212
|
+
if (similarity < minSimilarity) continue;
|
|
213
|
+
results.push({
|
|
214
|
+
symbolA: target.symbol,
|
|
215
|
+
shortNameA: shortenSymbol(target.symbol),
|
|
216
|
+
fileA: target.file,
|
|
217
|
+
symbolB: candidate.symbol,
|
|
218
|
+
shortNameB: shortenSymbol(candidate.symbol),
|
|
219
|
+
fileB: candidate.file,
|
|
220
|
+
similarity,
|
|
221
|
+
sharedCallees: [...shared].sort(),
|
|
222
|
+
uniqueToA: [...difference(target.tokens, candidate.tokens)].sort(),
|
|
223
|
+
uniqueToB: [...difference(candidate.tokens, target.tokens)].sort()
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
results.sort((a, b) => b.similarity - a.similarity || a.shortNameB.localeCompare(b.shortNameB));
|
|
227
|
+
return results.slice(0, opts.limit);
|
|
228
|
+
}
|
|
229
|
+
function findSourceFingerprint(db, symbolPattern) {
|
|
230
|
+
const match = findFirstSymbolMatch(db, symbolPattern);
|
|
231
|
+
if (!match || !isFunctionLikeSymbol(match.symbol)) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
const snippet = definitionSnippet(db, match.relativePath, match.startLine, match.endLine, leafName(match.symbol));
|
|
235
|
+
const tokens = sourceTokens(snippet, leafName(match.symbol));
|
|
236
|
+
if (tokens.size === 0) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
symbol: match.symbol,
|
|
241
|
+
file: match.relativePath,
|
|
242
|
+
tokens
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function getAllSourceFingerprints(db) {
|
|
246
|
+
return getAllDefinitions(db).filter((definition) => definition.isFunctionLike).map((definition) => ({
|
|
247
|
+
symbol: definition.symbol,
|
|
248
|
+
file: definition.relativePath,
|
|
249
|
+
tokens: sourceTokens(
|
|
250
|
+
definitionSnippet(db, definition.relativePath, definition.startLine, definition.endLine, definition.leaf),
|
|
251
|
+
definition.leaf
|
|
252
|
+
)
|
|
253
|
+
})).filter((fingerprint) => fingerprint.tokens.size > 0);
|
|
254
|
+
}
|
|
255
|
+
function definitionSnippet(db, relativePath, startLine, endLine, leaf) {
|
|
256
|
+
const source = getSourceText(db, relativePath);
|
|
257
|
+
if (!source) {
|
|
258
|
+
return "";
|
|
259
|
+
}
|
|
260
|
+
const lines = source.split("\n");
|
|
261
|
+
if (endLine >= startLine && endLine - startLine <= 12) {
|
|
262
|
+
return lines.slice(startLine, endLine + 1).join("\n");
|
|
263
|
+
}
|
|
264
|
+
const markerPatterns = [
|
|
265
|
+
new RegExp(`\\bdef\\s+${escapeRegex(leaf)}\\b`),
|
|
266
|
+
new RegExp(`\\bfun\\s+${escapeRegex(leaf)}\\b`),
|
|
267
|
+
new RegExp(`\\bfn\\s+${escapeRegex(leaf)}\\b`),
|
|
268
|
+
new RegExp(`\\bfunction\\s+${escapeRegex(leaf)}\\b`),
|
|
269
|
+
new RegExp(`\\b${escapeRegex(leaf)}\\s*\\(`)
|
|
270
|
+
];
|
|
271
|
+
const definitionStart = lines.findIndex((line) => markerPatterns.some((pattern) => pattern.test(line)));
|
|
272
|
+
if (definitionStart >= 0) {
|
|
273
|
+
let definitionEnd = definitionStart;
|
|
274
|
+
for (let index = definitionStart + 1; index < lines.length && index <= definitionStart + 8; index++) {
|
|
275
|
+
const line = lines[index] ?? "";
|
|
276
|
+
if (index > definitionStart && looksLikeDefinitionBoundary(line)) {
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
definitionEnd = index;
|
|
280
|
+
if (line.trim() === "" && index > definitionStart + 1) {
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return lines.slice(definitionStart, definitionEnd + 1).join("\n");
|
|
285
|
+
}
|
|
286
|
+
return lines.slice(startLine, Math.min(lines.length, startLine + 8)).join("\n");
|
|
287
|
+
}
|
|
288
|
+
function sourceTokens(snippet, leaf) {
|
|
289
|
+
if (!snippet) {
|
|
290
|
+
return /* @__PURE__ */ new Set();
|
|
291
|
+
}
|
|
292
|
+
const stopWords = /* @__PURE__ */ new Set([
|
|
293
|
+
"public",
|
|
294
|
+
"private",
|
|
295
|
+
"protected",
|
|
296
|
+
"final",
|
|
297
|
+
"static",
|
|
298
|
+
"class",
|
|
299
|
+
"def",
|
|
300
|
+
"fun",
|
|
301
|
+
"fn",
|
|
302
|
+
"function",
|
|
303
|
+
"return",
|
|
304
|
+
"string",
|
|
305
|
+
"bool",
|
|
306
|
+
"boolean",
|
|
307
|
+
"void",
|
|
308
|
+
"unit",
|
|
309
|
+
"self",
|
|
310
|
+
"this",
|
|
311
|
+
"new",
|
|
312
|
+
"const",
|
|
313
|
+
"let",
|
|
314
|
+
"var",
|
|
315
|
+
"end",
|
|
316
|
+
"pub"
|
|
317
|
+
]);
|
|
318
|
+
const normalizedLeafParts = splitIdentifier(leaf);
|
|
319
|
+
const normalized = snippet.replace(/["'`]/g, " ").replace(/\b\d+\b/g, " NUM ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[^A-Za-z0-9_]+/g, " ").replace(/_/g, " ").toLowerCase();
|
|
320
|
+
const tokens = normalized.split(/\s+/).map((token) => token.trim()).filter((token) => token.length > 1).filter((token) => !stopWords.has(token)).filter((token) => !normalizedLeafParts.has(token));
|
|
321
|
+
return new Set(tokens);
|
|
322
|
+
}
|
|
323
|
+
function splitIdentifier(value) {
|
|
324
|
+
return new Set(
|
|
325
|
+
value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9_]+|_/).map((part) => part.toLowerCase()).filter((part) => part.length > 1)
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
function looksLikeDefinitionBoundary(line) {
|
|
329
|
+
return /^\s*(?:def|fun|fn|function|class|trait|module|object|enum|interface|public|private|protected)\b/.test(line);
|
|
330
|
+
}
|
|
331
|
+
function escapeRegex(value) {
|
|
332
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
333
|
+
}
|
|
193
334
|
|
|
194
335
|
export {
|
|
195
336
|
similar,
|
|
196
337
|
similarAll
|
|
197
338
|
};
|
|
198
|
-
//# sourceMappingURL=chunk-
|
|
339
|
+
//# sourceMappingURL=chunk-I2JM34UV.js.map
|