Skip to content

Commit 1e8401b

Browse files
graememorganError Prone Team
authored andcommitted
CompileTimeConstantExpressionMatcher: Handle switch expressions
This change updates CompileTimeConstantExpressionMatcher to support switch expressions, ensuring that all branches are constant expressions. PiperOrigin-RevId: 789743986
1 parent 2c6417d commit 1e8401b

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

annotations/src/main/java/com/google/errorprone/annotations/CompileTimeConstant.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
* <li>the expression is a {@link String}, and formed from the concatenation of symbols which meet
4242
* these conditions, or
4343
* <li>the expression is a ternary condition, where both branches satisfy these conditions, or
44+
* <li>the expression is a switch expression, where every case is either a constant expression or
45+
* throws, or
4446
* <li>the expression is an immutable collection with all values known to satisfy these conditions
4547
* (for example, {@code ImmutableSet.of("a", "b", "c")}).
4648
* </ol>

check_api/src/main/java/com/google/errorprone/matchers/CompileTimeConstantExpressionMatcher.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@
3030
import com.google.errorprone.annotations.CompileTimeConstant;
3131
import com.google.errorprone.suppliers.Supplier;
3232
import com.sun.source.tree.BinaryTree;
33+
import com.sun.source.tree.CaseTree.CaseKind;
3334
import com.sun.source.tree.ConditionalExpressionTree;
3435
import com.sun.source.tree.ExpressionTree;
3536
import com.sun.source.tree.IdentifierTree;
3637
import com.sun.source.tree.MethodInvocationTree;
3738
import com.sun.source.tree.ParenthesizedTree;
39+
import com.sun.source.tree.SwitchExpressionTree;
40+
import com.sun.source.tree.ThrowTree;
3841
import com.sun.source.tree.Tree;
3942
import com.sun.source.tree.Tree.Kind;
4043
import com.sun.source.tree.TypeCastTree;
@@ -102,6 +105,17 @@ public Boolean visitConditionalExpression(ConditionalExpressionTree tree, Void u
102105
&& tree.getFalseExpression().accept(this, null);
103106
}
104107

108+
@Override
109+
public Boolean visitSwitchExpression(SwitchExpressionTree tree, Void unused) {
110+
// This is intentionally quite restrictive: only accept bare values and throws.
111+
return tree.getCases().stream()
112+
.allMatch(
113+
c ->
114+
c.getCaseKind().equals(CaseKind.RULE)
115+
&& (c.getBody().accept(this, null)
116+
|| c.getBody() instanceof ThrowTree));
117+
}
118+
105119
@Override
106120
public Boolean visitMethodInvocation(MethodInvocationTree tree, Void unused) {
107121
return IMMUTABLE_FACTORY.matches(tree, state)

core/src/test/java/com/google/errorprone/bugpatterns/CompileTimeConstantCheckerTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,4 +887,68 @@ public abstract class CompileTimeConstantTestCase {
887887
""")
888888
.doTest();
889889
}
890+
891+
@Test
892+
public void switchExpression_allBranchesConstant() {
893+
compilationHelper
894+
.addSourceLines(
895+
"Test.java",
896+
"""
897+
import com.google.errorprone.annotations.CompileTimeConstant;
898+
899+
public class Test {
900+
@CompileTimeConstant
901+
final String s =
902+
switch (1) {
903+
case 1 -> "a";
904+
case 2 -> "b";
905+
default -> "c";
906+
};
907+
}
908+
""")
909+
.doTest();
910+
}
911+
912+
@Test
913+
public void switchExpression_notAllBranchesConstant() {
914+
compilationHelper
915+
.addSourceLines(
916+
"Test.java",
917+
"""
918+
import com.google.errorprone.annotations.CompileTimeConstant;
919+
920+
public class Test {
921+
@CompileTimeConstant
922+
final String s =
923+
// BUG: Diagnostic contains:
924+
switch (1) {
925+
case 1 -> "a";
926+
case 2 -> toString();
927+
default -> "c";
928+
};
929+
}
930+
""")
931+
.doTest();
932+
}
933+
934+
@Test
935+
public void switchExpression_onlyConsiderReturningBranches() {
936+
compilationHelper
937+
.addSourceLines(
938+
"Test.java",
939+
"""
940+
import com.google.errorprone.annotations.CompileTimeConstant;
941+
942+
public class Test {
943+
@CompileTimeConstant
944+
final String s =
945+
switch (1) {
946+
case 1 -> "a";
947+
case 2 -> "b";
948+
default -> throw new RuntimeException();
949+
};
950+
}
951+
""")
952+
.doTest();
953+
}
890954
}

0 commit comments

Comments
 (0)