-
Notifications
You must be signed in to change notification settings - Fork 17
Closed
Description
Switch expressions came with Java 14, using them results in this stacktrace: https://gist.github.com/octylFractal/f30df05af3fc15fbf01a1dbc1d136b39
[INFO] [REDACTED]:75:85:expecting COLON, found ';'
[INFO] Instrumentation error
com.atlassian.clover.api.CloverException: [REDACTED]:75:85:expecting COLON, found ';'
at com.atlassian.clover.instr.java.Instrumenter.instrument (Instrumenter.java:159)
at com.atlassian.clover.CloverInstr.execute (CloverInstr.java:76)
at com.atlassian.clover.CloverInstr.mainImpl (CloverInstr.java:54)
...
Caused by: clover.antlr.MismatchedTokenException: expecting COLON, found ';'
at clover.antlr.Parser.match (Parser.java:211)
at com.atlassian.clover.instr.java.JavaRecognizer.aCase (JavaRecognizer.java:4330)
at com.atlassian.clover.instr.java.JavaRecognizer.casesGroup (JavaRecognizer.java:4161)
at com.atlassian.clover.instr.java.JavaRecognizer.statement (JavaRecognizer.java:3640)
at com.atlassian.clover.instr.java.JavaRecognizer.compoundStatement (JavaRecognizer.java:4050)
The code snippet that causes this error:
switch (result) {
case SUCCESS -> System.err.println("Success!");
case FAILURE -> System.err.println("Failure.");
}
another example with blocks:
int j = switch (day) {
case MONDAY -> 0;
case TUESDAY -> 1;
default -> {
int k = day.toString().length();
int result = f(k);
yield result;
}
};
Old style can also leverage the yield and value returned by switch:
A switch expression can, like a switch statement, also use a traditional switch block with "case L:" switch labels (implying fall through semantics). In this case, values are yielded using the new yield statement:
int result = switch (s) {
case "a":
yield 1;
case "b":
yield 2;
default:
yield -1;
};
Specification: https://openjdk.org/jeps/361
To be implemented:
- "case -> " with "default -> " as an alternative switch block grammar (both old and new cannot be mixed?)
- multiple values separated by comma in "case "
- the CAN return a value -> probably have to be wrapped in lambdaInc() like normal lambdas
- the entire switch expression CAN return a value,
** so "a = switch(b) { ...}" must work -> switch expression rule as one of the options for the 'expression' rule
** also passing switch value to a method "foo(switch(b) { ...})" must be handled - blocks with 'yield ;' keyword
- old-style switch with "case:" and yield
What needs no instrumentation:
- scope of variable flowing to next case statements
- don't need to check if all possible options were exhausted in a switch
- any recognition of generic types
marcin-chwedczuk and mtraton