Skip to content

Commit 8b528f0

Browse files
committed
Add support for guard clauses in Java 21 switch expressions
1 parent 53390d9 commit 8b528f0

File tree

3 files changed

+115
-2
lines changed

3 files changed

+115
-2
lines changed

core/pom.xml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@
226226
<profile>
227227
<id>jdk11</id>
228228
<activation>
229-
<jdk>(,17)</jdk>
229+
<jdk>[11,17)</jdk>
230230
</activation>
231231
<build>
232232
<plugins>
@@ -236,13 +236,40 @@
236236
<configuration>
237237
<excludes>
238238
<exclude>**/Java17InputAstVisitor.java</exclude>
239+
<exclude>**/Java21InputAstVisitor.java</exclude>
239240
</excludes>
240241
</configuration>
241242
</plugin>
242243
<plugin>
243244
<artifactId>maven-javadoc-plugin</artifactId>
244245
<configuration>
245246
<excludePackageNames>com.google.googlejavaformat.java.java17</excludePackageNames>
247+
<excludePackageNames>com.google.googlejavaformat.java.java21</excludePackageNames>
248+
</configuration>
249+
</plugin>
250+
</plugins>
251+
</build>
252+
</profile>
253+
<profile>
254+
<id>jdk17</id>
255+
<activation>
256+
<jdk>[17,21)</jdk>
257+
</activation>
258+
<build>
259+
<plugins>
260+
<plugin>
261+
<groupId>org.apache.maven.plugins</groupId>
262+
<artifactId>maven-compiler-plugin</artifactId>
263+
<configuration>
264+
<excludes>
265+
<exclude>**/Java21InputAstVisitor.java</exclude>
266+
</excludes>
267+
</configuration>
268+
</plugin>
269+
<plugin>
270+
<artifactId>maven-javadoc-plugin</artifactId>
271+
<configuration>
272+
<excludePackageNames>com.google.googlejavaformat.java.java21</excludePackageNames>
246273
</configuration>
247274
</plugin>
248275
</plugins>

core/src/main/java/com/google/googlejavaformat/java/Formatter.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,17 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept
151151
OpsBuilder builder = new OpsBuilder(javaInput, javaOutput);
152152
// Output the compilation unit.
153153
JavaInputAstVisitor visitor;
154-
if (Runtime.version().feature() >= 17) {
154+
if (Runtime.version().feature() >= 21) {
155+
try {
156+
visitor =
157+
Class.forName("com.google.googlejavaformat.java.java21.Java21InputAstVisitor")
158+
.asSubclass(JavaInputAstVisitor.class)
159+
.getConstructor(OpsBuilder.class, int.class)
160+
.newInstance(builder, options.indentationMultiplier());
161+
} catch (ReflectiveOperationException e) {
162+
throw new LinkageError(e.getMessage(), e);
163+
}
164+
} else if (Runtime.version().feature() >= 17) {
155165
try {
156166
visitor =
157167
Class.forName("com.google.googlejavaformat.java.java17.Java17InputAstVisitor")
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.google.googlejavaformat.java.java21;
2+
3+
import static com.google.common.collect.Iterables.getOnlyElement;
4+
5+
import com.google.googlejavaformat.OpsBuilder;
6+
import com.google.googlejavaformat.java.java17.Java17InputAstVisitor;
7+
import com.sun.source.tree.*;
8+
import java.util.List;
9+
10+
public class Java21InputAstVisitor extends Java17InputAstVisitor {
11+
12+
public Java21InputAstVisitor(OpsBuilder builder, int indentMultiplier) {
13+
super(builder, indentMultiplier);
14+
}
15+
16+
@Override
17+
public Void visitCase(CaseTree node, Void unused) {
18+
sync(node);
19+
markForPartialFormat();
20+
builder.forcedBreak();
21+
List<? extends CaseLabelTree> labels = node.getLabels();
22+
boolean isDefault =
23+
labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL");
24+
if (isDefault) {
25+
token("default", plusTwo);
26+
} else {
27+
token("case", plusTwo);
28+
builder.open(labels.size() > 1 ? plusFour : ZERO);
29+
builder.space();
30+
boolean first = true;
31+
for (Tree expression : labels) {
32+
if (!first) {
33+
token(",");
34+
builder.breakOp(" ");
35+
}
36+
scan(expression, null);
37+
first = false;
38+
}
39+
builder.close();
40+
}
41+
if (node.getGuard() != null) {
42+
builder.space();
43+
token("when");
44+
builder.space();
45+
scan(node.getGuard(), null);
46+
}
47+
switch (node.getCaseKind()) {
48+
case STATEMENT:
49+
token(":");
50+
builder.open(plusTwo);
51+
visitStatements(node.getStatements());
52+
builder.close();
53+
break;
54+
case RULE:
55+
builder.space();
56+
token("-");
57+
token(">");
58+
builder.space();
59+
if (node.getBody().getKind() == Tree.Kind.BLOCK) {
60+
// Explicit call with {@link CollapseEmptyOrNot.YES} to handle empty case blocks.
61+
visitBlock(
62+
(BlockTree) node.getBody(),
63+
CollapseEmptyOrNot.YES,
64+
AllowLeadingBlankLine.NO,
65+
AllowTrailingBlankLine.NO);
66+
} else {
67+
scan(node.getBody(), null);
68+
}
69+
builder.guessToken(";");
70+
break;
71+
default:
72+
throw new AssertionError(node.getCaseKind());
73+
}
74+
return null;
75+
}
76+
}

0 commit comments

Comments
 (0)