[java] Add Java12 support
This commit is contained in:
Andreas Dangel
committed by
Andreas Dangel
parent
e1f067ab52
commit
8949019da6
@ -378,6 +378,21 @@ public class JavaParser {
|
||||
throwParseException("With JDK 10, 'var' is a restricted local variable type and cannot be used for type declarations!");
|
||||
}
|
||||
}
|
||||
private void checkForMultipleCaseLabels() {
|
||||
if (jdkVersion < 12) {
|
||||
throwParseException("Multiple case labels in switch statements are only supported with Java 12");
|
||||
}
|
||||
}
|
||||
private void checkForSwitchRules() {
|
||||
if (jdkVersion < 12) {
|
||||
throwParseException("Switch rules in switch statements are only supported with Java 12");
|
||||
}
|
||||
}
|
||||
private void checkForSwitchExpression() {
|
||||
if (jdkVersion < 12) {
|
||||
throwParseException("Switch expressions are only supported with Java 12");
|
||||
}
|
||||
}
|
||||
|
||||
// This is a semantic LOOKAHEAD to determine if we're dealing with an assert
|
||||
// Note that this can't be replaced with a syntactic lookahead
|
||||
@ -2006,10 +2021,14 @@ void Expression() :
|
||||
// https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.27
|
||||
{}
|
||||
{
|
||||
LOOKAHEAD((<IDENTIFIER>|LambdaParameters()) "->" ) LambdaExpression()
|
||||
|
|
||||
(
|
||||
ConditionalExpression()
|
||||
[
|
||||
LOOKAHEAD(2) AssignmentOperator() Expression()
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
void AssignmentOperator() :
|
||||
@ -2140,13 +2159,14 @@ void UnaryExpressionNotPlusMinus() #UnaryExpressionNotPlusMinus((jjtn000.getImag
|
||||
{
|
||||
( "~" {jjtThis.setImage("~");} | "!" {jjtThis.setImage("!");} ) UnaryExpression()
|
||||
/*
|
||||
* This is really ugly... we are repeting the CastExpression lookahead and full expression...
|
||||
* This is really ugly... we are repeating the CastExpression lookahead and full expression...
|
||||
* If we don't the lookahead within CastExpression is ignored, and it simply looks for the expression,
|
||||
* meaning we can't be explicit as to what can be casted depending on the cast type (primitive or otherwhise)
|
||||
*/
|
||||
| LOOKAHEAD("(" (Annotation())* PrimitiveType() ")") CastExpression()
|
||||
| LOOKAHEAD("(" (Annotation())* Type() ( "&" ReferenceType() )* ")" UnaryExpressionNotPlusMinus()) CastExpression()
|
||||
| PostfixExpression()
|
||||
| SwitchExpression()
|
||||
}
|
||||
|
||||
void PostfixExpression() #PostfixExpression((jjtn000.getImage() != null)):
|
||||
@ -2164,6 +2184,13 @@ void CastExpression() :
|
||||
| "(" (TypeAnnotation())* Type() ( "&" {checkForBadIntersectionTypesInCasts(); jjtThis.setIntersectionTypes(true);} ReferenceType() )* ")" UnaryExpressionNotPlusMinus()
|
||||
}
|
||||
|
||||
void SwitchExpression() :
|
||||
{}
|
||||
{
|
||||
{checkForSwitchExpression();}
|
||||
"switch" "(" Expression() ")" "{" SwitchBlock() "}"
|
||||
}
|
||||
|
||||
void PrimaryExpression() :
|
||||
{}
|
||||
{
|
||||
@ -2191,9 +2218,9 @@ void PrimaryPrefix() :
|
||||
Literal()
|
||||
| LOOKAHEAD(2) "this" {jjtThis.setUsesThisModifier();}
|
||||
| "super" {jjtThis.setUsesSuperModifier();}
|
||||
| LOOKAHEAD( <IDENTIFIER> "->" ) LambdaExpression()
|
||||
| LOOKAHEAD( "(" VariableDeclaratorId() ( "," VariableDeclaratorId() )* ")" "->" ) LambdaExpression()
|
||||
| LOOKAHEAD( FormalParameters() "->" ) LambdaExpression()
|
||||
//| LOOKAHEAD( <IDENTIFIER> "->" ) LambdaExpression()
|
||||
//| LOOKAHEAD( "(" VariableDeclaratorId() ( "," VariableDeclaratorId() )* ")" "->" ) LambdaExpression()
|
||||
//| LOOKAHEAD( FormalParameters() "->" ) LambdaExpression()
|
||||
| LOOKAHEAD(3) "(" Expression() ")"
|
||||
| AllocationExpression()
|
||||
| LOOKAHEAD( ResultType() "." "class" ) ResultType() "." "class"
|
||||
@ -2415,20 +2442,51 @@ void StatementExpression() :
|
||||
PostfixExpression()
|
||||
}
|
||||
|
||||
void SwitchStatement() :
|
||||
void SwitchStatement():
|
||||
{}
|
||||
{
|
||||
"switch" "(" Expression() ")" "{"
|
||||
( SwitchLabel() ( BlockStatement() )* )*
|
||||
SwitchBlock()
|
||||
"}"
|
||||
}
|
||||
|
||||
void SwitchBlock() #void :
|
||||
{}
|
||||
{
|
||||
(
|
||||
SwitchLabel()
|
||||
(
|
||||
"->" ( Expression() ";" | Block() | ThrowStatement() )
|
||||
|
|
||||
":" (SwitchLabel() ":")* ( BlockStatement() )*
|
||||
)
|
||||
)*
|
||||
/*
|
||||
LOOKAHEAD(SwitchLabel() "->") SwitchLabeledRule() ( SwitchLabeledRule() )*
|
||||
|
|
||||
( SwitchLabeledStatementGroup() )*
|
||||
*/
|
||||
}
|
||||
|
||||
void SwitchLabeledStatementGroup() #void:
|
||||
{}
|
||||
{
|
||||
SwitchLabel() ":" (SwitchLabel() ":")* ( BlockStatement() )*
|
||||
}
|
||||
|
||||
void SwitchLabel() :
|
||||
{}
|
||||
{
|
||||
"case" Expression() ":"
|
||||
"case" ConditionalExpression() ({checkForMultipleCaseLabels();} "," ConditionalExpression())*
|
||||
|
|
||||
"default" {jjtThis.setDefault();} ":"
|
||||
"default" {jjtThis.setDefault();}
|
||||
}
|
||||
|
||||
void SwitchLabeledRule():
|
||||
{}
|
||||
{
|
||||
{checkForSwitchRules();}
|
||||
SwitchLabel() "->" ( Expression() ";" | Block() | ThrowStatement() )
|
||||
}
|
||||
|
||||
void IfStatement() :
|
||||
|
@ -25,7 +25,8 @@ public class JavaLanguageModule extends BaseLanguageModule {
|
||||
addVersion("1.8", new JavaLanguageHandler(8), false);
|
||||
addVersion("9", new JavaLanguageHandler(9), false);
|
||||
addVersion("10", new JavaLanguageHandler(10), false);
|
||||
addVersion("11", new JavaLanguageHandler(11), true);
|
||||
addVersion("11", new JavaLanguageHandler(11), false);
|
||||
addVersion("12", new JavaLanguageHandler(12), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
/* Generated By:JJTree: Do not edit this line. ASTSwitchLabeledRule.java Version 4.3 */
|
||||
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=true,VISITOR=true,TRACK_TOKENS=true,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public
|
||||
class ASTSwitchExpression extends AbstractJavaNode {
|
||||
ASTSwitchExpression(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTSwitchExpression(JavaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
|
||||
/** Accept the visitor. **/
|
||||
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=8b1747ca53f66203ee212a3699a9a2f3 (do not edit this line) */
|
@ -0,0 +1,21 @@
|
||||
/* Generated By:JJTree: Do not edit this line. ASTSwitchLabeledRule.java Version 4.3 */
|
||||
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=true,VISITOR=true,TRACK_TOKENS=true,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public
|
||||
class ASTSwitchLabeledRule extends AbstractJavaNode {
|
||||
ASTSwitchLabeledRule(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
ASTSwitchLabeledRule(JavaParser p, int id) {
|
||||
super(p, id);
|
||||
}
|
||||
|
||||
|
||||
/** Accept the visitor. **/
|
||||
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
}
|
||||
/* JavaCC - OriginalChecksum=8b1747ca53f66203ee212a3699a9a2f3 (do not edit this line) */
|
@ -868,4 +868,16 @@ public class JavaParserDecoratedVisitor implements JavaParserVisitor {
|
||||
visitor.visit(node, data);
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchLabeledRule node, Object data) {
|
||||
visitor.visit(node, data);
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchExpression node, Object data) {
|
||||
visitor.visit(node, data);
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
}
|
||||
|
@ -600,4 +600,14 @@ public class JavaParserVisitorAdapter implements JavaParserVisitor {
|
||||
public Object visit(ASTModuleName node, Object data) {
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchLabeledRule node, Object data) {
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchExpression node, Object data) {
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
}
|
||||
|
@ -730,4 +730,14 @@ public class JavaParserVisitorDecorator implements JavaParserControllessVisitor
|
||||
public Object visit(ASTModuleName node, Object data) {
|
||||
return visitor.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchLabeledRule node, Object data) {
|
||||
return visitor.visit(node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchExpression node, Object data) {
|
||||
return visitor.visit(node, data);
|
||||
}
|
||||
}
|
||||
|
@ -674,4 +674,14 @@ public abstract class AbstractJavaRule extends AbstractRule implements JavaParse
|
||||
public Object visit(ASTModuleName node, Object data) {
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchLabeledRule node, Object data) {
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTSwitchExpression node, Object data) {
|
||||
return visit((JavaNode) node, data);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.ParseException;
|
||||
import net.sourceforge.pmd.lang.java.ParserTstUtil;
|
||||
|
||||
public class Java12Test {
|
||||
private static String loadSource(String name) {
|
||||
try {
|
||||
return IOUtils.toString(Java10Test.class.getResourceAsStream("jdkversiontests/java12/" + name),
|
||||
StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = ParseException.class)
|
||||
public void testMultipleCaseLabelsJava11() {
|
||||
ParserTstUtil.parseAndTypeResolveJava("11", loadSource("MultipleCaseLabels.java"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleCaseLabels() {
|
||||
ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("12",
|
||||
loadSource("MultipleCaseLabels.java"));
|
||||
Assert.assertNotNull(compilationUnit);
|
||||
}
|
||||
|
||||
@Test(expected = ParseException.class)
|
||||
public void testSwitchRulesJava11() {
|
||||
ParserTstUtil.parseAndTypeResolveJava("11", loadSource("SwitchRules.java"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitchRules() {
|
||||
ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("12",
|
||||
loadSource("SwitchRules.java"));
|
||||
Assert.assertNotNull(compilationUnit);
|
||||
}
|
||||
|
||||
@Test(expected = ParseException.class)
|
||||
public void testSwitchExpressionsJava11() {
|
||||
ParserTstUtil.parseAndTypeResolveJava("11", loadSource("SwitchExpressions.java"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitchExpressions() {
|
||||
ASTCompilationUnit compilationUnit = ParserTstUtil.parseAndTypeResolveJava("12",
|
||||
loadSource("SwitchExpressions.java"));
|
||||
Assert.assertNotNull(compilationUnit);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
public class MultipleCaseLabels {
|
||||
private static final int MONDAY = 1;
|
||||
private static final int TUESDAY = 2;
|
||||
private static final int WEDNESDAY = 3;
|
||||
private static final int THURSDAY = 4;
|
||||
private static final int FRIDAY = 5;
|
||||
private static final int SATURDAY = 6;
|
||||
private static final int SUNDAY = 7;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
int day = THURSDAY;
|
||||
|
||||
switch (day) {
|
||||
case MONDAY, FRIDAY, SUNDAY: System.out.println(" 6"); break;
|
||||
case TUESDAY : System.out.println(" 7"); break;
|
||||
case THURSDAY, SATURDAY : System.out.println(" 8"); break;
|
||||
case WEDNESDAY : System.out.println(" 9"); break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
public class SwitchExpressions {
|
||||
private static final int MONDAY = 1;
|
||||
private static final int TUESDAY = 2;
|
||||
private static final int WEDNESDAY = 3;
|
||||
private static final int THURSDAY = 4;
|
||||
private static final int FRIDAY = 5;
|
||||
private static final int SATURDAY = 6;
|
||||
private static final int SUNDAY = 7;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
int day = FRIDAY;
|
||||
|
||||
int numLetters = switch (day) {
|
||||
case MONDAY, FRIDAY, SUNDAY -> 6;
|
||||
case TUESDAY -> 7;
|
||||
case THURSDAY, SATURDAY -> 8;
|
||||
case WEDNESDAY -> 9;
|
||||
default -> {
|
||||
int k = day * 2;
|
||||
int result = f(k);
|
||||
break result;
|
||||
}
|
||||
};
|
||||
System.out.printf("NumLetters: %d%n", numLetters);
|
||||
}
|
||||
|
||||
private static int f(int k) {
|
||||
return k*3;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
public class SwitchRules {
|
||||
private static final int MONDAY = 1;
|
||||
private static final int TUESDAY = 2;
|
||||
private static final int WEDNESDAY = 3;
|
||||
private static final int THURSDAY = 4;
|
||||
private static final int FRIDAY = 5;
|
||||
private static final int SATURDAY = 6;
|
||||
private static final int SUNDAY = 7;
|
||||
|
||||
public static void main(String[] args) {
|
||||
int day = WEDNESDAY;
|
||||
|
||||
switch (day) {
|
||||
case MONDAY, FRIDAY, SUNDAY -> System.out.println(" 6");
|
||||
case TUESDAY -> System.out.println(" 7");
|
||||
case THURSDAY, SATURDAY -> System.out.println(" 8");
|
||||
case WEDNESDAY -> System.out.println(" 9");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user