Skip to content

Commit 9180ff4

Browse files
authored
Add switch-const-case-after-pattern-case.ql
1 parent e3bc505 commit 9180ff4

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Finds `switch` expressions and statements where a pattern case with guard (`when ...`) appears before
3+
* a const case such as `case 1`.
4+
*
5+
* For such code the compiler cannot determine if the const case is actually unreachable, and it
6+
* might also lead to less efficient code where the guard is evaluated even if the const case would
7+
* match.
8+
*
9+
* For example:
10+
* ```java
11+
* switch (string) {
12+
* case String s when !s.startsWith("prefix") -> ...;
13+
* // Bad: const case after pattern case
14+
* case "" -> ...;
15+
* default -> ...;
16+
* }
17+
* ```
18+
* In this example the `case ""` is actually unreachable (the `case String ...` covers it) but the
19+
* compiler cannot detect it.
20+
*
21+
* See also [Java documentation "Pattern Matching with switch": "Pattern Label Dominance"](https://docs.oracle.com/en/java/javase/26/language/pattern-matching-switch.html#GUID-08C56E57-B95B-45D8-930D-E3FAFA29B5B7).
22+
*
23+
* @kind problem
24+
* @id TODO
25+
*/
26+
27+
// Note: At least in current Java versions it might be unlikely that such code occurs in practice because
28+
// const cases apparently have to match the switch condition type, e.g. `case "..."` is not possible for
29+
// a `switch (object)`
30+
31+
import java
32+
33+
from
34+
SwitchBlock parent, int constIndex, ConstCase constCase, int patternIndex, PatternCase patternCase
35+
where
36+
constCase.isNthCaseOf(parent, constIndex) and
37+
patternCase.isNthCaseOf(parent, patternIndex) and
38+
constIndex > patternIndex and
39+
// For pattern case without guard, compiler will detect unreachable patterns
40+
exists(patternCase.getGuard()) and
41+
// Ignore `case null` which cannot be accidentally matched by non-null pattern case
42+
not constCase.getValue() instanceof NullLiteral
43+
select constCase, "Should appear before $@", patternCase, "pattern case"

0 commit comments

Comments
 (0)