ANN Switch Expressions in IntelliJ 2019.1 EAP
Brian Goetz
brian.goetz at oracle.com
Wed Feb 27 22:52:37 UTC 2019
I got around to trying this out on the JDK.
Here's an example of where it correctly refactors:
if (caltype !=null) {
switch (caltype) {
case "buddhist":
cal =new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal =new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal =new GregorianCalendar(zone, aLocale);
break;
}
to
switch (caltype) {
case "buddhist" -> cal =new BuddhistCalendar(zone, aLocale);
case "japanese" -> cal =new JapaneseImperialCalendar(zone, aLocale);
case "gregory" -> cal =new GregorianCalendar(zone, aLocale);
}
But, I would have expected it to do this instead:
cal =switch (caltype) {
case "buddhist" ->new BuddhistCalendar(zone, aLocale);
case "japanese" ->new JapaneseImperialCalendar(zone, aLocale);
case "gregory" ->new GregorianCalendar(zone, aLocale);
}
The latter is much better style (expressions all the way down, less repetition, less error-prone).
Similarly, if each RHS is a cast to the same target, you may want to factor the cast out as well.
But, it gets it right when transforming something like:
private static CharPredicate getPosixPredicate(String name) {
switch (name) {
case "ALPHA":return ALPHABETIC();
case "LOWER":return LOWERCASE();
case "UPPER":return UPPERCASE();
case "SPACE":return WHITE_SPACE();
case "PUNCT":return PUNCTUATION();
case "XDIGIT":return HEX_DIGIT();
case "ALNUM":return ALNUM();
case "CNTRL":return CONTROL();
case "DIGIT":return DIGIT();
case "BLANK":return BLANK();
case "GRAPH":return GRAPH();
case "PRINT":return PRINT();
default:return null;
}
}
the return is pulled out.
When transforming
switch (name) {
case "ALPHABETIC":return ALPHABETIC();
case "ASSIGNED":return ASSIGNED();
case "CONTROL":return CONTROL();
case "HEXDIGIT":return HEX_DIGIT();
case "IDEOGRAPHIC":return IDEOGRAPHIC();
case "JOINCONTROL":return JOIN_CONTROL();
case "LETTER":return LETTER();
case "LOWERCASE":return LOWERCASE();
case "NONCHARACTERCODEPOINT":return NONCHARACTER_CODE_POINT();
case "TITLECASE":return TITLECASE();
case "PUNCTUATION":return PUNCTUATION();
case "UPPERCASE":return UPPERCASE();
case "WHITESPACE":return WHITE_SPACE();
case "WORD":return WORD();
case "WHITE_SPACE":return WHITE_SPACE();
case "HEX_DIGIT":return HEX_DIGIT();
case "NONCHARACTER_CODE_POINT":return NONCHARACTER_CODE_POINT();
case "JOIN_CONTROL":return JOIN_CONTROL();
default:return null;
}
I noticed it didn't merge, say, WHITESPACE and WHITE_SPACE with commas; it did offer to do that as a follow-on refactor.
Here's one it didn't try to transform at all, even though all paths are basically "status = ..; break":
switch (state) {
case NORMAL:
status ="[Completed normally]";
break;
case EXCEPTIONAL:
status ="[Completed exceptionally: " +outcome +"]";
break;
case CANCELLED:
case INTERRUPTING:
case INTERRUPTED:
status ="[Cancelled]";
break;
default:
final Callable<?> callable =this.callable;
status = (callable ==null)
?"[Not completed]" :"[Not completed, task = " + callable +"]";
}
I might factor the switch refactor into two; one for expressions and one for statements. While the -> form is sometimes useful for statements, refactoring often doesn't gain nearly as much as for expressions. Separating them allows people to set them at different levels of severity.
On 1/29/2019 12:49 PM, Anna Kozlova wrote:
> Hi all,
>
> we have initially supported switch expressions, please give it a try.
>
> The download link: https://www.jetbrains.com/idea/nextversion/
>
> Your feedback is very welcome.
> Thanks,
> Anna
More information about the amber-dev
mailing list