scip-query 0.3.4 → 0.3.5
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 +1 -26
- package/dist/{chunk-FYYOWQXK.js → chunk-6FKIA6EI.js} +10 -27
- package/dist/{chunk-HLKAFWWJ.js → chunk-EN2Z2CLO.js} +59 -91
- package/dist/chunk-FVH3Y44U.js +1 -0
- package/dist/{chunk-HJZUSUPU.js → chunk-TRESG7OB.js} +4 -4
- package/dist/{chunk-GJDHTTR2.js → chunk-VMM4SYV4.js} +17 -15
- package/dist/{chunk-P4WO3BBW.js → chunk-YGGFLMTM.js} +31 -12
- package/dist/cli.js +109 -225
- package/dist/{db-ShvwGDKf.d.ts → db-viWlyVtv.d.ts} +1 -13
- package/dist/index.d.ts +2 -3
- package/dist/index.js +14 -18
- package/dist/queries/affected.d.ts +1 -1
- package/dist/queries/bottlenecks.d.ts +1 -1
- package/dist/queries/by-kind.d.ts +1 -1
- package/dist/queries/by-kind.js +1 -1
- package/dist/queries/call-graph.d.ts +1 -1
- package/dist/queries/change-surface.d.ts +1 -1
- package/dist/queries/code.d.ts +1 -1
- package/dist/queries/complexity-hotspots.d.ts +1 -1
- package/dist/queries/complexity.d.ts +1 -1
- package/dist/queries/convergence.d.ts +1 -1
- package/dist/queries/convergence.js +1 -1
- package/dist/queries/coupling.d.ts +1 -1
- package/dist/queries/cycles.d.ts +1 -1
- package/dist/queries/dataflow.d.ts +1 -1
- package/dist/queries/dead.d.ts +1 -1
- package/dist/queries/deep-chains.d.ts +1 -1
- package/dist/queries/deps.d.ts +1 -1
- package/dist/queries/diff-impact.d.ts +1 -1
- package/dist/queries/drift.d.ts +1 -1
- package/dist/queries/extract-candidates.d.ts +1 -1
- package/dist/queries/fan.d.ts +1 -1
- package/dist/queries/fan.js +1 -1
- package/dist/queries/files.d.ts +1 -1
- package/dist/queries/health.d.ts +1 -1
- package/dist/queries/health.js +3 -3
- package/dist/queries/hierarchy.d.ts +1 -1
- package/dist/queries/hotspots.d.ts +1 -1
- package/dist/queries/imports.d.ts +1 -1
- package/dist/queries/index.d.ts +1 -2
- package/dist/queries/index.js +14 -18
- package/dist/queries/isolated.d.ts +1 -1
- package/dist/queries/members.d.ts +1 -1
- package/dist/queries/methods.d.ts +1 -1
- package/dist/queries/outline.d.ts +1 -1
- package/dist/queries/passthrough-candidates.d.ts +1 -1
- package/dist/queries/redundant-reexports.d.ts +1 -1
- package/dist/queries/refs.d.ts +1 -1
- package/dist/queries/similar-chains.d.ts +1 -1
- package/dist/queries/similar-files.d.ts +1 -1
- package/dist/queries/similar-signatures.d.ts +1 -1
- package/dist/queries/similar.d.ts +1 -1
- package/dist/queries/slice.d.ts +1 -1
- package/dist/queries/stale-abstractions.d.ts +1 -1
- package/dist/queries/stale-abstractions.js +1 -1
- package/dist/queries/stats.d.ts +1 -1
- package/dist/queries/surface.d.ts +1 -1
- package/dist/queries/symbols.d.ts +1 -1
- package/dist/queries/system.d.ts +1 -1
- package/dist/queries/trace.d.ts +1 -1
- package/dist/queries/wrapper-candidates.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-2UELLEBI.js +0 -1
- package/dist/chunk-YZ6L7GFO.js +0 -73
- package/dist/queries/doc-coverage.d.ts +0 -14
- package/dist/queries/doc-coverage.js +0 -8
package/README.md
CHANGED
|
@@ -487,31 +487,6 @@ scip-query isolated --scope src/utils
|
|
|
487
487
|
|
|
488
488
|
---
|
|
489
489
|
|
|
490
|
-
#### `doc-coverage`
|
|
491
|
-
|
|
492
|
-
Check what percentage of symbols have documentation strings. Lists undocumented symbols.
|
|
493
|
-
|
|
494
|
-
```bash
|
|
495
|
-
scip-query doc-coverage --min-loc 5
|
|
496
|
-
# Documentation coverage: 78%
|
|
497
|
-
# Total symbols: 122
|
|
498
|
-
# Documented: 95
|
|
499
|
-
# Undocumented: 27
|
|
500
|
-
#
|
|
501
|
-
# Undocumented:
|
|
502
|
-
# src/utils/format.ts:15 formatCurrency
|
|
503
|
-
# src/utils/format.ts:28 formatDate
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
**Options:**
|
|
507
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
508
|
-
- `--min-loc <n>` — Minimum LOC to consider (default: 3)
|
|
509
|
-
- `-n, --limit <n>` — Max undocumented symbols to show (default: 50)
|
|
510
|
-
|
|
511
|
-
**Value:** Documentation health check. Focus efforts on the undocumented list.
|
|
512
|
-
|
|
513
|
-
---
|
|
514
|
-
|
|
515
490
|
### Codebase Metrics
|
|
516
491
|
|
|
517
492
|
These commands measure structural properties of the codebase — hotspots, coupling, bottlenecks, fan-in/out.
|
|
@@ -1148,7 +1123,7 @@ scip-query similar-signatures --min-loc 5
|
|
|
1148
1123
|
|
|
1149
1124
|
## Programmatic API
|
|
1150
1125
|
|
|
1151
|
-
All
|
|
1126
|
+
All 49 commands are available as TypeScript functions:
|
|
1152
1127
|
|
|
1153
1128
|
```typescript
|
|
1154
1129
|
import {
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
staleAbstractions
|
|
3
|
-
} from "./chunk-P4WO3BBW.js";
|
|
4
1
|
import {
|
|
5
2
|
stats
|
|
6
3
|
} from "./chunk-74RFWB5T.js";
|
|
7
4
|
import {
|
|
8
5
|
wrapperCandidates
|
|
9
6
|
} from "./chunk-4JCSOF2O.js";
|
|
10
|
-
import {
|
|
11
|
-
passthroughCandidates
|
|
12
|
-
} from "./chunk-ZEUCXQBN.js";
|
|
13
7
|
import {
|
|
14
8
|
similarAll
|
|
15
9
|
} from "./chunk-OIDHN6GD.js";
|
|
10
|
+
import {
|
|
11
|
+
staleAbstractions
|
|
12
|
+
} from "./chunk-YGGFLMTM.js";
|
|
16
13
|
import {
|
|
17
14
|
isolated
|
|
18
15
|
} from "./chunk-UQEQ6AHX.js";
|
|
16
|
+
import {
|
|
17
|
+
passthroughCandidates
|
|
18
|
+
} from "./chunk-ZEUCXQBN.js";
|
|
19
19
|
import {
|
|
20
20
|
drift
|
|
21
21
|
} from "./chunk-7KIMF5PV.js";
|
|
@@ -57,20 +57,7 @@ function health(db, opts = {}) {
|
|
|
57
57
|
const trueIsolatedCount = isolatedResult.filter(
|
|
58
58
|
(s2) => !isEntrySurface(db, s2.relativePath)
|
|
59
59
|
).length;
|
|
60
|
-
const
|
|
61
|
-
db.all(
|
|
62
|
-
`SELECT DISTINCT d.relative_path
|
|
63
|
-
FROM global_symbols gs
|
|
64
|
-
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
65
|
-
JOIN documents d ON der.document_id = d.id
|
|
66
|
-
WHERE gs.symbol LIKE '%().'
|
|
67
|
-
${db.pathExclusionsFor("d")}`
|
|
68
|
-
).map((r) => r.relative_path)
|
|
69
|
-
);
|
|
70
|
-
const trueStaleCount = staleResult.filter((s2) => {
|
|
71
|
-
if (s2.consumers === 0 && filesWithFunctions.has(s2.file)) return false;
|
|
72
|
-
return true;
|
|
73
|
-
}).length;
|
|
60
|
+
const trueStaleCount = staleResult.length;
|
|
74
61
|
const trueDriftCount = driftResult.results.length;
|
|
75
62
|
const trueSimilarCount = similarResult.length;
|
|
76
63
|
const actions = [];
|
|
@@ -145,11 +132,7 @@ function health(db, opts = {}) {
|
|
|
145
132
|
});
|
|
146
133
|
}
|
|
147
134
|
if (trueStaleCount > 0) {
|
|
148
|
-
const
|
|
149
|
-
if (s2.consumers === 0 && filesWithFunctions.has(s2.file)) return false;
|
|
150
|
-
return true;
|
|
151
|
-
});
|
|
152
|
-
const unused = trueStaleSymbols.filter((s2) => s2.consumers === 0).length;
|
|
135
|
+
const unused = staleResult.filter((s2) => s2.consumers === 0).length;
|
|
153
136
|
const singleUse = trueStaleCount - unused;
|
|
154
137
|
const parts = [];
|
|
155
138
|
if (unused > 0) parts.push(`${unused} unused`);
|
|
@@ -160,7 +143,7 @@ function health(db, opts = {}) {
|
|
|
160
143
|
effort: "low",
|
|
161
144
|
impact: "medium",
|
|
162
145
|
count: trueStaleCount,
|
|
163
|
-
locRecoverable: staleResult.
|
|
146
|
+
locRecoverable: staleResult.reduce((sum, r) => sum + r.loc, 0)
|
|
164
147
|
});
|
|
165
148
|
}
|
|
166
149
|
if (trueDriftCount > 0) {
|
|
@@ -235,4 +218,4 @@ function health(db, opts = {}) {
|
|
|
235
218
|
export {
|
|
236
219
|
health
|
|
237
220
|
};
|
|
238
|
-
//# sourceMappingURL=chunk-
|
|
221
|
+
//# sourceMappingURL=chunk-6FKIA6EI.js.map
|
|
@@ -115,102 +115,26 @@ function byKind(db, kindQuery, opts = {}) {
|
|
|
115
115
|
if (kindNum === null) {
|
|
116
116
|
return [];
|
|
117
117
|
}
|
|
118
|
-
const
|
|
119
|
-
const hasKinds = db.get(
|
|
120
|
-
`SELECT COUNT(*) AS c FROM global_symbols WHERE kind IS NOT NULL`
|
|
121
|
-
);
|
|
122
|
-
if (!hasKinds || hasKinds.c === 0) {
|
|
123
|
-
return inferByKind(db, kindNum, scope, limit);
|
|
124
|
-
}
|
|
125
|
-
const rows = db.all(
|
|
126
|
-
`SELECT gs.symbol, gs.kind, d.relative_path, der.start_line, der.end_line
|
|
127
|
-
FROM global_symbols gs
|
|
128
|
-
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
129
|
-
JOIN documents d ON der.document_id = d.id
|
|
130
|
-
WHERE gs.kind = ?
|
|
131
|
-
${db.pathExclusionsFor("d")}
|
|
132
|
-
${scopeFilter}
|
|
133
|
-
ORDER BY d.relative_path, der.start_line
|
|
134
|
-
LIMIT ?`,
|
|
135
|
-
kindNum,
|
|
136
|
-
limit
|
|
137
|
-
);
|
|
138
|
-
return rows.filter((r) => !db.isIgnored(r.relative_path)).map((r) => ({
|
|
139
|
-
symbol: r.symbol,
|
|
140
|
-
shortName: shortenSymbol(r.symbol),
|
|
141
|
-
kind: r.kind,
|
|
142
|
-
kindName: KIND_NAMES[r.kind] ?? "Unknown",
|
|
143
|
-
relativePath: r.relative_path,
|
|
144
|
-
startLine: r.start_line,
|
|
145
|
-
endLine: r.end_line
|
|
146
|
-
}));
|
|
147
|
-
}
|
|
148
|
-
function kindCounts(db, opts = {}) {
|
|
149
|
-
const scopeFilter = opts.scope ? `AND d.relative_path LIKE '%${opts.scope}%'` : "";
|
|
150
|
-
const rows = db.all(
|
|
151
|
-
`SELECT gs.kind, COUNT(*) AS cnt
|
|
152
|
-
FROM global_symbols gs
|
|
153
|
-
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
154
|
-
JOIN documents d ON der.document_id = d.id
|
|
155
|
-
WHERE 1 = 1
|
|
156
|
-
${db.pathExclusionsFor("d")}
|
|
157
|
-
AND gs.kind IS NOT NULL
|
|
158
|
-
AND gs.kind != 0
|
|
159
|
-
${scopeFilter}
|
|
160
|
-
GROUP BY gs.kind
|
|
161
|
-
ORDER BY cnt DESC`
|
|
162
|
-
);
|
|
163
|
-
if (rows.length === 0) {
|
|
164
|
-
return inferKindCounts(db, opts.scope);
|
|
165
|
-
}
|
|
166
|
-
return rows.map((r) => ({
|
|
167
|
-
kind: r.kind,
|
|
168
|
-
kindName: KIND_NAMES[r.kind] ?? "Unknown",
|
|
169
|
-
count: r.cnt
|
|
170
|
-
}));
|
|
171
|
-
}
|
|
172
|
-
function inferByKind(db, kindNum, scope, limit = 100) {
|
|
173
|
-
const scopeFilter = scope ? `AND d.relative_path LIKE '%${scope}%'` : "";
|
|
174
|
-
const rows = db.all(
|
|
175
|
-
`SELECT gs.symbol, d.relative_path, der.start_line, der.end_line, gs.documentation, gs.enclosing_symbol
|
|
176
|
-
FROM global_symbols gs
|
|
177
|
-
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
178
|
-
JOIN documents d ON der.document_id = d.id
|
|
179
|
-
WHERE 1 = 1
|
|
180
|
-
${db.pathExclusionsFor("d")}
|
|
181
|
-
${scopeFilter}
|
|
182
|
-
ORDER BY d.relative_path, der.start_line`
|
|
183
|
-
);
|
|
184
|
-
return rows.filter((row) => !db.isIgnored(row.relative_path)).map((row) => ({
|
|
118
|
+
const rows = loadKindRows(db, scope).map((row) => ({
|
|
185
119
|
row,
|
|
186
|
-
|
|
187
|
-
})).filter((entry) => entry.
|
|
120
|
+
resolvedKind: resolveKindNumber(row)
|
|
121
|
+
})).filter((entry) => entry.resolvedKind === kindNum).slice(0, limit);
|
|
122
|
+
return rows.map(({ row, resolvedKind }) => ({
|
|
188
123
|
symbol: row.symbol,
|
|
189
124
|
shortName: shortenSymbol(row.symbol),
|
|
190
|
-
kind:
|
|
191
|
-
kindName: KIND_NAMES[
|
|
125
|
+
kind: resolvedKind,
|
|
126
|
+
kindName: KIND_NAMES[resolvedKind] ?? "Unknown",
|
|
192
127
|
relativePath: row.relative_path,
|
|
193
128
|
startLine: row.start_line,
|
|
194
129
|
endLine: row.end_line
|
|
195
130
|
}));
|
|
196
131
|
}
|
|
197
|
-
function
|
|
198
|
-
const scopeFilter = scope ? `AND d.relative_path LIKE '%${scope}%'` : "";
|
|
199
|
-
const rows = db.all(
|
|
200
|
-
`SELECT gs.symbol, gs.documentation, gs.enclosing_symbol, d.relative_path
|
|
201
|
-
FROM global_symbols gs
|
|
202
|
-
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
203
|
-
JOIN documents d ON der.document_id = d.id
|
|
204
|
-
WHERE 1 = 1
|
|
205
|
-
${db.pathExclusionsFor("d")}
|
|
206
|
-
${scopeFilter}`
|
|
207
|
-
);
|
|
132
|
+
function kindCounts(db, opts = {}) {
|
|
208
133
|
const counts = /* @__PURE__ */ new Map();
|
|
209
|
-
for (const row of
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
counts.set(inferred, (counts.get(inferred) ?? 0) + 1);
|
|
134
|
+
for (const row of loadKindRows(db, opts.scope)) {
|
|
135
|
+
const kind = resolveKindNumber(row);
|
|
136
|
+
if (kind === null || kind === 0) continue;
|
|
137
|
+
counts.set(kind, (counts.get(kind) ?? 0) + 1);
|
|
214
138
|
}
|
|
215
139
|
return [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0] - b[0]).map(([kind, count]) => ({
|
|
216
140
|
kind,
|
|
@@ -218,22 +142,66 @@ function inferKindCounts(db, scope) {
|
|
|
218
142
|
count
|
|
219
143
|
}));
|
|
220
144
|
}
|
|
145
|
+
function loadKindRows(db, scope) {
|
|
146
|
+
const scopeFilter = scope ? `AND d.relative_path LIKE '%${scope}%'` : "";
|
|
147
|
+
return db.all(
|
|
148
|
+
`SELECT
|
|
149
|
+
gs.symbol,
|
|
150
|
+
gs.kind,
|
|
151
|
+
gs.documentation,
|
|
152
|
+
gs.enclosing_symbol,
|
|
153
|
+
d.relative_path,
|
|
154
|
+
der.start_line,
|
|
155
|
+
der.end_line
|
|
156
|
+
FROM global_symbols gs
|
|
157
|
+
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
158
|
+
JOIN documents d ON der.document_id = d.id
|
|
159
|
+
WHERE 1 = 1
|
|
160
|
+
${db.pathExclusionsFor("d")}
|
|
161
|
+
${scopeFilter}
|
|
162
|
+
ORDER BY d.relative_path, der.start_line`
|
|
163
|
+
).filter((row) => !db.isIgnored(row.relative_path));
|
|
164
|
+
}
|
|
165
|
+
function resolveKindNumber(row) {
|
|
166
|
+
if (row.kind !== null && row.kind !== 0) {
|
|
167
|
+
return normalizeIndexedKind(row.kind, row.symbol, row.documentation);
|
|
168
|
+
}
|
|
169
|
+
return inferKindNumber(row.symbol, row.documentation, row.enclosing_symbol);
|
|
170
|
+
}
|
|
171
|
+
function normalizeIndexedKind(kind, symbol, documentation) {
|
|
172
|
+
const signature = (documentation ?? "").toLowerCase();
|
|
173
|
+
const suffix = leafSuffix(symbol);
|
|
174
|
+
if (suffix === "type") {
|
|
175
|
+
if (signature.includes("type ")) return 76;
|
|
176
|
+
if (signature.includes("interface ")) return 27;
|
|
177
|
+
if (signature.includes("struct ")) return 68;
|
|
178
|
+
if (signature.includes("trait ")) return 73;
|
|
179
|
+
if (signature.includes("class ")) return 9;
|
|
180
|
+
}
|
|
181
|
+
return kind;
|
|
182
|
+
}
|
|
221
183
|
function inferKindNumber(symbol, documentation, enclosingSymbol) {
|
|
222
184
|
const parsed = parseSymbol(symbol);
|
|
223
185
|
if ("kind" in parsed) {
|
|
224
186
|
return null;
|
|
225
187
|
}
|
|
226
188
|
const descriptors = parsed.descriptors;
|
|
227
|
-
const last = descriptors[descriptors.length - 1] ?? null;
|
|
228
189
|
const parent = descriptors[descriptors.length - 2] ?? null;
|
|
229
190
|
const suffix = leafSuffix(symbol);
|
|
230
|
-
|
|
191
|
+
const signature = (documentation ?? "").toLowerCase();
|
|
192
|
+
if (suffix === "type") {
|
|
193
|
+
if (signature.includes("type ")) return 76;
|
|
194
|
+
if (signature.includes("interface ")) return 27;
|
|
195
|
+
if (signature.includes("struct ")) return 68;
|
|
196
|
+
if (signature.includes("trait ")) return 73;
|
|
197
|
+
if (signature.includes("class ")) return 9;
|
|
198
|
+
return 9;
|
|
199
|
+
}
|
|
231
200
|
if (suffix === "method") {
|
|
232
201
|
return parent?.suffix === "type" ? 33 : 23;
|
|
233
202
|
}
|
|
234
203
|
if (suffix === "namespace") return 39;
|
|
235
204
|
if (suffix !== "term") return null;
|
|
236
|
-
const signature = (documentation ?? "").toLowerCase();
|
|
237
205
|
if (signature.includes("async def ") || signature.includes("def ")) {
|
|
238
206
|
return 23;
|
|
239
207
|
}
|
|
@@ -248,4 +216,4 @@ export {
|
|
|
248
216
|
byKind,
|
|
249
217
|
kindCounts
|
|
250
218
|
};
|
|
251
|
-
//# sourceMappingURL=chunk-
|
|
219
|
+
//# sourceMappingURL=chunk-EN2Z2CLO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-FVH3Y44U.js.map
|
|
@@ -37,11 +37,11 @@ function convergence(db, symbolPatternA, symbolPatternB) {
|
|
|
37
37
|
} else if (shared.length === 0) {
|
|
38
38
|
strategy = "These functions do not share any callees. They are not a callee-based consolidation candidate.";
|
|
39
39
|
} else if (uniqueA.length === 0 && uniqueB.length === 0) {
|
|
40
|
-
strategy = "These functions have identical callee sets.
|
|
40
|
+
strategy = "These functions have identical tracked callee sets. They are a strong structural match, but identical callees do not prove interchangeable semantics; inspect signatures, control flow, and return values before consolidating.";
|
|
41
41
|
} else if (uniqueA.length === 0) {
|
|
42
|
-
strategy = `A
|
|
42
|
+
strategy = `A's tracked callees are a subset of B's. B may subsume part of A's structure, but verify signatures, guards, and non-call logic before replacing A with B.`;
|
|
43
43
|
} else if (uniqueB.length === 0) {
|
|
44
|
-
strategy = `B
|
|
44
|
+
strategy = `B's tracked callees are a subset of A's. A may subsume part of B's structure, but verify signatures, guards, and non-call logic before replacing B with A.`;
|
|
45
45
|
} else if (uniqueA.length <= 2 && uniqueB.length <= 2) {
|
|
46
46
|
strategy = `Create a shared function with the ${shared.length} common callees. Pass the ${uniqueA.length + uniqueB.length} divergent callees as parameters or strategy callbacks.`;
|
|
47
47
|
} else {
|
|
@@ -73,4 +73,4 @@ function convergence(db, symbolPatternA, symbolPatternB) {
|
|
|
73
73
|
export {
|
|
74
74
|
convergence
|
|
75
75
|
};
|
|
76
|
-
//# sourceMappingURL=chunk-
|
|
76
|
+
//# sourceMappingURL=chunk-TRESG7OB.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
findFirstSymbolMatch,
|
|
2
3
|
resolveIndexedFile
|
|
3
4
|
} from "./chunk-AXQKUYKF.js";
|
|
4
5
|
import {
|
|
@@ -7,21 +8,22 @@ import {
|
|
|
7
8
|
|
|
8
9
|
// src/queries/fan.ts
|
|
9
10
|
function fanIn(db, symbolPattern) {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
const match = findFirstSymbolMatch(db, symbolPattern);
|
|
12
|
+
if (!match) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
const row = db.get(
|
|
16
|
+
`SELECT COUNT(DISTINCT c.document_id) AS file_count
|
|
17
|
+
FROM mentions m
|
|
18
|
+
JOIN chunks c ON m.chunk_id = c.id
|
|
19
|
+
WHERE m.symbol_id = ?
|
|
20
|
+
AND m.role != 1`,
|
|
21
|
+
match.symbolId
|
|
20
22
|
);
|
|
21
|
-
return
|
|
22
|
-
name: shortenSymbol(
|
|
23
|
-
count:
|
|
24
|
-
}
|
|
23
|
+
return [{
|
|
24
|
+
name: shortenSymbol(match.symbol),
|
|
25
|
+
count: row?.file_count ?? 0
|
|
26
|
+
}];
|
|
25
27
|
}
|
|
26
28
|
function fanOut(db, filePattern) {
|
|
27
29
|
const resolvedFile = resolveIndexedFile(db, filePattern);
|
|
@@ -106,4 +108,4 @@ export {
|
|
|
106
108
|
topFanIn,
|
|
107
109
|
topFanOut
|
|
108
110
|
};
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-VMM4SYV4.js.map
|
|
@@ -37,17 +37,11 @@ function staleAbstractions(db, opts) {
|
|
|
37
37
|
AND (der.end_line - der.start_line + 1) >= ?
|
|
38
38
|
${scopeFilter}
|
|
39
39
|
) WHERE consumers <= 1
|
|
40
|
-
ORDER BY loc DESC
|
|
41
|
-
|
|
42
|
-
minLoc,
|
|
43
|
-
limit
|
|
40
|
+
ORDER BY loc DESC, file ASC, start_line ASC`,
|
|
41
|
+
minLoc
|
|
44
42
|
);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const isTypeFile = basename.includes("types") || r.file.includes("/types/");
|
|
48
|
-
if (isTypeFile && r.consumers > 0) return false;
|
|
49
|
-
return true;
|
|
50
|
-
}).map((r) => ({
|
|
43
|
+
const filesWithFunctions = getFilesWithFunctions(db, scope);
|
|
44
|
+
return rows.filter((r) => !db.isIgnored(r.file)).filter((r) => isTrueStaleAbstraction(r, filesWithFunctions)).map((r) => ({
|
|
51
45
|
symbol: r.symbol,
|
|
52
46
|
shortName: shortenSymbol(r.symbol),
|
|
53
47
|
file: r.file,
|
|
@@ -55,10 +49,35 @@ function staleAbstractions(db, opts) {
|
|
|
55
49
|
endLine: r.end_line,
|
|
56
50
|
loc: r.loc,
|
|
57
51
|
consumers: r.consumers
|
|
58
|
-
}));
|
|
52
|
+
})).slice(0, limit);
|
|
53
|
+
}
|
|
54
|
+
function getFilesWithFunctions(db, scope) {
|
|
55
|
+
const scopeFilter = scope ? `AND d.relative_path LIKE '%${scope}%'` : "";
|
|
56
|
+
return new Set(
|
|
57
|
+
db.all(
|
|
58
|
+
`SELECT DISTINCT d.relative_path
|
|
59
|
+
FROM global_symbols gs
|
|
60
|
+
JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
|
|
61
|
+
JOIN documents d ON der.document_id = d.id
|
|
62
|
+
WHERE gs.symbol LIKE '%().'
|
|
63
|
+
${db.pathExclusionsFor("d")}
|
|
64
|
+
${scopeFilter}`
|
|
65
|
+
).map((row) => row.relative_path).filter((path) => !db.isIgnored(path))
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
function isTrueStaleAbstraction(row, filesWithFunctions) {
|
|
69
|
+
const basename = row.file.split("/").pop() ?? "";
|
|
70
|
+
const isTypeFile = basename.includes("types") || row.file.includes("/types/");
|
|
71
|
+
if (isTypeFile && row.consumers > 0) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (row.consumers === 0 && filesWithFunctions.has(row.file)) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
59
78
|
}
|
|
60
79
|
|
|
61
80
|
export {
|
|
62
81
|
staleAbstractions
|
|
63
82
|
};
|
|
64
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-YGGFLMTM.js.map
|