# 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). ```java public interface CodebaseIntelligenceProvider { // Event Triggers List findTriggerPoints(); // Entry Points List findEntryPoints(); // Call Graphs List 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. 1. **SM Parser**: Extracts the core states and transitions. 2. **Intelligence Service**: Discovers where events are triggered. 3. **Correlation Engine**: Merges the two models based on Event IDs. ## 4. Benefits - **Testability**: We can mock the `CodebaseIntelligenceProvider` to 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. ## 5. Monorepo and Multi-Module Support Applications are often split into multiple modules (e.g., `core`, `api`, `workers`). - **Workspace Scanning**: The analyzer should treat the entire monorepo as a single codebase context. - **Source Tracking**: Each metadata item (`TriggerPoint`, `EntryPoint`) includes a `sourceModule` identifier to show exactly where it was found. - **Cross-Module Resolution**: Properties defined in one module's `application.yml` and used in another should be resolved globally. - **Internal Dependency Following**: If the analyzer finds a call to a method in another module, it should continue the call-chain analysis into that module's source. ## Challenges - **Multiple State Machines**: How to know which `StateMachine` instance is being used? - Initial heuristic: If there's only one, assume it's that one. - If multiple, check generic types `StateMachine` or variable names. - **Indirect Calls**: Method `A` (Controller) calls `B` (Service), and `B` calls `sendEvent`. - 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 1. Create a PoC `TriggerDetector` for Spring MVC. 2. Integrate `TriggerAggregator` into the main analysis pipeline. 3. Update the `Exporter` to visualize these links.