AI Distiller provides support for Java 8+ codebases using the tree-sitter-java parser, with basic support for modern Java features including records, sealed classes, and pattern matching.
Java support in AI Distiller is designed to extract the essential structure of Java code while preserving type information, visibility modifiers, and relationships between classes, interfaces, and abstract classes. The distilled output maintains Java's semantic meaning while dramatically reducing token count for AI consumption.
AI Distiller models Java code as a semantic graph, representing not just the syntax but the relationships between entities. This document explains how Java constructs are mapped to this representation, focusing on providing AI systems with a clear understanding of your codebase's structure and API surface.
- Minimum supported: Java 8
- Recommended: Java 11+
- Modern features: Partial support for Java 14+ (records, sealed classes, pattern matching)
| Construct | Support Level | Notes |
|---|---|---|
| Packages | ✅ Full | Package declarations and structure |
| Imports | ✅ Full | Standard and static imports |
| Classes | ✅ Full | Including abstract, final, nested classes |
| Interfaces | ✅ Full | Full interface support including sealed interfaces with permits clause |
| Enums | ✅ Full | Enum declarations and constants |
| Records | ✅ Full | Record syntax, parameters, and implementations |
| Construct | Support Level | Notes |
|---|---|---|
| Methods | ✅ Full | Including constructors, overloading |
| Fields | ✅ Full | All modifiers (static, final, volatile, etc.) |
| Visibility | ✅ Full | public, private, protected, package-private |
| Inheritance | ✅ Full | extends and implements relationships |
| Method Overriding | ✅ Full | @Override annotations preserved |
| Static Members | ✅ Full | Static methods and fields |
| Feature | Support Level | Notes |
|---|---|---|
| Basic Types | ✅ Full | Primitives and wrapper classes |
| Generics | Type parameters captured, multiple bounds supported, inheritance generics dropped | |
| Arrays | ✅ Full | Array type declarations |
| Annotations | ✅ Full | Type/method/parameter annotations, @interface definitions with default values |
| Lambda Expressions | ❌ Not supported | Not parsed correctly |
| Method References | ❌ Not supported | Not parsed correctly |
Java visibility in AI Distiller follows standard Java keywords in text format:
- Public:
publickeyword (accessible everywhere) - Private:
privatekeyword (class-only access) - Protected:
protectedkeyword (package + subclass access) - Package-private: no keyword (package-only access, Java default)
AI Distiller uses standard Java visibility keywords for clear representation:
// Input
public class User {
private String name;
protected int id;
public String getName() { return name; }
}// Output (default version - public only)
public class User {
public String getName();
}
Methods are cleanly extracted with parameter types and return types:
// Input
public Optional<User> findUserById(String id, boolean includeDeleted) {
// implementation
}// Output (no implementation)
public Optional<User> findUserById(String id, boolean includeDeleted);
Class hierarchies and interface implementations are preserved:
// Input
public class UserService extends BaseService implements Cacheable, Auditable {
// implementation
}// Output
public class UserService extends BaseService implements Cacheable, Auditable {
// members
}
Basic Class Example
Basic.java - Source Code
```java package com.aidi.test.basic;/** * A basic class to test fundamental parsing */ public class Basic { private static final String GREETING_PREFIX = "Hello, "; public static void main(String[] args) { String world = "World"; System.out.println(createGreeting(world)); } private static String createGreeting(String name) { return GREETING_PREFIX + name; } } ```Compact AI-friendly version (`default output (public only, no implementation)`)
``` package com.aidi.test.basicpublic class Basic { public static void main(String[] args); } </file> ```Full version (`--public=1 --protected=1 --internal=1 --private=1 --implementation=1`)
``` package com.aidi.test.basic import java.util.Objectspublic class Basic { private static final String GREETING_PREFIX = "Hello, "; public static void main(String[] args) { String world = "World"; int repetitions = 3; for (int i = 0; i < repetitions; i++) { String message = createGreeting(world, i + 1); System.out.println(message); } } private static String createGreeting(String name, int number) { return String.format("%s%s #%d", GREETING_PREFIX, name, number); } } </file> ```
Object-Oriented Example
SimpleOOP.java - Source Code
```java package com.aidi.test.oop;import java.util.Objects; public class SimpleOOP { public final String id; protected String name; private int version; public SimpleOOP(String id, String name) { this.id = Objects.requireNonNull(id); this.name = name; this.version = 1; } public String getName() { return name; } @Override public String toString() { return "SimpleOOP{id='" + id + "', name='" + name + "'}"; } } ```Compact AI-friendly version (`default output (public only, no implementation)`)
``` package com.aidi.test.oop import java.util.Objectspublic class SimpleOOP { public final String id; public SimpleOOP(String id, String name); public SimpleOOP(String id); public String getName(); public void setName(String name); @Override public String toString(); } </file> ```Full version with all visibility (`--strip 'comments,implementation'`)
``` package com.aidi.test.oop import java.util.Objectspublic class SimpleOOP { public final String id; protected String name; private int version; private boolean dirty; public SimpleOOP(String id, String name); public SimpleOOP(String id); public String getName(); public void setName(String name); @Override public String toString(); } </file> ```
- Fixed Visibility Detection: Package-private types no longer incorrectly promoted to public (critical bug fix)
- Enhanced Annotation Support: @interface definitions with default values now properly displayed without redundant modifiers
- Improved Java Modern Features: Records, sealed interfaces with permits clause, annotation default values
- Parameter Annotations: Method parameter annotations are now extracted (e.g.,
@NotNull U input) - Generic Bounds: Shows all bounds in generic type constraints (e.g.,
T extends Number & Runnable & Serializable)
Dependency Resolution
- When public classes use package-private types (sealed interfaces, records), those dependencies are excluded from default output
- Example:
ModernJavausesShape,Circle,Rectanglebut onlyModernJavaappears in public-only output - Solution: Use
--internal=1flag to include package-private types and see complete sealed interface definitions with permits clause - Results in incomplete/non-compilable code representations in default output only
Inheritance Resolution
- Inherited public methods from parent classes are not displayed in child classes
- Example:
UserStore extends BaseStore- missingsave()method from parent - Public API surface appears incomplete for inherited classes
Advanced Type Features
- Wildcard generics
? extends Tand? super Tare not yet supported - Type inference with
varkeyword loses type information
Throws Clauses
- Method
throwsdeclarations are not being extracted despite parser support - This affects API completeness and exception handling documentation
Generic Type Arguments in Inheritance
- Generic arguments in
extendsclauses are dropped (e.g.,extends BaseStore<User>becomesextends BaseStore)
Multiple Type Definitions
- Parser may miss additional classes/interfaces/annotations in the same file
- Nested types and inner classes have limited support
Lambda Expressions and Method References
- Lambda syntax
() -> {}is not parsed - Method references
String::lengthare not recognized - Functional interfaces lose their context
Modern Java Pattern Matching
- Pattern matching syntax is not recognized
- Switch expressions are not properly handled
Package Declaration Formatting
- Package declarations are missing semicolons in output
Formatting Inconsistencies
- Method implementations have extra indentation
- Brace placement is inconsistent with Java conventions
- Static initializer blocks format as
static;
JavaDoc Parsing
- JavaDoc tags like
@paramand@returnare included in text but not structured - HTML tags in JavaDoc comments are preserved as-is
- Use explicit types: Avoid
varkeyword where possible for better type extraction - Document with JavaDoc: Use
/** */comments for better API documentation in output - Leverage generics: Generic type information is now fully captured and preserved
- Use annotations: Annotation arguments are extracted and preserved in output
# Extract public API with JavaDoc (recommended for AI)
aid src/ --strip "non-public,implementation" --format text
# Extract all structure with generics and annotations
aid MyClass.java --strip "implementation" --format text
# Complete code preservation including JavaDoc
aid . --strip "" --format text --output java-full.txt// Query Java codebase structure
const result = await mcp.call("aid", {
path: "./src/main/java",
strip: ["non-public", "implementation"],
format: "text"
});# GitHub Actions example
- name: Extract Java API
run: |
aid src/main/java --strip "non-public,implementation" \
--format text --output api-surface.txt- Constructor chaining:
this()calls are preserved in signatures - Method overloading: All overloaded variants are captured
- Static imports: Preserved as regular imports in output
- Nested classes: Basic support, complex nesting may be flattened
- Enum methods: Enum constants and methods are both captured
| Feature | AI Distiller | JavaDoc | IDEs | AST Tools |
|---|---|---|---|---|
| AI-optimized output | ✅ | ❌ | ❌ | ❌ |
| Visibility notation | ✅ UML-style | ❌ | ❌ | |
| Type preservation | ✅ | ✅ | ✅ | ✅ |
| Implementation stripping | ✅ | ❌ | ❌ | |
| Inheritance tracking | ✅ | ✅ | ✅ | |
| Compact output | ✅ | ❌ | ❌ | ❌ |
"Generic constraints not detailed enough"
- Wildcard generics
? extends Tneed specialized handling - Solution: Most bounded generics
T extends Classare now captured
"JavaDoc tags not structured"
- JavaDoc content is captured but tags like
@paramare in text form - Solution: JavaDoc is now preserved, structured tag parsing is planned
"Methods have extra indentation"
- Formatting issue with implementation blocks
- Impact: Cosmetic only, doesn't affect parsing
"Annotation arguments simplified"
- Complex annotation expressions may lose some detail
- Solution: Most annotation arguments are now properly extracted
If parsing fails completely:
- Check for valid Java syntax
- Ensure file encoding is UTF-8
- Try with simpler constructs first
- Report complex cases as issues
- Wildcard generics:
? extends Tand? super Tsupport - Structured JavaDoc: Parsed
@param,@return,@throwstags - Modern Java features: Records, sealed classes, pattern matching
- Lambda expressions: Functional programming constructs
- Annotation definitions: Proper
@interfaceparsing
We welcome contributions to improve Java support:
- Wildcard generics implementation
- JavaDoc tag structuring
- Modern Java feature support
- Test case additions
To improve Java language support:
- Add test cases: Create complex Java examples in
test-data/java/ - Report issues: Document parsing failures with minimal reproductions
- Enhance parser: Improve tree-sitter integration for missing features
- Update docs: Keep this documentation current with capabilities
For questions or contributions, see the main project README.