Files
spring-state-machine-renderer/plan-extended-anaylis/polyglot_support.md

2.4 KiB

Polyglot Analysis: Supporting Mixed Java and Kotlin

1. The Need for Language Abstraction

Professional JVM codebases are increasingly "Mixed Mode" (Java + Kotlin). Tying our analysis logic directly to JDT (Java AST) creates a bottleneck for Kotlin support.

2. The "Driver" Architecture

We decouple the Intelligence Logic (e.g., "Find all REST controllers") from the AST Parser (e.g., "Walk the JDT tree").

1. Language Driver Interface

public interface LanguageDriver {
    boolean supports(Path filePath);
    
    // Unified Extraction Methods
    List<RawClassMetadata> extractClasses(Path filePath);
    List<RawMethodMetadata> extractMethods(RawClassMetadata cls);
    List<RawInvocationMetadata> findInvocations(RawMethodMetadata method, String targetMethodName);
}

2. Unified Metadata Model (Intermediate Representation)

We move to a "Generic JVM Model" before performing the final state machine mapping.

public record RawClassMetadata(
    String fqn,
    String language, // "java", "kotlin"
    List<String> annotations,
    String superclass,
    List<String> interfaces
) {}

public record RawMethodMetadata(
    String name,
    List<String> annotations,
    String returnType,
    List<String> parameterTypes
) {}

3. Polyglot Analysis Flow

  1. File Discovery: Find all .java and .kt files.
  2. Driver Assignment: Delegate each file to the appropriate LanguageDriver.
  3. Cross-Language Resolution: The CodebaseContext stores metadata for ALL classes.
    • A Java controller calling a Kotlin service is resolved by looking up the Kotlin class's unified metadata.
  4. Enricher Execution: Enrichers (like SpringMvcEnricher) now operate on the Unified Metadata Model, making them language-agnostic!

4. Why this is "Future Proof":

  • Enrichers are written once: The logic to find @PostMapping only needs to know how to query the RawClassMetadata annotations, not how to traverse JDT vs. Kotlin PSI.
  • Easy Expansion: To support Scala, Groovy, or even a newer Java version, you just add a new LanguageDriver.

5. Refactoring Plan

  1. Define Intermediate Models: Create RawClassMetadata and RawMethodMetadata.
  2. Extract JDT Logic: Move the current JDT-specific code into JavaLanguageDriver.
  3. Kotlin PoC (Phase 12): Implement a basic KotlinLanguageDriver using Regex or a lightweight parser (like Tree-Sitter) to prove the abstraction works.