Skip to content

Commit

Permalink
Handle exhaustive switches on sealed types in MissingDefault
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 618889679
  • Loading branch information
cushon authored and Error Prone Team committed Mar 25, 2024
1 parent 9d5491d commit cd6a504
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
Expand Up @@ -33,6 +33,8 @@
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.SwitchTree;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Optional;
import javax.lang.model.element.ElementKind;
Expand All @@ -55,6 +57,9 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) {
}
Optional<? extends CaseTree> maybeDefault = getSwitchDefault(tree);
if (!maybeDefault.isPresent()) {
if (isExhaustive(tree)) {
return NO_MATCH;
}
Description.Builder description = buildDescription(tree);
if (!tree.getCases().isEmpty()) {
// Inserting the default after the last case is easier than finding the closing brace
Expand Down Expand Up @@ -95,4 +100,22 @@ public Description matchSwitch(SwitchTree tree, VisitorState state) {
.addFix(SuggestedFix.postfixWith(defaultCase, " // fall out"))
.build();
}

private static final Field IS_EXHAUSTIVE = getIsExhaustive();

private static Field getIsExhaustive() {
try {
return JCTree.JCSwitch.class.getField("isExhaustive");
} catch (NoSuchFieldException e) {
return null;
}
}

private static boolean isExhaustive(SwitchTree tree) {
try {
return IS_EXHAUSTIVE != null && IS_EXHAUSTIVE.getBoolean(tree);
} catch (IllegalAccessException e) {
throw new LinkageError(e.getMessage(), e);
}
}
}
Expand Up @@ -282,4 +282,25 @@ public void arrowComment() {
"}")
.doTest();
}

@Test
public void exhaustiveExpressionSwitch() {
assumeTrue(RuntimeVersion.isAtLeast21());
compilationHelper
.addSourceLines(
"Test.java",
"class Test {",
" sealed interface I permits A, B {}",
" abstract static class S {}",
" static final class A extends S implements I {}",
" static final class B extends S implements I {}",
" void f(I i) {",
" switch (i) {",
" case A a -> System.err.println(a);",
" case B b -> System.err.println(b);",
" };",
" }",
"}")
.doTest();
}
}

0 comments on commit cd6a504

Please sign in to comment.