diff --git a/build.gradle b/build.gradle index 70bb400b3..488b35555 100644 --- a/build.gradle +++ b/build.gradle @@ -75,7 +75,7 @@ subprojects { javaVersions { libraryTarget = 17 - runtime = 21 + runtime = 23 } jdks { diff --git a/palantir-java-format-spi/build.gradle b/palantir-java-format-spi/build.gradle index a3f1583fd..ba8daac9a 100644 --- a/palantir-java-format-spi/build.gradle +++ b/palantir-java-format-spi/build.gradle @@ -18,5 +18,5 @@ tasks.withType(JavaCompile).named('compileJava') { } javaVersion { - target = 21 + target = 23 } diff --git a/palantir-java-format/build.gradle b/palantir-java-format/build.gradle index 470e5cbaf..51b37e3f9 100644 --- a/palantir-java-format/build.gradle +++ b/palantir-java-format/build.gradle @@ -41,6 +41,16 @@ moduleJvmArgs { 'jdk.compiler/com.sun.tools.javac.api') } +applicationDefaultJvmArgs = [ + '--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED', + '--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED', + '--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED', + '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED', + '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED', + '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED', + '--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED' +] + tasks.withType(JavaCompile).named('compileJava') { // By setting the source and target compatibility to 11, while still using a higher level // JDK for compilation, we can compile against the AST classes we need to support >11 source @@ -62,5 +72,5 @@ tasks.named("test") { } javaVersion { - target = 21 + target = 23 } diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/JavacTokens.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/JavacTokens.java index 705837412..eaf19fd9a 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/JavacTokens.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/JavacTokens.java @@ -27,7 +27,9 @@ import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.parser.UnicodeReader; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import java.util.Set; +import javax.annotation.Nullable; /** A wrapper around javac's lexer. */ class JavacTokens { @@ -178,6 +180,12 @@ public int getSourcePos(int index) { return pos + index; } + @Override + @Nullable + public DiagnosticPosition getPos() { + return null; + } + @Override public CommentStyle getStyle() { return style; diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/RemoveUnusedImports.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/RemoveUnusedImports.java index a66b6b559..15c6b652e 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/RemoveUnusedImports.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/RemoveUnusedImports.java @@ -226,7 +226,12 @@ private static RangeMap buildReplacements( Set usedNames, Multimap> usedInJavadoc) { RangeMap replacements = TreeRangeMap.create(); - for (JCImport importTree : unit.getImports()) { + for (Object o : unit.getImports()) { + if (!(o instanceof JCImport)) { + // TODO: In Java >=23, getImports() returns JCImportBase + continue; + } + JCImport importTree = (JCImport) o; String simpleName = getSimpleName(importTree); if (!isUnused(unit, usedNames, usedInJavadoc, importTree, simpleName)) { continue; diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/java21/Java21InputAstVisitor.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/java21/Java21InputAstVisitor.java index 5f089c4e6..6deadf1f2 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/java21/Java21InputAstVisitor.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/java21/Java21InputAstVisitor.java @@ -18,6 +18,7 @@ import com.palantir.javaformat.OpsBuilder; import com.palantir.javaformat.java.java14.Java14InputAstVisitor; +import com.sun.source.tree.AnyPatternTree; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ConstantCaseLabelTree; import com.sun.source.tree.DeconstructionPatternTree; @@ -88,4 +89,10 @@ protected void variableName(Name name) { visit(name); } } + + @Override + public Void visitAnyPattern(AnyPatternTree node, Void unused) { + token("_"); + return null; + } } diff --git a/palantir-java-format/src/test/java/com/palantir/javaformat/java/FileBasedTests.java b/palantir-java-format/src/test/java/com/palantir/javaformat/java/FileBasedTests.java index 4edb8fa12..64ce64493 100644 --- a/palantir-java-format/src/test/java/com/palantir/javaformat/java/FileBasedTests.java +++ b/palantir-java-format/src/test/java/com/palantir/javaformat/java/FileBasedTests.java @@ -59,7 +59,8 @@ public final class FileBasedTests { "SwitchUnderscore", "I880", "I1309", - "Unnamed") + "Unnamed", + "UnnamedPattern") .build(); private final Class testClass; diff --git a/palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/UnnamedPattern.input b/palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/UnnamedPattern.input new file mode 100644 index 000000000..9eb7739a2 --- /dev/null +++ b/palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/UnnamedPattern.input @@ -0,0 +1,19 @@ +class UnnamedPattern { + public static void main(String[] args) { + var cp = new ColoredPoint(new Point(1, 2), Color.RED); + + // The colour doesn't matter, so use an unnamed pattern + // (as opposed to the unnamed type pattern `var _`). + if (cp instanceof ColoredPoint(Point(int x, int y), _)) { + System.out.println(x + "," + y); + } + + if (cp instanceof ColoredPoint(_, var c)) { + System.out.println(c); + } + } +} + +record Point(int x, int y) { } +enum Color { RED, GREEN, BLUE } +record ColoredPoint(Point p, Color c) { } diff --git a/palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/UnnamedPattern.output b/palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/UnnamedPattern.output new file mode 100644 index 000000000..656d40d4f --- /dev/null +++ b/palantir-java-format/src/test/resources/com/palantir/javaformat/java/testdata/UnnamedPattern.output @@ -0,0 +1,25 @@ +class UnnamedPattern { + public static void main(String[] args) { + var cp = new ColoredPoint(new Point(1, 2), Color.RED); + + // The colour doesn't matter, so use an unnamed pattern + // (as opposed to the unnamed type pattern `var _`). + if (cp instanceof ColoredPoint(Point(int x, int y), _)) { + System.out.println(x + "," + y); + } + + if (cp instanceof ColoredPoint(_, var c)) { + System.out.println(c); + } + } +} + +record Point(int x, int y) {} + +enum Color { + RED, + GREEN, + BLUE +} + +record ColoredPoint(Point p, Color c) {}