Skip to content

Commit

Permalink
Issue checkstyle#6615: Add support for Java 14 switch
Browse files Browse the repository at this point in the history
  • Loading branch information
octylFractal committed Apr 25, 2020
1 parent 11bb48a commit 8d39027
Show file tree
Hide file tree
Showing 5 changed files with 1,143 additions and 8 deletions.
2 changes: 2 additions & 0 deletions config/checkstyle_non_main_files_suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
files="src[\\/]test[\\/]resources[\\/].*[\\/]InputLineLength.*\.java"/>
<suppress id="lineLength"
files="src[\\/]test[\\/]resources[\\/].*[\\/]grammar[\\/]comments[\\/].*"/>
<suppress id="lineLength"
files="src[\\/]test[\\/]resources[\\/].*[\\/]grammar[\\/]InputRegressionJava14SwitchExpressionAst\.txt"/>
<suppress id="lineLength"
files="src[\\/]test[\\/]resources[\\/].*[\\/]asttreestringprinter[\\/]InputAstTreeStringPrinterFullOfBlockComments\.java"/>
<suppress id="lineLength"
Expand Down
44 changes: 36 additions & 8 deletions src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java.g
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,9 @@ traditionalStatement
// up, but that's pretty hard without a symbol table ;)
| (declaration)=> declaration SEMI
// switch/case statement
| "switch"^ LPAREN expression RPAREN switchBlock
// An expression statement. This could be a method call,
// assignment statement, or any other expression evaluated for
// side-effects.
Expand Down Expand Up @@ -1095,16 +1098,11 @@ traditionalStatement
// Return an expression
| "return"^ (expression)? SEMI
// switch/case statement
| "switch"^ LPAREN expression RPAREN LCURLY
( casesGroup )*
RCURLY
// exception try-catch block
| tryBlock
// throw an exception
| "throw"^ expression SEMI
| throwStatement
// synchronize a statement
| "synchronized"^ LPAREN expression RPAREN compoundStatement
Expand Down Expand Up @@ -1145,6 +1143,12 @@ elseStatement
: "else"^ statement
;
switchBlock
: LCURLY
( casesGroup )*
RCURLY
;
casesGroup
: ( // CONFLICT: to which case group do the statements bind?
// ANTLR generates proper code: it groups the
Expand All @@ -1161,7 +1165,16 @@ casesGroup
;
aCase
: ("case"^ expression | "default"^) COLON
: ("case"^ exprConditionalExpression (COMMA exprConditionalExpression )* | "default"^)
( COLON
| LAMBDA switchRule
)
;
// Compatibility hack, wraps our conditionalExpression with the EXPR AST node
exprConditionalExpression
: conditionalExpression
{#exprConditionalExpression = #(#[EXPR,"EXPR"],#exprConditionalExpression);}
;
caseSList
Expand All @@ -1179,6 +1192,16 @@ caseSList
{#caseSList = #(#[SLIST,"SLIST"],#caseSList);}
;
// New Java 14 switch rules
switchRule
:
( // can be one of an expression, block of statements, or throw statement
expression SEMI
| compoundStatement
| throwStatement
)
;
// The initializer for a for loop
forInit
// if it looks like a declaration, it is
Expand Down Expand Up @@ -1212,6 +1235,10 @@ tryBlock
( finallyHandler )?
;
throwStatement
: "throw"^ expression SEMI
;
resourceSpecification
: LPAREN resources (SEMI)? RPAREN
{#resourceSpecification =
Expand Down Expand Up @@ -1404,7 +1431,8 @@ unaryExpression
;
unaryExpressionNotPlusMinus
: BNOT^ unaryExpression
: "switch"^ LPAREN expression RPAREN switchBlock
| BNOT^ unaryExpression
| LNOT^ unaryExpression
| ( // subrule allows option to shut off warnings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ public void testJava8InterfaceAstTree1() throws Exception {
getPath("InputRegressionJava8Interface1.java"));
}

@Test
public void testJava14SwitchExpression() throws Exception {
verifyAst(getPath("InputRegressionJava14SwitchExpressionAst.txt"),
getNonCompilablePath("InputRegressionJava14SwitchExpression.java"));
}

@Test
public void testEnumAstTree1() throws Exception {
verifyAst(getPath("InputRegressionJavaEnum1Ast.txt"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//non-compiled with javac: Compilable with Java14
package com.puppycrawl.tools.checkstyle.grammar;

import java.util.EnumSet;
import java.util.Set;

public class InputRegressionJava14SwitchExpression {

enum Day {
MON,
TUE,
WED,
THU,
FRI,
SAT,
SUN,
}

String whatIsToday(Day day) {
return switch (day) {
case SAT, SUN -> "Weekend";
case MON, TUE, WED, THU, FRI -> "Working day";
default -> throw new IllegalArgumentException("Invalid day: " + day.name());
};
}

Set<Day> days(String weekPart) {
return switch (weekPart) {
case "Weekend" -> EnumSet.of(Day.SAT, Day.SUN);
case "Working day" -> EnumSet.of(Day.MON, Day.TUE, Day.WED, Day.THU, Day.FRI);
default -> throw new IllegalArgumentException("Invalid weekPart: " + weekPart);
};
}

String isDayNameLong(Day day) {
return switch (day) {
case MON, FRI, SUN -> 6;
case TUE -> 7;
case THU, SAT -> 8;
case WED -> 9;
} > 7 ? "long" : "short";
}

int assignement(Day day) {
int numLetters = switch (day) {
case MON, FRI, SUN -> 6;
case TUE -> 7;
case THU, SAT -> 8;
case WED -> 9;
};
return numLetters;
}

static void howMany(int k) {
switch (k) {
case 1 -> System.out.println("one");
case 2 -> System.out.println("two");
case 3 -> System.out.println("many");
default -> throw new IllegalArgumentException("Unknown");
}
}

int methodCalls(Day day) {
return switch (day) {
case MON, TUE -> Math.addExact(0, 1);
case WED -> Math.addExact(1, 1);
default -> {
yield Math.addExact(2, 1);
}
};
}

int yieldAcceptsExpressions(Day day) {
return switch (day) {
case MON, TUE -> 0;
case WED -> 1;
default -> day.toString().length() > 5 ? 1 : 0;
};
}

int complexCase(Day day) {
return switch (day) {
case MON, TUE -> {
int l = day.toString().length();
yield Math.addExact(l, 0);
}
case WED -> {
int l = day.toString().length();
yield Math.addExact(l, 1);
}
default -> {
int l = day.toString().length();
yield Math.addExact(l, 2);
}
};
}

int arithmetic(Day day) {
return switch (day) {
case MON, FRI, SUN -> 6;
case TUE -> 7;
case THU, SAT -> 8;
case WED -> 9;
} % 2;
}

int signArithmetic(Day day) {
return - switch (day) {
case MON, FRI, SUN -> 6;
case TUE -> 7;
case THU, SAT -> 8;
case WED -> 9;
};
}

int usedOnBothSidesOfAriphmeticExpression(Day day) {
return switch (day) {
case MON, TUE -> 0;
case WED -> 1;
default -> 2;
} * switch (day) {
case WED, THU -> 3;
case FRI -> 4;
default -> 5;
};
}

}
Loading

0 comments on commit 8d39027

Please sign in to comment.