Skip to content

Commit

Permalink
Add support for guard clauses in Java 21 switch expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
TheCK committed Nov 10, 2023
1 parent 53390d9 commit 8b528f0
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 2 deletions.
29 changes: 28 additions & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@
<profile>
<id>jdk11</id>
<activation>
<jdk>(,17)</jdk>
<jdk>[11,17)</jdk>
</activation>
<build>
<plugins>
Expand All @@ -236,13 +236,40 @@
<configuration>
<excludes>
<exclude>**/Java17InputAstVisitor.java</exclude>
<exclude>**/Java21InputAstVisitor.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,17 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept
OpsBuilder builder = new OpsBuilder(javaInput, javaOutput);
// Output the compilation unit.
JavaInputAstVisitor visitor;
if (Runtime.version().feature() >= 17) {
if (Runtime.version().feature() >= 21) {
try {
visitor =
Class.forName("com.google.googlejavaformat.java.java21.Java21InputAstVisitor")
.asSubclass(JavaInputAstVisitor.class)
.getConstructor(OpsBuilder.class, int.class)
.newInstance(builder, options.indentationMultiplier());
} catch (ReflectiveOperationException e) {
throw new LinkageError(e.getMessage(), e);
}
} else if (Runtime.version().feature() >= 17) {
try {
visitor =
Class.forName("com.google.googlejavaformat.java.java17.Java17InputAstVisitor")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.google.googlejavaformat.java.java21;

import static com.google.common.collect.Iterables.getOnlyElement;

import com.google.googlejavaformat.OpsBuilder;
import com.google.googlejavaformat.java.java17.Java17InputAstVisitor;
import com.sun.source.tree.*;
import java.util.List;

public class Java21InputAstVisitor extends Java17InputAstVisitor {

public Java21InputAstVisitor(OpsBuilder builder, int indentMultiplier) {
super(builder, indentMultiplier);
}

@Override
public Void visitCase(CaseTree node, Void unused) {
sync(node);
markForPartialFormat();
builder.forcedBreak();
List<? extends CaseLabelTree> labels = node.getLabels();
boolean isDefault =
labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL");
if (isDefault) {
token("default", plusTwo);
} else {
token("case", plusTwo);
builder.open(labels.size() > 1 ? plusFour : ZERO);
builder.space();
boolean first = true;
for (Tree expression : labels) {
if (!first) {
token(",");
builder.breakOp(" ");
}
scan(expression, null);
first = false;
}
builder.close();
}
if (node.getGuard() != null) {
builder.space();
token("when");
builder.space();
scan(node.getGuard(), null);
}
switch (node.getCaseKind()) {
case STATEMENT:
token(":");
builder.open(plusTwo);
visitStatements(node.getStatements());
builder.close();
break;
case RULE:
builder.space();
token("-");
token(">");
builder.space();
if (node.getBody().getKind() == Tree.Kind.BLOCK) {
// Explicit call with {@link CollapseEmptyOrNot.YES} to handle empty case blocks.
visitBlock(
(BlockTree) node.getBody(),
CollapseEmptyOrNot.YES,
AllowLeadingBlankLine.NO,
AllowTrailingBlankLine.NO);
} else {
scan(node.getBody(), null);
}
builder.guessToken(";");
break;
default:
throw new AssertionError(node.getCaseKind());
}
return null;
}
}

0 comments on commit 8b528f0

Please sign in to comment.