Skip to content

Commit 5d3a71b

Browse files
committed
fix: address review feedback on graph model
- getCallableNodes now queries all 10 CORE_SYMBOL_KINDS, not just 3 (fixes function-level cycle detection regression for interfaces, structs, enums, traits, records, modules, types) - edgeCount returns logical edge count for undirected graphs (was 2x) - Remove duplicate branches in toGraphology
1 parent 412874a commit 5d3a71b

3 files changed

Lines changed: 11 additions & 16 deletions

File tree

src/db/repository/graph-read.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { CORE_SYMBOL_KINDS } from '../../kinds.js';
12
import { cachedStmt } from './cached-stmt.js';
23

34
// ─── Statement caches (one prepared statement per db instance) ────────────
@@ -6,16 +7,18 @@ const _getCallEdgesStmt = new WeakMap();
67
const _getFileNodesAllStmt = new WeakMap();
78
const _getImportEdgesStmt = new WeakMap();
89

10+
const CALLABLE_KINDS_SQL = CORE_SYMBOL_KINDS.map((k) => `'${k}'`).join(',');
11+
912
/**
10-
* Get callable nodes (function/method/class) for community detection.
13+
* Get callable nodes (all core symbol kinds) for graph construction.
1114
* @param {object} db
1215
* @returns {{ id: number, name: string, kind: string, file: string }[]}
1316
*/
1417
export function getCallableNodes(db) {
1518
return cachedStmt(
1619
_getCallableNodesStmt,
1720
db,
18-
"SELECT id, name, kind, file FROM nodes WHERE kind IN ('function','method','class')",
21+
`SELECT id, name, kind, file FROM nodes WHERE kind IN (${CALLABLE_KINDS_SQL})`,
1922
).all();
2023
}
2124

src/graph/model.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export class CodeGraph {
3232
get edgeCount() {
3333
let count = 0;
3434
for (const targets of this._successors.values()) count += targets.size;
35-
return count;
35+
// Undirected graphs store each edge twice (a→b and b→a)
36+
return this._directed ? count : count / 2;
3637
}
3738

3839
// ─── Node operations ────────────────────────────────────────────
@@ -195,17 +196,9 @@ export class CodeGraph {
195196
g.addNode(id);
196197
}
197198

198-
if (type === 'undirected') {
199-
// Deduplicate: only add each unordered pair once
200-
for (const [src, tgt] of this.edges()) {
201-
if (src === tgt) continue;
202-
if (!g.hasEdge(src, tgt)) g.addEdge(src, tgt);
203-
}
204-
} else {
205-
for (const [src, tgt] of this.edges()) {
206-
if (src === tgt) continue;
207-
if (!g.hasEdge(src, tgt)) g.addEdge(src, tgt);
208-
}
199+
for (const [src, tgt] of this.edges()) {
200+
if (src === tgt) continue;
201+
if (!g.hasEdge(src, tgt)) g.addEdge(src, tgt);
209202
}
210203
return g;
211204
}

tests/graph/model.test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,7 @@ describe('CodeGraph — undirected', () => {
9494
const g = new CodeGraph({ directed: false });
9595
g.addEdge('a', 'b');
9696
g.addEdge('b', 'c');
97-
expect(g.edgeCount).toBe(4); // 2 directed entries per undirected edge
98-
// But edges() iterator deduplicates
97+
expect(g.edgeCount).toBe(2);
9998
expect([...g.edges()]).toHaveLength(2);
10099
});
101100
});

0 commit comments

Comments
 (0)