Check documentation: https://checkstyle.sourceforge.io/config_coding.html#MissingSwitchDefault
> javac Sample.java
> type config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="charset" value="UTF-8"/>
<module name="TreeWalker">
<module name="MissingSwitchDefault"/>
</module>
</module>
> type Sample.java
public class Sample {
public enum Options {
ONE,
TWO,
THREE
}
public int foo(Options option) {
switch (option) { // violation
case ONE:
return 1;
case TWO:
return 2;
case THREE:
return 3;
}
return 0;
}
public int bar(Options option) {
return switch (option) { // violation, but not expected
case ONE -> 1;
case TWO -> 2;
case THREE -> 3;
};
}
}
> set RUN_LOCALE="-Duser.language=en -Duser.country=US"
> java %RUN_LOCALE% -jar checkstyle-8.36-all.jar -c config.xml Sample.java
Starting audit...
[ERROR] C:\temp\Sample.java:9:9: switch without "default" clause. [MissingSwitchDefault]
[ERROR] C:\temp\Sample.java:22:16: switch without "default" clause. [MissingSwitchDefault]
Audit done.
Checkstyle ends with 2 errors.
Expected:
no violation on line 22 as compiler will validate this and cause compiler error, so no need for additional static analysis.
Describe what you expect in detail.
The changes related to https://github.com/checkstyle/checkstyle/issues/8672 allow Java 14 switch expressions to be parsed by Checkstyle now 馃憤. However, the compiler enforces exhaustive branches for switch _expressions_, and ideally there'd be a way to only have this check apply to the original switch statement syntax.
The original rationale behind the MissingSwitchDefault check stated in the docs makes sense for the original switch statements:
Rationale: It's usually a good idea to introduce a default case in every switch statement. Even if the developer is sure that all currently possible cases are covered, this should be expressed in the default branch, e.g. by using an assertion. This way the code is protected against later changes, e.g. introduction of new types in an enumeration type.
However, Java 14 switch expressions must be exhaustive otherwise there will be a compilation error. If the logic isn't exhaustive, a default case is already mandatory in order for the expression to be valid. And if there is no default case, adding a new element to the enumeration in the future requires an update to the expression in order to compile. For example, removing the case THREE -> 3; line yields:
> javac Sample.java
Sample.java:22: error: the switch expression does not cover all possible input values
return switch (option) {
^
1 error
In the example code above, the desired state is for the syntax in the foo method to remain a violation as part of the check, and the bar method to not be a violation as the compiler is enforcing a stronger guarantee than adding a default would provide. This seems like a better default behavior to me, but adding a property to configure the behavior of whether or not switch _expressions_ are evaluated by the check would also be reasonable.
We should not demand "default:" in such case. Checkstyle does not validate what is covered by compiler.
No new property is required, if new syntax is used.
@pbludov , I ma ok to approve bug, please do second review.
Yes, this is a bug. @nmancus1, can you take some time to solve this issue?
@pbludov I will submit a PR this week.
@romani @pbludov can we edit the name of this issue to match the PR, since this ended up being a bug report and not a feature request?
Done
Fix is merged
Most helpful comment
@pbludov I will submit a PR this week.