Skip to content

Commit

Permalink
Handle qualified enum elements in MissingCasesInEnumSwitch.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 697598061
  • Loading branch information
graememorgan authored and Error Prone Team committed Nov 18, 2024
1 parent 332cbfa commit b222ea8
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.util.ASTHelpers.getSymbol;
import static com.google.errorprone.util.ASTHelpers.isSwitchDefault;

import com.google.common.collect.ImmutableSet;
Expand All @@ -27,9 +28,11 @@
import com.google.errorprone.bugpatterns.BugChecker.SwitchTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.CaseTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.SwitchTree;
import com.sun.tools.javac.code.Type;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.element.ElementKind;
Expand All @@ -44,25 +47,26 @@ public class MissingCasesInEnumSwitch extends BugChecker implements SwitchTreeMa

@Override
public Description matchSwitch(SwitchTree tree, VisitorState state) {
Type switchType = ASTHelpers.getType(tree.getExpression());
ExpressionTree expression = tree.getExpression();
List<? extends CaseTree> cases = tree.getCases();
Type switchType = ASTHelpers.getType(expression);
if (switchType.asElement().getKind() != ElementKind.ENUM) {
return Description.NO_MATCH;
}
// default case is present
if (tree.getCases().stream().anyMatch(c -> isSwitchDefault(c))) {
if (cases.stream().anyMatch(c -> isSwitchDefault(c))) {
return Description.NO_MATCH;
}
ImmutableSet<String> handled =
tree.getCases().stream()
cases.stream()
.flatMap(c -> c.getExpressions().stream())
.filter(IdentifierTree.class::isInstance)
.map(e -> ((IdentifierTree) e).getName().toString())
.map(e -> getSymbol(e).getSimpleName().toString())
.collect(toImmutableSet());
Set<String> unhandled = Sets.difference(ASTHelpers.enumValues(switchType.asElement()), handled);
if (unhandled.isEmpty()) {
return Description.NO_MATCH;
}
return buildDescription(tree).setMessage(buildMessage(unhandled)).build();
return buildDescription(expression).setMessage(buildMessage(unhandled)).build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,36 @@ void m(Case c) {
.doTest();
}

@Test
public void exhaustive_allowsQualifying() {
assume().that(Runtime.version().feature()).isAtLeast(21);
compilationHelper
.addSourceLines(
"Test.java",
"""
class Test {
enum Case {
ONE,
TWO,
THREE
}
void m(Case c) {
switch (c) {
case Case.ONE:
case Case.TWO:
case Case.THREE:
System.err.println("found it!");
break;
}
}
}
""")
.doTest();
}

@Test
public void exhaustive_multipleCaseExpressions() {
assume().that(Runtime.version().feature()).isAtLeast(14);
compilationHelper
.addSourceLines(
"Test.java",
Expand Down Expand Up @@ -209,7 +236,6 @@ void m(Case e) {

@Test
public void nonExhaustive_arrowStatement() {
assume().that(Runtime.version().feature()).isAtLeast(14);
compilationHelper
.addSourceLines(
"Test.java",
Expand All @@ -235,7 +261,6 @@ void m(Case c) {

@Test
public void nonExhaustive_multi() {
assume().that(Runtime.version().feature()).isAtLeast(14);
compilationHelper
.addSourceLines(
"Test.java",
Expand All @@ -261,7 +286,6 @@ void m(Case c) {

@Test
public void nonExhaustive_multiArrow() {
assume().that(Runtime.version().feature()).isAtLeast(14);
compilationHelper
.addSourceLines(
"Test.java",
Expand Down

0 comments on commit b222ea8

Please sign in to comment.