DEV Community

Sumit Deore
Sumit Deore

Posted on

Predicting the Blast Radius of a Code Change: Building AEGIS with AST Parsing and Graph Traversal

Every developer knows this moment: you're asked to modify a class you didn't write, in a codebase you don't fully understand, and before you touch a single line you find yourself wondering — what else is going to break?
In small projects, answering that is easy. You read the file, maybe grep a few references, and you're done. But in a real Spring Boot application with thousands of Java files, dozens of services, and layers of dependency injection, that question becomes genuinely hard to answer by hand. I built AEGIS, a VS Code extension, to answer it automatically.
The problem: understanding costs more than writing
The instinctive first move when told "modify PaymentService" is to ask a chain of questions: Which controllers call this? Which repositories does it touch? What tests should I re-run? IDE tools like "Find References" and "Call Hierarchy" give you fragments of the answer, but you still have to manually stitch those fragments into a mental model of the system before you can safely make a change.
AEGIS exists to build that model automatically — and to do it before you write any code, not after something breaks in production.
Why static analysis, not runtime tracing
The first real design decision was whether to observe the application while it runs (dynamic analysis) or read the source code without executing it (static analysis). I went with static analysis, for a fairly practical reason: it doesn't require a running server, a configured environment, or test data. It works directly on .java files, which means it's fast, safe, and usable the moment a project is opened — no setup cost.
The tradeoff is real: static analysis can't see dependencies created through reflection, dynamic proxies, or runtime configuration. AEGIS is upfront about this — it produces an estimate of impact, not a guarantee. That distinction mattered enough to me that the tool explicitly frames its output as a risk indicator rather than a correctness check.
From source code to a tree Aegis can actually reason about
Computers can't understand Java the way we do just by reading text. The first real step is converting source files into an Abstract Syntax Tree (AST) — a structured representation that captures classes, methods, fields, annotations, and imports, while discarding irrelevant details like whitespace and formatting.
I used JavaParser for this rather than writing a parser from scratch. Writing a full Java parser is a multi-month undertaking on its own, and it wasn't the problem I was trying to solve — I wanted to build an impact-analysis engine, not a compiler front-end. JavaParser hands you a reliable AST; from there, a Visitor implementation walks the tree and extracts exactly the constructs I need: class declarations, field types (to detect dependency injection), interface implementations, and inheritance.
Turning "who imports what" into a graph
Once AEGIS knows what exists in a project, the next question is how those pieces connect. This is where the dependency graph comes in — the actual core data structure of the whole system.
Each class becomes a node. Each dependency — a field injected via @Autowired, an interface implementation, a class extension — becomes a directed edge. Direction matters here: OrderService depending on OrderRepository doesn't imply the reverse, and treating dependencies as undirected would make impact analysis meaningless.
With the graph built, answering "what's affected if I change PaymentService?" becomes a graph traversal problem rather than a manual search problem — a Depth-First Search starting from the selected node, collecting every class reachable from it, both directly and indirectly. That's the mechanism that turns "I have a hunch this might be risky" into "here are the 7 specific classes you should look at."
A design decision I'd defend in an interview
The choice I'm most confident about is splitting AEGIS into two completely independent applications: a TypeScript VS Code extension that handles only UI and user interaction, and a separate Java analyzer engine that does all the actual parsing, graph building, and analysis — communicating over JSON.
It would have been faster to write everything inside the extension. But the analyzer doesn't know or care that it's being called from VS Code. That means the exact same engine could later be wrapped in a CLI tool, exposed as a REST API for CI/CD pipelines, or reused inside an IntelliJ plugin — without touching a single line of analysis logic. Separating "how developers interact with this" from "how this actually works" is a small decision that pays off every time the surrounding requirements change, and it's the one architectural call in this project I'd make again without hesitation.
What's next
The current version calculates a rule-based risk score from dependency counts — deliberately simple and fully explainable, rather than a black-box model. Future iterations will fold in Git history (which files change together, how often, with how many contributors) and eventually offer plain-language explanations of why a component is flagged as high-risk, so the tool is useful to someone new to a codebase, not just someone who already understands its graph.
I'd love your input
AEGIS is still early, and I'm building it as much to learn as to ship. If you've worked on static analysis tools, AST-based tooling, or IDE extensions before, I'd genuinely value your perspective — especially on things I haven't gotten right yet:
Is DFS the right default for impact traversal, or would you reach for something else at scale (thousands of classes, deep dependency chains)?
How would you approach detecting reflection-based or dynamically injected dependencies, which static analysis inherently misses?
Any war stories from building similar tools — false positives, performance walls, or design decisions you'd undo?
Feedback, critique, and pull requests are all welcome — the repo is open at github.com/sumitsdeore, and I'll happily talk through the architecture or a specific module with anyone who's curious. If you try it out and hit something broken or confusing, opening an issue is the most useful thing you can do for the project right now.
You can see AEGIS in more depth on my portfolio, and I'm always reachable in the comments here or on LinkedIn.

Top comments (0)