This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
When you need to know something about OpenRewrite:
- Refer to the rewrite-docs folder (if available)
- Consult Architecture Decision Records in
docs/adr/for design decisions
OpenRewrite is an automated refactoring ecosystem for source code that eliminates technical debt through AST-based transformations. The project uses a visitor pattern architecture where Recipes define transformations and TreeVisitors traverse and modify Abstract Syntax Trees (ASTs).
- Recipe: Defines what transformation to perform (
org.openrewrite.Recipe) - LST (Lossless Semantic Tree): AST preserving all formatting, comments, and type attribution during transformations
- TreeVisitor: Implements how to traverse and modify LSTs (
org.openrewrite.TreeVisitor) - SourceFile: Represents parsed source code as an LST (
org.openrewrite.SourceFile) - Markers: Attach metadata to LST nodes without modifying the tree structure
# Build everything (compile + test)
./gradlew build
# Quick compilation check without tests
./gradlew assemble
# Run tests only
./gradlew test
# Run all quality checks (tests, license, etc.)
./gradlew check
# Clean and rebuild
./gradlew clean build
# Install to local Maven repository
./gradlew publishToMavenLocal
# Apply license headers to files
./gradlew licenseFormat
# Run security vulnerability check
./gradlew dependencyCheck# Test specific module
./gradlew :rewrite-java:test
# Test specific class
./gradlew :rewrite-java:test --tests "org.openrewrite.java.cleanup.UnnecessaryParenthesesTest"
# Run with test filtering
./gradlew test --tests "*Maven*"# Install Node.js dependencies
./gradlew :rewrite-javascript:npmInstall
# Run JavaScript tests
./gradlew :rewrite-javascript:npm_test
# Build JavaScript components
./gradlew :rewrite-javascript:npm_run_buildrewrite-core: AST framework, visitor pattern, recipe infrastructurerewrite-test: Testing utilities (RewriteTest,RecipeSpec)
rewrite-java: Main Java language support with comprehensive AST modelrewrite-java-8/11/17/21: Java version-specific features and compatibilityrewrite-groovy/kotlin/javascript: Other JVM and web languages extending theJmodel fromrewrite-java
rewrite-maven: Maven POM manipulation and dependency managementrewrite-gradle: Gradle build script parsing (Groovy/Kotlin DSL)rewrite-json/yaml/xml/hcl/properties/toml/protobuf: Configuration and data formats
rewrite-java-tck: Technology Compatibility Kit for Java parser validationrewrite-java-test: Java-specific testing utilities and infrastructurerewrite-java-lombok: Lombok-specific Java supportrewrite-benchmarks: JMH performance benchmarks
Significant architectural decisions are documented in docs/adr/. When working on features that involve architectural decisions, consult existing ADRs and create new ones as needed following the standard ADR format (Context, Decision, Consequences).
Recipes extend org.openrewrite.Recipe and typically contain one or more TreeVisitor implementations. The visitor pattern allows type-safe traversal of language-specific ASTs.
- Use
TreeVisitor<SourceFile, ExecutionContext>for cross-cutting concerns - Use language-specific visitors (e.g.,
JavaIsoVisitor) for language transformations - Always return modified trees; don't mutate in place
- Return
nullfrom a visitor method to delete an element - IMPORTANT: Never typecast LST elements without an
instanceofcheck first. The typical pattern when an LST element is not of the expected type is to return early, making no changes. For example:if (!(arg instanceof J.Lambda) || !(((J.Lambda) arg).getBody() instanceof J.Block)) { return m; // Return unchanged if not the expected type }
Use RewriteTest interface with @Test methods that call rewriteRun():
@Test
void myRecipeTest() {
rewriteRun(
spec -> spec.recipe(new MyRecipe()),
java("before code", "expected after code")
);
}New language support for grammars that don't have type attribution require:
- ANTLR grammar files (
.g4) insrc/main/antlr/ - AST model classes extending
Tree - Parser implementation extending
Parser - Visitor base classes extending
TreeVisitor
The project supports selective module loading via IDE.properties to improve IDE performance. This allows developers to work on specific modules without loading the entire multi-project build.
The build enforces license headers on all source files and runs OWASP dependency vulnerability scanning. Always run ./gradlew licenseFormat before committing code changes.
The project uses JSpecify nullability annotations.