scip-query 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-HNURMDF4.js → chunk-24LF6IZB.js} +3 -3
  3. package/dist/{chunk-IV6NZ426.js → chunk-3NJSJ7TE.js} +3 -3
  4. package/dist/{chunk-H3FPW5YN.js → chunk-43A4UCS7.js} +3 -3
  5. package/dist/{chunk-A5BGEBM7.js → chunk-5GCORUNV.js} +3 -3
  6. package/dist/{chunk-I2JM34UV.js → chunk-6CH23IAS.js} +4 -4
  7. package/dist/{chunk-5AJJGPZE.js → chunk-6ECR2FLR.js} +3 -3
  8. package/dist/{chunk-2UISVZGQ.js → chunk-6UZU7DFL.js} +3 -3
  9. package/dist/{chunk-NWCJWA36.js → chunk-7BS4CPJX.js} +5 -5
  10. package/dist/{chunk-QCYR4S6T.js → chunk-A6XLXV6W.js} +3 -3
  11. package/dist/{chunk-QGCEAVJD.js → chunk-ALUFWH3U.js} +232 -66
  12. package/dist/{chunk-CQRYLK33.js → chunk-CBIWNZZZ.js} +3 -3
  13. package/dist/{chunk-N2LH3M2P.js → chunk-DUJNJQPO.js} +3 -3
  14. package/dist/{chunk-XH56HXLC.js → chunk-EAGKJFDX.js} +3 -3
  15. package/dist/{chunk-SL674KAW.js → chunk-ELFGD5EW.js} +3 -3
  16. package/dist/{chunk-GIBETK3W.js → chunk-FVJE4MQL.js} +3 -3
  17. package/dist/{chunk-CQUNEJYM.js → chunk-GNAMV3JC.js} +3 -3
  18. package/dist/{chunk-VCOJRQPP.js → chunk-J47VSL6I.js} +3 -3
  19. package/dist/{chunk-7YBLWIXY.js → chunk-J6QXMYAQ.js} +3 -3
  20. package/dist/{chunk-2F2WH5WQ.js → chunk-JHVQB4Y5.js} +12 -12
  21. package/dist/{chunk-X3J4VPWM.js → chunk-JKXHHV4B.js} +2 -2
  22. package/dist/{chunk-4ZT7UGWW.js → chunk-KG4OFQEN.js} +3 -3
  23. package/dist/{chunk-SRELHCMG.js → chunk-KLNKDX6A.js} +4 -4
  24. package/dist/{chunk-LOVDB4C6.js → chunk-KYPXKV64.js} +3 -3
  25. package/dist/{chunk-UTRKBUCB.js → chunk-NXUIWD6K.js} +3 -3
  26. package/dist/{chunk-VU7FDTWV.js → chunk-OXX3QF24.js} +2 -2
  27. package/dist/{chunk-7HK5ZLOE.js → chunk-PCU455MX.js} +2 -2
  28. package/dist/{chunk-A4GWYETB.js → chunk-POLELLNM.js} +3 -3
  29. package/dist/{chunk-AS7N27JK.js → chunk-PU2254N2.js} +3 -3
  30. package/dist/{chunk-WNPF2I25.js → chunk-QMXSLHZP.js} +2 -2
  31. package/dist/{chunk-PGHN5UTM.js → chunk-R7HPHMRZ.js} +3 -3
  32. package/dist/{chunk-VUBLUTMU.js → chunk-RE7POFGI.js} +2 -2
  33. package/dist/{chunk-KDCQJTYW.js → chunk-RJ5GULL6.js} +2 -2
  34. package/dist/{chunk-HRDPUTIQ.js → chunk-RL74LF47.js} +2 -2
  35. package/dist/{chunk-5RKYZSQ6.js → chunk-SVLUJSY7.js} +3 -3
  36. package/dist/{chunk-D4I3ZMN5.js → chunk-SYQR4QGK.js} +3 -3
  37. package/dist/{chunk-QIXNAB5K.js → chunk-TO3L4YNK.js} +1 -2
  38. package/dist/{chunk-P42KQKJZ.js → chunk-TWVXFKJA.js} +4 -4
  39. package/dist/{chunk-MA3B3IUT.js → chunk-UJWI5CBB.js} +3 -3
  40. package/dist/{chunk-E7J7Q7UW.js → chunk-VKBOLNYN.js} +3 -3
  41. package/dist/{chunk-RIEA5DOB.js → chunk-VY2L4TP6.js} +3 -3
  42. package/dist/{chunk-A7YY7IDA.js → chunk-W46L2BXT.js} +2 -2
  43. package/dist/{chunk-VISMEWYP.js → chunk-XUVPQDXW.js} +4 -4
  44. package/dist/{chunk-ZU2AQQB5.js → chunk-Z5VSUOEE.js} +2 -2
  45. package/dist/{chunk-EOHPASDV.js → chunk-ZVZAIIB5.js} +3 -3
  46. package/dist/cli.js +254 -88
  47. package/dist/index.js +47 -46
  48. package/dist/queries/affected.js +3 -3
  49. package/dist/queries/bottlenecks.js +3 -3
  50. package/dist/queries/by-kind.js +3 -3
  51. package/dist/queries/call-graph.js +3 -3
  52. package/dist/queries/change-surface.js +3 -3
  53. package/dist/queries/code.js +3 -3
  54. package/dist/queries/complexity-hotspots.js +3 -3
  55. package/dist/queries/complexity.js +3 -3
  56. package/dist/queries/convergence.js +3 -3
  57. package/dist/queries/coupling.js +3 -3
  58. package/dist/queries/cycles.js +3 -3
  59. package/dist/queries/dataflow.js +3 -3
  60. package/dist/queries/dead.js +4 -4
  61. package/dist/queries/deep-chains.js +3 -3
  62. package/dist/queries/deps.js +3 -3
  63. package/dist/queries/diff-impact.js +2 -2
  64. package/dist/queries/drift.js +3 -3
  65. package/dist/queries/extract-candidates.js +3 -3
  66. package/dist/queries/fan.js +3 -3
  67. package/dist/queries/health.js +14 -14
  68. package/dist/queries/hierarchy.js +3 -3
  69. package/dist/queries/hotspots.js +3 -3
  70. package/dist/queries/imports.js +3 -3
  71. package/dist/queries/index.js +44 -44
  72. package/dist/queries/isolated.js +4 -4
  73. package/dist/queries/members.js +3 -3
  74. package/dist/queries/methods.js +3 -3
  75. package/dist/queries/outline.js +3 -3
  76. package/dist/queries/passthrough-candidates.js +3 -3
  77. package/dist/queries/redundant-reexports.js +4 -4
  78. package/dist/queries/refs.js +3 -3
  79. package/dist/queries/similar-chains.js +3 -3
  80. package/dist/queries/similar-files.js +3 -3
  81. package/dist/queries/similar-signatures.js +3 -3
  82. package/dist/queries/similar.js +3 -3
  83. package/dist/queries/slice.js +3 -3
  84. package/dist/queries/stale-abstractions.js +3 -3
  85. package/dist/queries/surface.js +3 -3
  86. package/dist/queries/symbols.js +3 -3
  87. package/dist/queries/system.js +3 -3
  88. package/dist/queries/trace.js +3 -3
  89. package/dist/queries/wrapper-candidates.js +3 -3
  90. package/dist/reindex-worker.js +3 -2
  91. package/package.json +5 -1
package/README.md CHANGED
@@ -62,7 +62,7 @@ For Python, the npm package is `scip-python-plus`. Depending on which version yo
62
62
  2. The `scip` CLI converts the protobuf to a SQLite database (`index.db`).
63
63
  3. `scip-query` runs SQL queries against that database to answer questions about your codebase.
64
64
 
65
- Because the index comes from the real compiler, results are precise — not grep-based approximations. A reference to `login()` in file A is provably the same `login()` defined in file B, not just a string match.
65
+ Because the index comes from the real compiler, direct symbol, definition, and reference queries are precise — not grep-based approximations. When a language index is missing enough call-site detail for higher-level analyses, `scip-query` can fall back to source parsing and identifier recovery so those commands stay useful, but they should be treated as source-backed heuristics rather than compiler-proof facts.
66
66
 
67
67
  ## Configuration
68
68
 
@@ -2,10 +2,10 @@ import {
2
2
  buildFileDepGraph,
3
3
  findFirstSymbolMatch,
4
4
  resolveIndexedFile
5
- } from "./chunk-QGCEAVJD.js";
5
+ } from "./chunk-ALUFWH3U.js";
6
6
  import {
7
7
  shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
8
+ } from "./chunk-TO3L4YNK.js";
9
9
 
10
10
  // src/queries/fan.ts
11
11
  function fanIn(db, symbolPattern) {
@@ -121,4 +121,4 @@ export {
121
121
  topFanIn,
122
122
  topFanOut
123
123
  };
124
- //# sourceMappingURL=chunk-HNURMDF4.js.map
124
+ //# sourceMappingURL=chunk-24LF6IZB.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getCalleeRowsForSymbol,
3
3
  getDefinitionsForFile
4
- } from "./chunk-QGCEAVJD.js";
4
+ } from "./chunk-ALUFWH3U.js";
5
5
  import {
6
6
  isFunctionLikeSymbol,
7
7
  shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
8
+ } from "./chunk-TO3L4YNK.js";
9
9
 
10
10
  // src/queries/extract-candidates.ts
11
11
  function extractCandidates(db, opts = {}) {
@@ -109,4 +109,4 @@ function definitionLoc(definition) {
109
109
  export {
110
110
  extractCandidates
111
111
  };
112
- //# sourceMappingURL=chunk-IV6NZ426.js.map
112
+ //# sourceMappingURL=chunk-3NJSJ7TE.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  resolveIndexedFile
3
- } from "./chunk-QGCEAVJD.js";
3
+ } from "./chunk-ALUFWH3U.js";
4
4
  import {
5
5
  shortenSymbol
6
- } from "./chunk-QIXNAB5K.js";
6
+ } from "./chunk-TO3L4YNK.js";
7
7
 
8
8
  // src/queries/change-surface.ts
9
9
  function changeSurface(db, filePattern) {
@@ -68,4 +68,4 @@ function changeSurface(db, filePattern) {
68
68
  export {
69
69
  changeSurface
70
70
  };
71
- //# sourceMappingURL=chunk-H3FPW5YN.js.map
71
+ //# sourceMappingURL=chunk-43A4UCS7.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  findFirstSymbolMatch,
3
3
  getCalleeRowsForSymbol
4
- } from "./chunk-QGCEAVJD.js";
4
+ } from "./chunk-ALUFWH3U.js";
5
5
  import {
6
6
  shortenSymbol
7
- } from "./chunk-QIXNAB5K.js";
7
+ } from "./chunk-TO3L4YNK.js";
8
8
 
9
9
  // src/queries/slice.ts
10
10
  function slice(db, symbolPattern, opts = {}) {
@@ -97,4 +97,4 @@ function forwardSlice(db, match) {
97
97
  export {
98
98
  slice
99
99
  };
100
- //# sourceMappingURL=chunk-A5BGEBM7.js.map
100
+ //# sourceMappingURL=chunk-5GCORUNV.js.map
@@ -3,12 +3,12 @@ import {
3
3
  getAllDefinitions,
4
4
  getCalleeRowsForSymbol,
5
5
  getSourceText
6
- } from "./chunk-QGCEAVJD.js";
6
+ } from "./chunk-ALUFWH3U.js";
7
7
  import {
8
8
  isFunctionLikeSymbol,
9
9
  leafName,
10
10
  shortenSymbol
11
- } from "./chunk-QIXNAB5K.js";
11
+ } from "./chunk-TO3L4YNK.js";
12
12
 
13
13
  // src/queries/similar.ts
14
14
  function similar(db, symbolPattern, opts = {}) {
@@ -25,7 +25,7 @@ function similar(db, symbolPattern, opts = {}) {
25
25
  const results = [];
26
26
  for (const candidate of candidates) {
27
27
  if (candidate.callees.size < 3) continue;
28
- const { similarity, significantShared, trivialShared } = weightedSimilarity(
28
+ const { similarity, significantShared } = weightedSimilarity(
29
29
  target.callees,
30
30
  candidate.callees,
31
31
  idfWeights
@@ -336,4 +336,4 @@ export {
336
336
  similar,
337
337
  similarAll
338
338
  };
339
- //# sourceMappingURL=chunk-I2JM34UV.js.map
339
+ //# sourceMappingURL=chunk-6CH23IAS.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getCalleeRowsForSymbol,
3
3
  getDefinitionsForFile
4
- } from "./chunk-QGCEAVJD.js";
4
+ } from "./chunk-ALUFWH3U.js";
5
5
  import {
6
6
  isFunctionLikeSymbol,
7
7
  shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
8
+ } from "./chunk-TO3L4YNK.js";
9
9
 
10
10
  // src/queries/passthrough-candidates.ts
11
11
  function passthroughCandidates(db, opts) {
@@ -57,4 +57,4 @@ function definitionLoc(definition) {
57
57
  export {
58
58
  passthroughCandidates
59
59
  };
60
- //# sourceMappingURL=chunk-5AJJGPZE.js.map
60
+ //# sourceMappingURL=chunk-6ECR2FLR.js.map
@@ -2,10 +2,10 @@ import {
2
2
  findFirstSymbolMatch,
3
3
  getCalleeRowsForSymbol,
4
4
  getCallerRowsForSymbol
5
- } from "./chunk-QGCEAVJD.js";
5
+ } from "./chunk-ALUFWH3U.js";
6
6
  import {
7
7
  shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
8
+ } from "./chunk-TO3L4YNK.js";
9
9
 
10
10
  // src/queries/call-graph.ts
11
11
  function callGraph(db, symbolPattern) {
@@ -43,4 +43,4 @@ function uniqueRows(rows) {
43
43
  export {
44
44
  callGraph
45
45
  };
46
- //# sourceMappingURL=chunk-2UISVZGQ.js.map
46
+ //# sourceMappingURL=chunk-6UZU7DFL.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  getAllDefinitions,
3
3
  getSourceText
4
- } from "./chunk-QGCEAVJD.js";
4
+ } from "./chunk-ALUFWH3U.js";
5
5
  import {
6
6
  shortenSymbol
7
- } from "./chunk-QIXNAB5K.js";
7
+ } from "./chunk-TO3L4YNK.js";
8
8
 
9
9
  // src/queries/similar-signatures.ts
10
10
  function similarSignatures(db, opts = {}) {
@@ -103,7 +103,7 @@ function normalizeSignature(raw) {
103
103
  }
104
104
  function normalizeSourceSignature(raw, leaf) {
105
105
  if (!raw || !raw.trim()) return null;
106
- let declaration = raw.replace(/\s+/g, " ").trim();
106
+ const declaration = raw.replace(/\s+/g, " ").trim();
107
107
  const parenIdx = declaration.indexOf("(");
108
108
  if (parenIdx === -1) return null;
109
109
  let prefix = declaration.slice(0, parenIdx);
@@ -113,7 +113,7 @@ function normalizeSourceSignature(raw, leaf) {
113
113
  prefix = prefix.slice(0, leafMatch.index);
114
114
  }
115
115
  prefix = prefix.replace(/\b(public|private|protected|internal|final|static|abstract|sealed|virtual|override|async|suspend|inline|constexpr|consteval|constinit|const|pub|fn|function|def|sub|friend|shared|readonly|new|open|partial|export)\b/gi, " ").replace(/\s+/g, " ").trim();
116
- let suffix = declaration.slice(parenIdx).replace(/\s*\{[\s\S]*$/, "").replace(/\s*=>[\s\S]*$/, "").replace(/\)\s*=\s*[\s\S]*$/, ")").replace(/\s+throws\s+[^={]+$/i, "").replace(/\s+where\s+.+$/i, "").replace(/\s+/g, " ").trim();
116
+ const suffix = declaration.slice(parenIdx).replace(/\s*\{[\s\S]*$/, "").replace(/\s*=>[\s\S]*$/, "").replace(/\)\s*=\s*[\s\S]*$/, ")").replace(/\s+throws\s+[^={]+$/i, "").replace(/\s+where\s+.+$/i, "").replace(/\s+/g, " ").trim();
117
117
  if (!suffix.startsWith("(")) {
118
118
  return null;
119
119
  }
@@ -159,4 +159,4 @@ function escapeRegex(value) {
159
159
  export {
160
160
  similarSignatures
161
161
  };
162
- //# sourceMappingURL=chunk-NWCJWA36.js.map
162
+ //# sourceMappingURL=chunk-7BS4CPJX.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  findFirstSymbolMatch,
3
3
  getCalleeRowsForSymbol
4
- } from "./chunk-QGCEAVJD.js";
4
+ } from "./chunk-ALUFWH3U.js";
5
5
  import {
6
6
  shortenSymbol
7
- } from "./chunk-QIXNAB5K.js";
7
+ } from "./chunk-TO3L4YNK.js";
8
8
 
9
9
  // src/queries/complexity.ts
10
10
  import { readFileSync } from "fs";
@@ -107,4 +107,4 @@ function stripCommentsAndStrings(source) {
107
107
  export {
108
108
  complexity
109
109
  };
110
- //# sourceMappingURL=chunk-QCYR4S6T.js.map
110
+ //# sourceMappingURL=chunk-A6XLXV6W.js.map
@@ -5,7 +5,7 @@ import {
5
5
  leafSuffix,
6
6
  parseSymbol,
7
7
  shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
8
+ } from "./chunk-TO3L4YNK.js";
9
9
 
10
10
  // src/source-analysis.ts
11
11
  import {
@@ -1190,6 +1190,10 @@ function buildFileDepGraph(db, scope) {
1190
1190
  return graph;
1191
1191
  }
1192
1192
  function findFirstSymbolMatch(db, symbolPattern) {
1193
+ const exact = findExactSymbolMatch(db, symbolPattern.trim());
1194
+ if (exact) {
1195
+ return exact;
1196
+ }
1193
1197
  const fileLineMatch = symbolPattern.match(/^(.+):(\d+)-(\d+)$/);
1194
1198
  if (fileLineMatch) {
1195
1199
  const [, filePath, startStr, endStr] = fileLineMatch;
@@ -1227,19 +1231,16 @@ function findFirstSymbolMatch(db, symbolPattern) {
1227
1231
  );
1228
1232
  }
1229
1233
  if (row && !db.isIgnored(row.relative_path)) {
1230
- return {
1231
- symbolId: row.id,
1232
- symbol: row.symbol,
1233
- documentId: row.document_id,
1234
- startLine: row.start_line,
1235
- endLine: row.end_line,
1236
- relativePath: row.relative_path
1237
- };
1234
+ return hydrateSymbolMatch(db, row);
1238
1235
  }
1239
1236
  }
1240
1237
  const cleaned = normalizeLookupPattern(symbolPattern);
1241
1238
  const tokens = lookupTokens(symbolPattern);
1242
1239
  const candidates = getSymbolLookupCandidates(db, tokens);
1240
+ const direct = findDirectSymbolCandidate(candidates, symbolPattern, cleaned);
1241
+ if (direct && !db.isIgnored(direct.relative_path)) {
1242
+ return hydrateSymbolMatch(db, direct);
1243
+ }
1243
1244
  let best = null;
1244
1245
  for (const row of candidates) {
1245
1246
  if (db.isIgnored(row.relative_path)) continue;
@@ -1250,14 +1251,7 @@ function findFirstSymbolMatch(db, symbolPattern) {
1250
1251
  }
1251
1252
  }
1252
1253
  if (best) {
1253
- return {
1254
- symbolId: best.row.id,
1255
- symbol: best.row.symbol,
1256
- documentId: best.row.document_id,
1257
- startLine: best.row.start_line,
1258
- endLine: best.row.end_line,
1259
- relativePath: best.row.relative_path
1260
- };
1254
+ return hydrateSymbolMatch(db, best.row);
1261
1255
  }
1262
1256
  return null;
1263
1257
  }
@@ -1276,14 +1270,7 @@ function findExactSymbolMatch(db, symbol) {
1276
1270
  if (!row || db.isIgnored(row.relative_path)) {
1277
1271
  return null;
1278
1272
  }
1279
- return {
1280
- symbolId: row.id,
1281
- symbol: row.symbol,
1282
- documentId: row.document_id,
1283
- startLine: row.start_line,
1284
- endLine: row.end_line,
1285
- relativePath: row.relative_path
1286
- };
1273
+ return hydrateSymbolMatch(db, row);
1287
1274
  }
1288
1275
  function resolveIndexedFile(db, filePattern) {
1289
1276
  return resolveDocumentCandidates(db, filePattern, { allowMultiple: false })[0]?.relativePath ?? null;
@@ -1424,27 +1411,10 @@ function getCalleeRowsForSymbol(db, symbol, opts = {}) {
1424
1411
  });
1425
1412
  }
1426
1413
  const sourceFallback = getSourceBackedCalleeRows(db, symbol, opts.limit);
1427
- if (sourceFallback.length === 0) {
1428
- return primary;
1429
- }
1430
- if (primary.length === 0) {
1414
+ if (sourceFallback.length > 0) {
1431
1415
  return applyLimit(sourceFallback, opts.limit);
1432
1416
  }
1433
- const merged = [...sourceFallback];
1434
- const seen = new Set(merged.map((row) => `${row.symbol}|${row.file}`));
1435
- const preferredFallbackLeaves = new Set(
1436
- sourceFallback.filter((row) => !isLikelyTestPath(row.file)).map((row) => leafName(row.symbol))
1437
- );
1438
- for (const row of primary) {
1439
- if (isLikelyTestPath(row.file) && preferredFallbackLeaves.has(leafName(row.symbol))) {
1440
- continue;
1441
- }
1442
- const key = `${row.symbol}|${row.file}`;
1443
- if (seen.has(key)) continue;
1444
- seen.add(key);
1445
- merged.push(row);
1446
- }
1447
- return applyLimit(merged, opts.limit);
1417
+ return primary;
1448
1418
  }
1449
1419
  function getCallerRowsForSymbol(db, symbol, opts = {}) {
1450
1420
  const match = getFullSymbolMatch(db, symbol);
@@ -1477,11 +1447,13 @@ function getCallerRowsForSymbol(db, symbol, opts = {}) {
1477
1447
  ...getGenericSourceCallerRows(db, match, opts.limit)
1478
1448
  ]);
1479
1449
  if (sourceFallback.length === 0) {
1480
- return primary;
1450
+ return dedupeCallerRows(primary);
1481
1451
  }
1482
1452
  const merged = [...sourceFallback];
1453
+ const fallbackFiles = new Set(sourceFallback.map((row) => row.file));
1483
1454
  const seen = new Set(merged.map((row) => `${row.symbol}|${row.file}`));
1484
1455
  for (const row of primary) {
1456
+ if (fallbackFiles.has(row.file)) continue;
1485
1457
  const key = `${row.symbol}|${row.file}`;
1486
1458
  if (seen.has(key)) continue;
1487
1459
  if (isFunctionLikeSymbol(row.symbol) || merged.length === 0) {
@@ -1862,14 +1834,7 @@ function getFullSymbolMatch(db, symbol) {
1862
1834
  if (!row) {
1863
1835
  return null;
1864
1836
  }
1865
- return {
1866
- symbolId: row.id,
1867
- documentId: row.document_id,
1868
- startLine: row.start_line,
1869
- endLine: row.end_line,
1870
- symbol: row.symbol,
1871
- relativePath: row.relative_path
1872
- };
1837
+ return hydrateSymbolMatch(db, row);
1873
1838
  }
1874
1839
  function getDefinitionsForFile(db, relativePath) {
1875
1840
  let cache = FILE_DEFINITION_CACHE.get(db);
@@ -1889,6 +1854,7 @@ function getDefinitionsForFile(db, relativePath) {
1889
1854
  der.start_line,
1890
1855
  der.end_line,
1891
1856
  d.relative_path,
1857
+ gs.display_name,
1892
1858
  gs.kind,
1893
1859
  gs.documentation,
1894
1860
  gs.enclosing_symbol
@@ -1908,6 +1874,7 @@ function getDefinitionsForFile(db, relativePath) {
1908
1874
  MIN(c.start_line) AS start_line,
1909
1875
  MAX(c.end_line) AS end_line,
1910
1876
  d.relative_path,
1877
+ gs.display_name,
1911
1878
  gs.kind,
1912
1879
  gs.documentation,
1913
1880
  gs.enclosing_symbol
@@ -1922,23 +1889,222 @@ function getDefinitionsForFile(db, relativePath) {
1922
1889
  ORDER BY start_line, end_line`,
1923
1890
  relativePath
1924
1891
  );
1925
- const definitions = (primary.length > 0 ? primary : fallback).map((row) => ({
1892
+ const definitions = correctDefinitionRangesFromSource(
1893
+ db,
1894
+ relativePath,
1895
+ (primary.length > 0 ? primary : fallback).map((row) => ({
1896
+ symbolId: row.id,
1897
+ symbol: row.symbol,
1898
+ documentId: row.document_id,
1899
+ startLine: row.start_line,
1900
+ endLine: row.end_line,
1901
+ relativePath: row.relative_path,
1902
+ leaf: leafName(row.symbol),
1903
+ parentTypeName: parentTypeName(row.symbol),
1904
+ isFunctionLike: isFunctionLikeSymbol(row.symbol),
1905
+ isTypeLike: leafSuffix(row.symbol) === "type",
1906
+ kind: row.kind ?? null,
1907
+ documentation: row.documentation ?? null,
1908
+ enclosingSymbol: row.enclosing_symbol ?? null
1909
+ }))
1910
+ );
1911
+ cache.set(relativePath, definitions);
1912
+ return definitions;
1913
+ }
1914
+ function hydrateSymbolMatch(db, row) {
1915
+ const corrected = getDefinitionsForFile(db, row.relative_path).find((definition) => definition.symbolId === row.id);
1916
+ if (corrected) {
1917
+ return {
1918
+ symbolId: corrected.symbolId,
1919
+ symbol: corrected.symbol,
1920
+ documentId: corrected.documentId,
1921
+ startLine: corrected.startLine,
1922
+ endLine: corrected.endLine,
1923
+ relativePath: corrected.relativePath
1924
+ };
1925
+ }
1926
+ return {
1926
1927
  symbolId: row.id,
1927
1928
  symbol: row.symbol,
1928
1929
  documentId: row.document_id,
1929
1930
  startLine: row.start_line,
1930
1931
  endLine: row.end_line,
1931
- relativePath: row.relative_path,
1932
- leaf: leafName(row.symbol),
1933
- parentTypeName: parentTypeName(row.symbol),
1934
- isFunctionLike: isFunctionLikeSymbol(row.symbol),
1935
- isTypeLike: leafSuffix(row.symbol) === "type",
1936
- kind: row.kind,
1937
- documentation: row.documentation,
1938
- enclosingSymbol: row.enclosing_symbol
1939
- }));
1940
- cache.set(relativePath, definitions);
1941
- return definitions;
1932
+ relativePath: row.relative_path
1933
+ };
1934
+ }
1935
+ function findDirectSymbolCandidate(candidates, symbolPattern, cleanedPattern) {
1936
+ const trimmed = symbolPattern.trim();
1937
+ const directMatches = candidates.filter((row) => {
1938
+ const short = shortenSymbol(row.symbol);
1939
+ const display = (row.display_name ?? "").trim();
1940
+ return row.symbol === trimmed || short === trimmed || short === cleanedPattern || display === trimmed || display === cleanedPattern || `${display}()` === trimmed || row.relative_path === trimmed;
1941
+ });
1942
+ if (directMatches.length === 0) {
1943
+ return null;
1944
+ }
1945
+ directMatches.sort(
1946
+ (left, right) => left.end_line - left.start_line - (right.end_line - right.start_line) || left.relative_path.localeCompare(right.relative_path) || left.symbol.localeCompare(right.symbol)
1947
+ );
1948
+ return directMatches[0] ?? null;
1949
+ }
1950
+ function correctDefinitionRangesFromSource(db, relativePath, definitions) {
1951
+ const source = getSourceText(db, relativePath);
1952
+ if (!source) {
1953
+ return definitions;
1954
+ }
1955
+ const lines = source.split(/\r?\n/);
1956
+ const correctedStarts = /* @__PURE__ */ new Map();
1957
+ for (const definition of definitions) {
1958
+ correctedStarts.set(
1959
+ definition.symbolId,
1960
+ resolveCallableDefinitionStartLine(lines, definition)
1961
+ );
1962
+ }
1963
+ const correctedRanges = /* @__PURE__ */ new Map();
1964
+ const callableDefinitions = definitions.filter((definition) => isCallableDefinition(definition.symbol)).map((definition) => ({
1965
+ definition,
1966
+ startLine: correctedStarts.get(definition.symbolId) ?? definition.startLine
1967
+ })).sort(
1968
+ (left, right) => left.startLine - right.startLine || left.definition.startLine - right.definition.startLine || left.definition.symbol.localeCompare(right.definition.symbol)
1969
+ );
1970
+ for (let index = 0; index < callableDefinitions.length; index += 1) {
1971
+ const current = callableDefinitions[index];
1972
+ const next = callableDefinitions[index + 1];
1973
+ const maxEndLine = next ? Math.max(current.startLine, next.startLine - 1) : lines.length - 1;
1974
+ correctedRanges.set(current.definition.symbolId, {
1975
+ startLine: current.startLine,
1976
+ endLine: resolveCallableDefinitionEndLine(
1977
+ lines,
1978
+ current.definition,
1979
+ current.startLine,
1980
+ maxEndLine
1981
+ )
1982
+ });
1983
+ }
1984
+ return definitions.map((definition) => {
1985
+ const corrected = correctedRanges.get(definition.symbolId);
1986
+ if (!corrected) {
1987
+ return definition;
1988
+ }
1989
+ return {
1990
+ ...definition,
1991
+ startLine: corrected.startLine,
1992
+ endLine: corrected.endLine
1993
+ };
1994
+ });
1995
+ }
1996
+ function resolveCallableDefinitionStartLine(lines, definition) {
1997
+ if (!isCallableDefinition(definition.symbol)) {
1998
+ return definition.startLine;
1999
+ }
2000
+ const escapedLeaf = escapeRegex2(definition.leaf);
2001
+ const strongPatterns = [
2002
+ new RegExp(`\\b(?:function|def|fn)\\s+${escapedLeaf}\\b`),
2003
+ new RegExp(`\\b${escapedLeaf}\\b\\s*[:=]\\s*(?:async\\s*)?(?:function\\b|\\()`)
2004
+ ];
2005
+ const fallbackPatterns = [
2006
+ new RegExp(`\\b${escapedLeaf}\\b\\s*\\(`)
2007
+ ];
2008
+ return findNearestMatchingLine(
2009
+ lines,
2010
+ [...strongPatterns, ...fallbackPatterns],
2011
+ definition.startLine,
2012
+ definition.endLine
2013
+ );
2014
+ }
2015
+ function findNearestMatchingLine(lines, patterns, preferredStartLine, preferredEndLine) {
2016
+ const windowStart = Math.max(0, preferredStartLine - 40);
2017
+ const windowEnd = Math.min(lines.length - 1, Math.max(preferredEndLine + 40, preferredStartLine + 5));
2018
+ const windowMatch = matchNearestLine(lines, patterns, preferredStartLine, windowStart, windowEnd);
2019
+ if (windowMatch !== null) {
2020
+ return windowMatch;
2021
+ }
2022
+ const fullMatch = matchNearestLine(lines, patterns, preferredStartLine, 0, lines.length - 1);
2023
+ return fullMatch ?? Math.max(0, Math.min(preferredStartLine, lines.length - 1));
2024
+ }
2025
+ function matchNearestLine(lines, patterns, preferredLine, startLine, endLine) {
2026
+ let best = null;
2027
+ for (let lineIndex = startLine; lineIndex <= endLine; lineIndex += 1) {
2028
+ const line = lines[lineIndex] ?? "";
2029
+ if (!patterns.some((pattern) => pattern.test(line))) continue;
2030
+ const distance = Math.abs(lineIndex - preferredLine);
2031
+ if (!best || distance < best.distance) {
2032
+ best = { line: lineIndex, distance };
2033
+ }
2034
+ }
2035
+ return best?.line ?? null;
2036
+ }
2037
+ function resolveCallableDefinitionEndLine(lines, definition, startLine, maxEndLine) {
2038
+ const boundedEndLine = Math.max(startLine, Math.min(lines.length - 1, maxEndLine));
2039
+ const fallbackEndLine = Math.max(startLine, Math.min(boundedEndLine, definition.endLine));
2040
+ let braceDepth = 0;
2041
+ let parenDepth = 0;
2042
+ let sawOpeningBrace = false;
2043
+ for (let lineIndex = startLine; lineIndex <= boundedEndLine; lineIndex += 1) {
2044
+ const masked = maskStructuralLine(lines[lineIndex] ?? "");
2045
+ for (const char of masked) {
2046
+ if (char === "{") {
2047
+ braceDepth += 1;
2048
+ sawOpeningBrace = true;
2049
+ } else if (char === "}") {
2050
+ braceDepth = Math.max(0, braceDepth - 1);
2051
+ } else if (char === "(") {
2052
+ parenDepth += 1;
2053
+ } else if (char === ")") {
2054
+ parenDepth = Math.max(0, parenDepth - 1);
2055
+ }
2056
+ }
2057
+ if (sawOpeningBrace && braceDepth === 0) {
2058
+ return lineIndex;
2059
+ }
2060
+ if (!sawOpeningBrace && parenDepth === 0 && lineIndex >= fallbackEndLine) {
2061
+ return lineIndex;
2062
+ }
2063
+ }
2064
+ return fallbackEndLine;
2065
+ }
2066
+ function maskStructuralLine(line) {
2067
+ let masked = "";
2068
+ let quote = null;
2069
+ let escaping = false;
2070
+ for (let index = 0; index < line.length; index += 1) {
2071
+ const char = line[index];
2072
+ const next = line[index + 1];
2073
+ if (!quote && char === "/" && next === "/") {
2074
+ masked += " ".repeat(line.length - index);
2075
+ break;
2076
+ }
2077
+ if (quote) {
2078
+ if (escaping) {
2079
+ escaping = false;
2080
+ masked += " ";
2081
+ continue;
2082
+ }
2083
+ if (char === "\\") {
2084
+ escaping = true;
2085
+ masked += " ";
2086
+ continue;
2087
+ }
2088
+ if (char === quote) {
2089
+ quote = null;
2090
+ }
2091
+ masked += " ";
2092
+ continue;
2093
+ }
2094
+ if (char === '"' || char === "'" || char === "`") {
2095
+ quote = char;
2096
+ masked += " ";
2097
+ continue;
2098
+ }
2099
+ masked += char;
2100
+ }
2101
+ return masked;
2102
+ }
2103
+ function isCallableDefinition(symbol) {
2104
+ return symbol.includes("().");
2105
+ }
2106
+ function escapeRegex2(value) {
2107
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1942
2108
  }
1943
2109
  function getAllDefinitions(db, opts = {}) {
1944
2110
  const { scope } = opts;
@@ -2526,4 +2692,4 @@ export {
2526
2692
  getDefinitionsForFile,
2527
2693
  getAllDefinitions
2528
2694
  };
2529
- //# sourceMappingURL=chunk-QGCEAVJD.js.map
2695
+ //# sourceMappingURL=chunk-ALUFWH3U.js.map
@@ -2,10 +2,10 @@ import {
2
2
  getAllDefinitions,
3
3
  getCalleeRowsForSymbol,
4
4
  getCallerRowsForSymbol
5
- } from "./chunk-QGCEAVJD.js";
5
+ } from "./chunk-ALUFWH3U.js";
6
6
  import {
7
7
  shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
8
+ } from "./chunk-TO3L4YNK.js";
9
9
 
10
10
  // src/queries/bottlenecks.ts
11
11
  function bottlenecks(db, opts = {}) {
@@ -76,4 +76,4 @@ function bottlenecks(db, opts = {}) {
76
76
  export {
77
77
  bottlenecks
78
78
  };
79
- //# sourceMappingURL=chunk-CQRYLK33.js.map
79
+ //# sourceMappingURL=chunk-CBIWNZZZ.js.map
@@ -2,12 +2,12 @@ import {
2
2
  findFirstSymbolMatch,
3
3
  getSourceImports,
4
4
  resolveIndexedFile
5
- } from "./chunk-QGCEAVJD.js";
5
+ } from "./chunk-ALUFWH3U.js";
6
6
  import {
7
7
  isModuleLikeSymbol,
8
8
  leafName,
9
9
  shortenSymbol
10
- } from "./chunk-QIXNAB5K.js";
10
+ } from "./chunk-TO3L4YNK.js";
11
11
 
12
12
  // src/queries/imports.ts
13
13
  function imports(db, filePattern) {
@@ -169,4 +169,4 @@ export {
169
169
  importedBy,
170
170
  unusedImports
171
171
  };
172
- //# sourceMappingURL=chunk-N2LH3M2P.js.map
172
+ //# sourceMappingURL=chunk-DUJNJQPO.js.map
@@ -2,10 +2,10 @@ import {
2
2
  findFirstSymbolMatch,
3
3
  getCalleeRowsForSymbol,
4
4
  getSourceReferenceSites
5
- } from "./chunk-QGCEAVJD.js";
5
+ } from "./chunk-ALUFWH3U.js";
6
6
  import {
7
7
  shortenSymbol
8
- } from "./chunk-QIXNAB5K.js";
8
+ } from "./chunk-TO3L4YNK.js";
9
9
 
10
10
  // src/queries/dataflow.ts
11
11
  function dataflow(db, symbolPattern) {
@@ -84,4 +84,4 @@ function uniqueSymbolRows(rows) {
84
84
  export {
85
85
  dataflow
86
86
  };
87
- //# sourceMappingURL=chunk-XH56HXLC.js.map
87
+ //# sourceMappingURL=chunk-EAGKJFDX.js.map