CodeGraph/docs
Section 4.5

Circular Dependency Analysis

Global detection of circular import dependencies, mutual recursion, and constructor cycles across 5 isolated projections using Tarjan's Strongly Connected Components algorithm.

Source: server/src/analytics/cycles/CycleAnalyzer.ts

5 Isolated Cycle Projections

Circular dependencies in a code graph represent distinct architectural violations depending on the entities involved. CodeGraph evaluates cycles across 5 isolated projections:

CycleTypeNode KindEdge KindArchitectural Violation
"file-import"file"imports"Circular module imports leading to undefined export bindings at runtime.
"symbol-call"symbol"calls"Mutual recursion between functions leading to potential stack overflows.
"symbol-inheritance"symbol"extends"Circular class inheritance (illegal in JS/TS type systems).
"symbol-implementation"symbol"implements"Circular interface implementation loops.
"symbol-instantiation"symbol"instantiates"Mutually instantiating factory constructors.

Self-Loop & Multi-Node Filtering

Tarjan's algorithm outputs strongly connected components (SCCs). The analyzer filters out trivial 1-node components unless they exhibit a self-loop (e.g. direct recursion):

server/src/analytics/cycles/CycleAnalyzer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private isCyclic(component: string[], relationshipKind: RelationshipKind): boolean { if (component.length > 1) return true; // Multi-node SCC is always a cycle // Single-node: only cyclic if it contains a self-loop const nodeId = component[0]; const edgeIds = this.graph.outgoingEdges.get(nodeId) ?? []; return [...edgeIds].some((edgeId) => { const edge = this.graph.edges.get(edgeId); return ( edge !== undefined && edge.relationshipKind === relationshipKind && edge.targetId === nodeId // Self-loop ); }); }
Algorithmic Detail
For a deep dive into the mathematical low-link formulation and DFS stack management of Tarjan's SCC, see Section 5.2: Tarjan's Strongly Connected Components.