Check for diamond operator for anonymous classes

This commit is contained in:
Andreas Dangel
2017-09-22 14:31:24 +02:00
parent 722b2b1657
commit 77222904de
5 changed files with 46 additions and 3 deletions

View File

@ -1,7 +1,8 @@
/**
* Add support for Java 9 changes
* private interface methods are only allowed with java9,
* a single underscore "_" is an invalid identifier in java9.
* Add support for Java 9 changes:
* Private interface methods are only allowed with java9.
* A single underscore "_" is an invalid identifier in java9.
* Diamond operator for anonymous classes is only allowed with java9.
* Andreas Dangel 09/2017
*====================================================================
* Add support for new Java 8 annotation locations.
@ -324,6 +325,15 @@ public class JavaParser {
throwParseException("Cannot use explicit receiver parameters when running in JDK inferior to 1.8 mode!");
}
}
private void checkForBadAnonymousDiamondUsage() {
if (jdkVersion < 9) {
ASTAllocationExpression node = (ASTAllocationExpression)jjtree.peekNode();
ASTTypeArguments types = node.getFirstDescendantOfType(ASTTypeArguments.class);
if (node.isAnonymousClass() && types != null && types.isDiamond()) {
throwParseException("Cannot use '<>' with anonymous inner classes when running in JDK inferior to 9 mode!");
}
}
}
/**
* Keeps track whether we are dealing with an interface or not. Needed since the tree is
* is not fully constructed yet, when we check for private interface methods.
@ -1960,6 +1970,7 @@ void AllocationExpression():
Arguments() [ ClassOrInterfaceBody() ]
)
)
{ checkForBadAnonymousDiamondUsage(); }
}
/*

View File

@ -5,6 +5,8 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.lang.ast.Node;
public class ASTAllocationExpression extends AbstractJavaTypeNode {
public ASTAllocationExpression(int id) {
super(id);
@ -20,4 +22,12 @@ public class ASTAllocationExpression extends AbstractJavaTypeNode {
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public boolean isAnonymousClass() {
if (jjtGetNumChildren() > 1) {
Node lastChild = jjtGetChild(jjtGetNumChildren() - 1);
return lastChild instanceof ASTClassOrInterfaceBody;
}
return false;
}
}

View File

@ -20,4 +20,8 @@ public class ASTTypeArguments extends AbstractJavaNode {
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public boolean isDiamond() {
return jjtGetNumChildren() == 0;
}
}

View File

@ -237,4 +237,14 @@ public class JDKVersionTest {
public final void jdk9InvalidIdentifier() {
parseJava9(loadSource("jdk9_invalid_identifier.java"));
}
@Test(expected = ParseException.class)
public final void jdk9AnonymousDiamondInJava8() {
parseJava18(loadSource("jdk9_anonymous_diamond.java"));
}
@Test
public final void jdk9AnonymousDiamond() {
parseJava9(loadSource("jdk9_anonymous_diamond.java"));
}
}

View File

@ -0,0 +1,8 @@
import java.util.HashSet;
import java.util.Set;
public class Java9AnonymousDiamond {
public static void main(String ... args) {
Set<String> set = new HashSet<>() { };
}
}