How Flow Detection in code-review-graph Traces Execution Paths from Entry Points
Flow detection in code-review-graph performs a bidirectional breadth-first search from changed files, traversing call graphs and dependency relationships up to a configurable depth to map complete execution paths and identify impacted code.
The code-review-graph VS Code extension analyzes pull request impact by treating modified files as graph entry points and walking the codebase dependency graph stored in SQLite. This article examines the SqliteReader.getImpactRadius() implementation to explain how the system traces execution paths through function calls, imports, inheritance, and test relationships to surface the complete blast radius of any code change.
From Changed Files to Seed Nodes
Flow detection begins when the system identifies modified files in a pull request or working directory. In code-review-graph-vscode/src/backend/sqlite.ts, the algorithm initializes by converting these file paths into seed nodes—the qualified names of every function, class, and symbol defined within the changed files.
The getImpactRadius() method collects these seeds into a Set<string> to ensure uniqueness and O(1) lookups during traversal【L44-L48】. These seeds represent the entry points from which the algorithm will explore both downstream dependencies (functions called by the changed code) and upstream dependencies (functions that call the changed code).
Bidirectional BFS Traversal in getImpactRadius
The core traversal engine resides in SqliteReader.getImpactRadius() within sqlite.ts. The method implements a breadth-first search (BFS) that expands simultaneously in both directions through the dependency graph.
For each node in the current frontier, the algorithm queries the SQLite database for:
- Outgoing edges via
getEdgesBySource()to find downstream dependencies - Incoming edges via
getEdgesByTarget()to find upstream dependents
Unvisited nodes discovered through either direction are added to the next frontier level and accumulated in the impacted set【L58-L76】. This bidirectional approach ensures the detection captures complete execution paths regardless of whether the change affects callers or callees.
Relationship Types That Drive Flow Detection
The BFS follows seven distinct relationship types defined in sqlite.ts that represent different execution and dependency paths【L45-L52】:
CALLS– Function and method invocationsIMPORTS_FROM– Module import dependenciesINHERITS– Class inheritance hierarchiesIMPLEMENTS– Interface implementationsCONTAINS– Parent-child relationships (classes containing methods)TESTED_BY– Test coverage mappingsDEPENDS_ON– General dependency declarations
By traversing all edge types simultaneously, the algorithm constructs a comprehensive view of how changes propagate through runtime execution, static imports, object-oriented hierarchies, and test suites.
Bounding the Search with Maximum Depth
To maintain performance in large codebases, the algorithm accepts a maxDepth parameter that defaults to 2 levels【L40-L42】. This bounds the BFS to immediate neighbors and their direct connections, preventing exponential explosion while still capturing the most likely impact radius. When maxDepth is reached, the frontier expansion stops regardless of whether unvisited nodes remain in the queue.
Resolving Nodes and Building the Impact Graph
After completing the traversal, the system distinguishes between direct changes and transitive impacts. The raw impacted set is resolved back to full node objects, creating two distinct collections:
changedNodes– The original seed nodes representing code actually modifiedimpactedNodes– Transitively reached nodes excluding the seeds themselves【L82-L94】
The method then constructs the edges array containing only the relationships that connect nodes within the impact radius【L99-L103】. This filtered edge set allows the UI to render precise dependency graphs without visual noise from unrelated parts of the codebase.
Visualizing Flow Paths in the VS Code Interface
The impact radius data flows through three integration points in the extension:
Blast Radius View (blastRadius.ts): Invokes reader.getImpactRadius() and displays changed versus impacted nodes in a dedicated tree view, allowing developers to see at a glance which files require careful review【L13-L66】.
Graph Webview (graphWebview.ts): Renders the subgraph defined by the impact radius, showing only the nodes and edges returned by the BFS traversal when a specific file is selected【L150-L165】.
Extension Commands (extension.ts): Registers the "Code Graph: Show Impact" command palette entry that triggers flow detection for manually selected files【L162-L176】.
Practical Implementation Example
To programmatically trace execution paths from entry points in your own extensions or scripts:
import { SqliteReader } from './backend/sqlite';
async function analyzeChangeImpact(dbPath: string, changedFiles: string[]) {
const reader = await SqliteReader.create(dbPath);
// Traverse 2 levels deep through all relationship types
const impact = reader.getImpactRadius(changedFiles, /*maxDepth=*/ 2);
// Entry points (modified code)
console.log('Changed:', impact.changedNodes.map(n => n.qualifiedName));
// Execution paths discovered via BFS
console.log('Impacted:', impact.impactedNodes.map(n => n.qualifiedName));
// Files that may need review
console.log('Files to review:', impact.impactedFiles);
}
When rendering the results, the UI filters the complete graph to show only the impact radius subset:
// Inside graphWebview.ts - filtering nodes for visualization
if (this.impactRadius) {
const nodes = [
...this.impactRadius.changedNodes,
...this.impactRadius.impactedNodes
];
const edges = this.impactRadius.edges;
// Send to webview renderer...
}
Summary
- Flow detection in code-review-graph uses changed files as seed nodes to initialize a bidirectional BFS through the codebase dependency graph.
- The
getImpactRadius()method insqlite.tstraverses seven relationship types including calls, imports, inheritance, and test relationships. - A configurable depth limit (default 2) bounds the search to maintain performance while capturing immediate blast radius.
- The algorithm produces distinct sets of
changedNodes(entry points) andimpactedNodes(transitive dependencies) plus the specific edges connecting them. - Results are consumed by the Blast Radius view and Graph webview to visualize execution paths affected by code modifications.
Frequently Asked Questions
What is the default depth for flow detection in code-review-graph?
The default maxDepth is 2 levels, meaning the algorithm traverses from seed nodes to their immediate neighbors and one additional level of connections. This default is defined in code-review-graph-vscode/src/backend/sqlite.ts【L40-L42】 and balances comprehensiveness with performance, though developers can increase this value for deeper analysis at the cost of slower queries.
Which edge types does code-review-graph traverse during flow detection?
The BFS follows seven edge types defined in the SqliteReader class: CALLS, IMPORTS_FROM, INHERITS, IMPLEMENTS, CONTAINS, TESTED_BY, and DEPENDS_ON【L45-L52】. These relationships capture runtime execution flows, static dependencies, object-oriented hierarchies, and test coverage mappings to provide a complete picture of code interdependencies.
How does code-review-graph distinguish between changed nodes and impacted nodes?
The system maintains two separate collections: changedNodes containing the original seed symbols defined in modified files, and impactedNodes containing all nodes reached via BFS traversal that are not in the original seed set【L82-L94】. This separation allows the UI to highlight the actual modifications differently from the transitive dependencies that might be affected by those changes.
Can flow detection in code-review-graph trace backwards dependencies?
Yes. The getImpactRadius() method performs bidirectional traversal by querying both outgoing edges (getEdgesBySource) and incoming edges (getEdgesByTarget) for each node in the frontier【L58-L76】. This means it discovers not only what your changed code calls (downstream), but also what code calls your changes (upstream), ensuring both callers and callees are included in the impact analysis.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →