Support Java 22-26 language features#1707
Conversation
The formatter parses with javac internals, so Java 25/26 syntax can only be exercised when the tests run on a matching JDK. Register azul-zulu JDK 22/25/26 toolchains and add per-tier testJdkNN tasks so each visitor-dispatch branch (Java21/25/26) and each feature's GA boundary is exercised natively, while every other module stays on JDK 21. The published library still targets Java 17 (libraryTarget unchanged).
Add formatting support for language features finalized through Java 26: - Module import declarations (import module M;) — JEP 511 - Compact source files and instance main methods — JEP 512 - Unnamed patterns in deconstruction (case Box(_, _)) — JEP 456, fixes a formatter crash on the AnyPatternTree node - Markdown documentation comments (///) — JEP 467 - Flexible constructor bodies — JEP 513 Formatter selects Java25InputAstVisitor / Java26InputAstVisitor by runtime major version, with a graceful fallback to the existing Java21 visitor so older runtimes are unaffected. All javac APIs newer than Java 17 are reached via reflection / flag-bit detection, so the library keeps compiling at libraryTarget 17.
|
Thanks for your interest in palantir/palantir-java-format, @asm0dey! Before we can accept your pull request, you need to sign our contributor license agreement - just visit https://cla.palantir.com/ and follow the instructions. Once you sign, I'll automatically update this pull request. |
Generate changelog in
|
|
+1 |
Before this PR
palantir-java-format supports Java language features through Java 21. Source code using features finalized in Java 22–26 does not format correctly — several cases crash the formatter outright:
import module java.base;(module import declarations) throwsexpected token: 'module'.mainmethods crash (the implicit top-level class emits a non-existentclasstoken).case Box(_, _), crash on theAnyPatternTreenode.After this PR
The formatter handles Java language features finalized through Java 26:
import module M;— JEP 511 (kept as a leading, blank-line-separated import group; never stripped as "unused").case Box(_, _)— JEP 456 (fixes the crash above).///— JEP 467 (preserved verbatim, including fenced code blocks and{@snippet}content).Dispatch selects
Java25InputAstVisitor/Java26InputAstVisitorby runtime major version, with a graceful fallback to the existingJava21InputAstVisitor, so consumers on older JDKs are unaffected. Every javac API newer than Java 17 is reached via reflection / flag-bit detection, so the library still compiles atlibraryTarget = 17. Formatter tests run on a JDK 21/22/23/25/26 matrix so each visitor-dispatch tier and each feature's GA boundary is exercised natively; all other modules stay on JDK 21.Fixes
JCModuleImport is not an instance of JCImportcrash andExpected ; after import).palantir-java-formatcannot parse JEP 512 compact source files / instancemainon JDK 25 (expected token: 'void') #1701 — compact source files / instancemain(expected token: 'void') on JDK 25.case Insufficient(_, var source, var reason)(expected token: '_').==COMMIT_MSG==
Support Java 22–26 language features: module import declarations (JEP 511), compact source files and instance main methods (JEP 512), unnamed patterns in deconstruction (JEP 456), markdown documentation comments (JEP 467), and flexible constructor bodies (JEP 513). Visitors are selected by runtime major version with graceful fallback to Java 21, and post-17 javac APIs are accessed reflectively so the library still targets Java 17. Formatter tests run on a JDK 21/22/23/25/26 matrix.
==COMMIT_MSG==
Possible downsides?
./gradlew buildnow provisions JDK 22/23/25/26 toolchains for the test matrix, which increases first-run CI provisioning cost.Disclosure: this change was prepared with AI assistance (Claude Code). It has been reviewed, and the full test suite passes across the JDK 21/22/23/25/26 matrix.