2.8 KiB
2.8 KiB
Decoupled Analysis Architecture: The "Modular Provider" Approach
Core Philosophy
We decouple the State Machine Definition (what the machine IS) from the Codebase Intelligence (how the machine IS USED). This allows for swappable analysis tools and prevents the state machine parser from becoming a monolithic "all-knowing" beast.
1. The Intelligence Interface (The Bridge)
We introduce an abstraction layer that provides information about the code without tying us to a specific implementation (like JDT).
public interface CodebaseIntelligenceProvider {
// Event Triggers
List<TriggerPoint> findTriggerPoints();
// Entry Points
List<EntryPoint> findEntryPoints();
// Call Graphs
List<CallChain> traceCallChain(MethodReference target);
// Resolution
String resolveValue(ExpressionReference ref);
}
2. Swappable Implementations
This allows us to offer different "tiers" of analysis or even different tools:
- JdtProvider (Current): High-precision, understands hierarchy, but heavy.
- RegexProvider: Lightweight, fast, good for simple projects or quick scans.
- ExternalLspProvider (Future): Could query a running Language Server (like Eclipse JDT.LS) for ultra-accurate cross-project resolution.
3. The "State Machine Model" is the Sink
The State Machine Exporter now becomes a "Consumer" of intelligence.
- SM Parser: Extracts the core states and transitions.
- Intelligence Service: Discovers where events are triggered.
- Correlation Engine: Merges the two models based on Event IDs.
4. Benefits
- Testability: We can mock the
CodebaseIntelligenceProviderto test state machine rendering without needing a full Java project on disk. - Maintainability: Adding support for a new framework (e.g., Micronaut) only requires updating the
IntelligenceProvider, not touching the core state machine logic. - Performance: We can run the SM Parser and the Intelligence Scanner in parallel since they are now independent.
Challenges
- Multiple State Machines: How to know which
StateMachineinstance is being used?- Initial heuristic: If there's only one, assume it's that one.
- If multiple, check generic types
StateMachine<S, E>or variable names.
- Indirect Calls: Method
A(Controller) callsB(Service), andBcallssendEvent.- Static analysis might need to follow call graphs.
- Use JDT's cross-reference capabilities if possible, or build a simple call graph.
- Inheritance:
- Controllers might extend base classes with common mappings.
- State machine configurations already handle inheritance; Trigger detection should too.
Next Steps
- Create a PoC
TriggerDetectorfor Spring MVC. - Integrate
TriggerAggregatorinto the main analysis pipeline. - Update the
Exporterto visualize these links.