`callers <Class>` returned "No callers found" (or only the importing file) even when a class's constructor was called from many sites, and the instantiation sites were invisible — the opposite of what "what breaks if I change this class?" should answer. The `instantiates` edges already existed in the graph, correctly attributed to the constructing function; they were simply excluded from the caller/callee traversal, which queried only calls/references/imports. Constructing a class is calling its constructor, so add `instantiates` to the edge-kind set in both getCallers and getCallees (kept symmetric so they stay inverses and `trace` can cross the instantiation boundary, function -> class -> its methods). impact already traversed all edge kinds, so it was unaffected. Query-layer only — existing indexes benefit on upgrade with no re-index. Verified on a Python fixture: `callers Supervisor` now returns the construction sites (main/work/test_it), and a new graph test asserts main() <-> DerivedClass via the instantiation. Full suite green. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9a0f144770
commit
d0e649969a
+11
-2
@@ -248,7 +248,12 @@ export class GraphTraverser {
|
||||
}
|
||||
visited.add(nodeId);
|
||||
|
||||
const incomingEdges = this.queries.getIncomingEdges(nodeId, ['calls', 'references', 'imports']);
|
||||
// `instantiates` counts as a caller: constructing a class (`Foo(...)` /
|
||||
// `new Foo()`) is calling its constructor, so the instantiation site is a
|
||||
// caller of the class. Without it, `callers <Class>` surfaced only the
|
||||
// importing file (via `imports`) and missed every construction site —
|
||||
// the opposite of "what breaks if I change this class?" (#774).
|
||||
const incomingEdges = this.queries.getIncomingEdges(nodeId, ['calls', 'references', 'imports', 'instantiates']);
|
||||
if (incomingEdges.length === 0) return;
|
||||
|
||||
// Batch-fetch all caller nodes in one round-trip instead of one
|
||||
@@ -293,7 +298,11 @@ export class GraphTraverser {
|
||||
}
|
||||
visited.add(nodeId);
|
||||
|
||||
const outgoingEdges = this.queries.getOutgoingEdges(nodeId, ['calls', 'references', 'imports']);
|
||||
// Symmetric with getCallers: a function that constructs a class
|
||||
// (`Foo(...)` / `new Foo()`) has that class as a callee, so callers and
|
||||
// callees stay inverses of each other and `trace` can cross the
|
||||
// instantiation boundary (function → class → its methods) (#774).
|
||||
const outgoingEdges = this.queries.getOutgoingEdges(nodeId, ['calls', 'references', 'imports', 'instantiates']);
|
||||
if (outgoingEdges.length === 0) return;
|
||||
|
||||
// Batch-fetch callee nodes (was N+1 — see getCallersRecursive note).
|
||||
|
||||
Reference in New Issue
Block a user