diff options
author | CK <karsten_knuth@gmx.net> | 2023-12-07 14:38:12 -0800 |
---|---|---|
committer | google-java-format Team <google-java-format-dev+copybara@google.com> | 2023-12-07 14:38:45 -0800 |
commit | b86c508be5f42e7ed0d55cd1abe2c04d2db66676 (patch) | |
tree | dcbc4fda1b5ebb93f2b80a15e1cf5948328a89d4 | |
parent | ad771541474eebceb2c6666cb61d4836bf6d8560 (diff) | |
download | google-java-format-b86c508be5f42e7ed0d55cd1abe2c04d2db66676.tar.gz |
Add support for guard clauses in Java 21 switch expressions
This PR adds support for `switch` statements where a `case` has a guard clause.
See Issue #983
Fixes #988
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/988 from TheCK:master 4771486db7d8aab84eb4ecf8e68af2612d0c2b5c
PiperOrigin-RevId: 588913297
7 files changed, 117 insertions, 11 deletions
diff --git a/core/pom.xml b/core/pom.xml index 038e4ed..d1363fe 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -226,7 +226,7 @@ <profile> <id>jdk11</id> <activation> - <jdk>(,17)</jdk> + <jdk>[11,17)</jdk> </activation> <build> <plugins> @@ -236,6 +236,7 @@ <configuration> <excludes> <exclude>**/Java17InputAstVisitor.java</exclude> + <exclude>**/Java21InputAstVisitor.java</exclude> </excludes> </configuration> </plugin> @@ -243,6 +244,32 @@ <artifactId>maven-javadoc-plugin</artifactId> <configuration> <excludePackageNames>com.google.googlejavaformat.java.java17</excludePackageNames> + <excludePackageNames>com.google.googlejavaformat.java.java21</excludePackageNames> + </configuration> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>jdk17</id> + <activation> + <jdk>[17,21)</jdk> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <excludes> + <exclude>**/Java21InputAstVisitor.java</exclude> + </excludes> + </configuration> + </plugin> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <excludePackageNames>com.google.googlejavaformat.java.java21</excludePackageNames> </configuration> </plugin> </plugins> diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 9ff702d..5aa7a12 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -151,16 +151,14 @@ public final class Formatter { OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); // Output the compilation unit. JavaInputAstVisitor visitor; - if (Runtime.version().feature() >= 17) { - try { - visitor = - Class.forName("com.google.googlejavaformat.java.java17.Java17InputAstVisitor") - .asSubclass(JavaInputAstVisitor.class) - .getConstructor(OpsBuilder.class, int.class) - .newInstance(builder, options.indentationMultiplier()); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } + if (Runtime.version().feature() >= 21) { + visitor = + createVisitor( + "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", builder, options); + } else if (Runtime.version().feature() >= 17) { + visitor = + createVisitor( + "com.google.googlejavaformat.java.java17.Java17InputAstVisitor", builder, options); } else { visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier()); } @@ -173,6 +171,18 @@ public final class Formatter { javaOutput.flush(); } + private static JavaInputAstVisitor createVisitor( + final String className, final OpsBuilder builder, final JavaFormatterOptions options) { + try { + return Class.forName(className) + .asSubclass(JavaInputAstVisitor.class) + .getConstructor(OpsBuilder.class, int.class) + .newInstance(builder, options.indentationMultiplier()); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + static boolean errorDiagnostic(Diagnostic<?> input) { if (input.getKind() != Diagnostic.Kind.ERROR) { return false; diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index a0561e2..97bb2ff 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -29,6 +29,7 @@ import com.sun.source.tree.CaseLabelTree; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.InstanceOfTree; import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.ModuleTree; @@ -238,6 +239,15 @@ public class Java17InputAstVisitor extends JavaInputAstVisitor { } builder.close(); } + + final ExpressionTree guard = getGuard(node); + if (guard != null) { + builder.space(); + token("when"); + builder.space(); + scan(guard, null); + } + switch (node.getCaseKind()) { case STATEMENT: token(":"); @@ -267,4 +277,8 @@ public class Java17InputAstVisitor extends JavaInputAstVisitor { } return null; } + + protected ExpressionTree getGuard(final CaseTree node) { + return null; + } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java new file mode 100644 index 0000000..a96ef99 --- /dev/null +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -0,0 +1,36 @@ +/* + * Copyright 2023 The google-java-format Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java.java21; + +import com.google.googlejavaformat.OpsBuilder; +import com.google.googlejavaformat.java.java17.Java17InputAstVisitor; +import com.sun.source.tree.CaseTree; +import com.sun.source.tree.ExpressionTree; + +/** + * Extends {@link Java17InputAstVisitor} with support for AST nodes that were added or modified in + * Java 21. + */ +public class Java21InputAstVisitor extends Java17InputAstVisitor { + + public Java21InputAstVisitor(OpsBuilder builder, int indentMultiplier) { + super(builder, indentMultiplier); + } + + @Override + protected ExpressionTree getGuard(final CaseTree node) { + return node.getGuard(); + } +} diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 61a4346..688b24d 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -52,6 +52,7 @@ public class FormatterIntegrationTest { .putAll(15, "I603") .putAll(16, "I588") .putAll(17, "I683", "I684", "I696") + .putAll(21, "SwitchGuardClause") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input new file mode 100644 index 0000000..25df580 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input @@ -0,0 +1,9 @@ +class SwitchGuardClause { + boolean test(Object x) { + return switch (x) { + case String s when s.length() < 5 -> true; + case Integer i -> false; + default -> true; + }; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output new file mode 100644 index 0000000..25df580 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output @@ -0,0 +1,9 @@ +class SwitchGuardClause { + boolean test(Object x) { + return switch (x) { + case String s when s.length() < 5 -> true; + case Integer i -> false; + default -> true; + }; + } +} |