@remnic/coding-graph 9.6.36 → 9.6.38

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.
@@ -1474,6 +1474,97 @@ var GraphStore = class _GraphStore {
1474
1474
  return failure;
1475
1475
  }
1476
1476
  }
1477
+ /**
1478
+ * Find the innermost node whose span contains a byte offset in a file
1479
+ * (issue #1917). Used by the LSP resolution pass's NodeLocator to map
1480
+ * definition locations back to indexed nodes. Returns the node's
1481
+ * qualified name, or null when no node contains the offset.
1482
+ */
1483
+ findNodeBySpan(filePath, byteOffset) {
1484
+ if (this.closed) return null;
1485
+ try {
1486
+ const rows = expectRows(
1487
+ this.db.prepare(
1488
+ `SELECT n.qualified_name, (n.span_end - n.span_start) AS size FROM nodes n
1489
+ JOIN files f ON n.file_id = f.id
1490
+ WHERE f.path = ? AND n.span_start <= ? AND n.span_end > ?
1491
+ ORDER BY size ASC
1492
+ LIMIT 2`
1493
+ ).all(filePath, byteOffset, byteOffset),
1494
+ ["qualified_name", "size"]
1495
+ );
1496
+ if (rows.length === 0) return null;
1497
+ if (rows.length > 1 && rows[1] !== void 0 && rows[0].size === rows[1].size) return null;
1498
+ const qualifiedName = rows[0].qualified_name;
1499
+ const dupRow = expectRow(
1500
+ this.db.prepare(`SELECT COUNT(*) AS n FROM nodes WHERE qualified_name = ?`).get(qualifiedName),
1501
+ ["n"]
1502
+ );
1503
+ if (dupRow && dupRow.n > 1) return null;
1504
+ return qualifiedName;
1505
+ } catch {
1506
+ return null;
1507
+ }
1508
+ }
1509
+ /**
1510
+ * Callee NAMES already linked from a caller symbol via CALLS edges of a
1511
+ * given provenance (issue #1917 wiring). The LSP pass uses this to skip
1512
+ * call sites Phase A (provenance "heuristic") already resolved WITHOUT
1513
+ * also skipping sites whose only edge is a prior "lsp" edge — those must
1514
+ * be re-asserted each run or reconciliation would retire them.
1515
+ */
1516
+ resolvedCalleeNames(srcQualifiedName, provenance, filePath) {
1517
+ if (this.closed) return [];
1518
+ try {
1519
+ const fileClause = filePath !== void 0 ? " AND f.path = ?" : "";
1520
+ const bind = filePath !== void 0 ? [srcQualifiedName, provenance, filePath] : [srcQualifiedName, provenance];
1521
+ const rows = expectRows(
1522
+ this.db.prepare(
1523
+ `SELECT DISTINCT dn.name AS name FROM edges e
1524
+ JOIN nodes sn ON e.src = sn.id
1525
+ JOIN files f ON sn.file_id = f.id
1526
+ JOIN nodes dn ON e.dst = dn.id
1527
+ WHERE sn.qualified_name = ? AND e.type = 'CALLS' AND e.provenance = ?${fileClause}`
1528
+ ).all(...bind),
1529
+ ["name"]
1530
+ );
1531
+ return rows.map((r) => r.name);
1532
+ } catch {
1533
+ return [];
1534
+ }
1535
+ }
1536
+ /**
1537
+ * Current CALLS edges of a given provenance owned by a caller symbol in
1538
+ * a file (#1923 review threads). The LSP pass uses this two ways:
1539
+ * provenance "lsp" lists a filtered caller's existing lsp edges, and
1540
+ * provenance "heuristic" lists its current Phase-A resolutions — an lsp
1541
+ * edge is preserved at reconcile time only when it duplicates a current
1542
+ * heuristic resolution (same dst), so removed member calls' edges retire
1543
+ * while a filtered bare call's covering edge survives.
1544
+ */
1545
+ callEdgesForCaller(srcQualifiedName, filePath, provenance) {
1546
+ if (this.closed) return [];
1547
+ try {
1548
+ const rows = expectRows(
1549
+ this.db.prepare(
1550
+ `SELECT sn.qualified_name AS src_q, dn.qualified_name AS dst_q, dn.name AS dst_n, e.type AS type FROM edges e
1551
+ JOIN nodes sn ON e.src = sn.id
1552
+ JOIN files f ON sn.file_id = f.id
1553
+ JOIN nodes dn ON e.dst = dn.id
1554
+ WHERE sn.qualified_name = ? AND f.path = ? AND e.provenance = ? AND e.type = 'CALLS'`
1555
+ ).all(srcQualifiedName, filePath, provenance),
1556
+ ["src_q", "dst_q", "dst_n", "type"]
1557
+ );
1558
+ return rows.map((r) => ({
1559
+ srcQualifiedName: r.src_q,
1560
+ dstQualifiedName: r.dst_q,
1561
+ dstName: r.dst_n,
1562
+ type: r.type
1563
+ }));
1564
+ } catch {
1565
+ return [];
1566
+ }
1567
+ }
1477
1568
  /**
1478
1569
  * Read a symbol's source span from disk. The store NEVER persists
1479
1570
  * file contents (privacy + DB size — issue #1552 design); this
@@ -1973,4 +2064,4 @@ export {
1973
2064
  GraphStore,
1974
2065
  nodeIdFor
1975
2066
  };
1976
- //# sourceMappingURL=chunk-ABDBWCXU.js.map
2067
+ //# sourceMappingURL=chunk-I56SG643.js.map