Fix java changes

Refs #2714
This commit is contained in:
Clément Fournier
2020-08-22 20:48:21 +02:00
parent 05727ace87
commit 9ff940a157
9 changed files with 67 additions and 51 deletions

View File

@ -257,6 +257,16 @@ class JavaParserImpl {
this.preview = preview;
}
private boolean isRecordTypeSupported() {
return (jdkVersion == 14 || jdkVersion == 15) && preview;
}
private boolean isSealedClassSupported() {
return jdkVersion == 15 && preview;
}
/**
* Keeps track during tree construction, whether we are currently building a switch label.
* A switch label must not contain a LambdaExpression.
@ -321,11 +331,11 @@ class JavaParserImpl {
*/
private boolean isNonSealedModifier() {
if (isKeyword(1, "non") && isToken(2, MINUS) && isKeyword(3, "sealed")) {
Token nonToken = getToken(1);
Token minusToken = getToken(2);
Token sealedToken = getToken(3);
return nonToken.endColumn + 1 == minusToken.beginColumn
&& minusToken.endColumn + 1 == sealedToken.beginColumn;
JavaccToken nonToken = getToken(1);
JavaccToken minusToken = getToken(2);
JavaccToken sealedToken = getToken(3);
return nonToken.getEndColumn() == minusToken.getBeginColumn()
&& minusToken.getEndColumn() == sealedToken.getBeginColumn();
}
return false;
}
@ -894,8 +904,8 @@ int Modifiers() #void:
| "volatile" { modifiers |= AccessNode.VOLATILE; }
| "strictfp" { modifiers |= AccessNode.STRICTFP; }
| "default" { modifiers |= AccessNode.DEFAULT; }
| LOOKAHEAD({isKeyword("sealed")}) <IDENTIFIER> { modifiers |= AccessNode.SEALED; checkForSealedClassUsage(); }
| LOOKAHEAD({isNonSealedModifier()}) <IDENTIFIER> <MINUS> <IDENTIFIER> { modifiers |= AccessNode.NON_SEALED; checkForSealedClassUsage(); }
| LOOKAHEAD({isKeyword("sealed")}) <IDENTIFIER> { modifiers |= AccessNode.SEALED; }
| LOOKAHEAD({isNonSealedModifier()}) <IDENTIFIER> <MINUS> <IDENTIFIER> { modifiers |= AccessNode.NON_SEALED; }
| Annotation()
)
)*
@ -958,7 +968,6 @@ void ImplementsList():
void PermittedSubclasses() #PermitsList:
{
Token t;
checkForSealedClassUsage();
}
{
t = <IDENTIFIER> {
@ -1721,9 +1730,9 @@ void BlockStatement():
LOOKAHEAD({localTypeDeclLookahead()}) LocalTypeDecl(mods)
|
{
List<Node> annotationsAndChildren = new ArrayList<Node>();
List<ASTAnnotation> annotations = new ArrayList<ASTAnnotation>();
while (jjtree.peekNode() instanceof ASTAnnotation) {
annotationsAndChildren.add(jjtree.popNode());
annotations.add((ASTAnnotation) jjtree.popNode());
}
}
LocalVariableDeclaration()
@ -1732,15 +1741,10 @@ void BlockStatement():
if ((mods & AccessNode.FINAL) == AccessNode.FINAL) {
localVarDecl.setFinal(true);
}
if (!annotationsAndChildren.isEmpty()) {
Collections.reverse(annotationsAndChildren);
for (int i = 0; i < localVarDecl.getNumChildren(); i++) {
annotationsAndChildren.add(localVarDecl.getChild(i));
}
for (int i = 0; i < annotationsAndChildren.size(); i++) {
Node child = annotationsAndChildren.get(i);
child.jjtSetParent(localVarDecl);
localVarDecl.jjtAddChild(child, i);
if (!annotations.isEmpty()) {
Collections.reverse(annotations);
for (ASTAnnotation a : annotations) {
localVarDecl.insertChild(a, 0);
}
}
}
@ -1760,10 +1764,10 @@ void LocalTypeDecl(int mods) #void:
{
(
LOOKAHEAD(<CLASS>) ClassOrInterfaceDeclaration(mods)
| LOOKAHEAD(<INTERFACE>) ClassOrInterfaceDeclaration(mods) { checkForLocalInterfaceOrEnumType(); }
| LOOKAHEAD({isKeyword("record")}) RecordDeclaration(mods) { checkForLocalInterfaceOrEnumType(); }
| LOOKAHEAD({isKeyword("enum")}) EnumDeclaration(mods) { checkForLocalInterfaceOrEnumType(); }
| AnnotationTypeDeclaration(mods) { checkForLocalInterfaceOrEnumType(); }
| LOOKAHEAD(<INTERFACE>) ClassOrInterfaceDeclaration(mods)
| LOOKAHEAD({isKeyword("record")}) RecordDeclaration(mods)
| LOOKAHEAD({isKeyword("enum")}) EnumDeclaration(mods)
| AnnotationTypeDeclaration(mods)
)
}

View File

@ -107,10 +107,6 @@ public interface ASTAnyTypeDeclaration extends TypeNode, JavaQualifiableNode, Ac
return getFirstChildOfType(ASTRecordComponentList.class);
}
/**
* Returns true if this type is declared locally, e.g. in the context of a method block.
*/
boolean isLocal();
/**
* The kind of type this node declares.

View File

@ -12,6 +12,7 @@ import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.internal.util.IteratorUtil;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.NodeStream;
import net.sourceforge.pmd.util.CollectionUtil;
/**

View File

@ -29,18 +29,13 @@ public final class ASTPermitsList extends AbstractJavaNode implements Iterable<A
super(id);
}
ASTPermitsList(JavaParser p, int id) {
super(p, id);
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
protected <P, R> R acceptVisitor(JavaVisitor<? super P, ? extends R> visitor, P data) {
return visitor.visit(this, data);
}
@Override
public Iterator<ASTClassOrInterfaceType> iterator() {
return new NodeChildrenIterator<>(this, ASTClassOrInterfaceType.class);
return children(ASTClassOrInterfaceType.class).iterator();
}
}

View File

@ -50,6 +50,11 @@ public abstract class AbstractJavaNode extends AbstractJjtreeNode<AbstractJavaNo
super.addChild(child, index);
}
@Override // override to make it accessible to tests that build nodes (which have been removed on java-grammar)
protected void insertChild(AbstractJavaNode child, int index) {
super.insertChild(child, index);
}
@Override // override to make it accessible to parser
protected void setImage(String image) {
super.setImage(image);

View File

@ -15,6 +15,7 @@ import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration.TypeKind;
import net.sourceforge.pmd.lang.java.ast.ASTAssertStatement;
import net.sourceforge.pmd.lang.java.ast.ASTBreakStatement;
import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
@ -43,6 +44,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTTypeParameters;
import net.sourceforge.pmd.lang.java.ast.ASTTypeTestPattern;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.java.ast.ASTYieldStatement;
import net.sourceforge.pmd.lang.java.ast.AccessNode;
import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.ast.JavaVisitorBase;
@ -114,13 +116,16 @@ public class LanguageLevelChecker<T> {
SWITCH_EXPRESSIONS(12, 13, true),
SWITCH_RULES(12, 13, true),
TEXT_BLOCK_LITERALS(13, 14, false),
TEXT_BLOCK_LITERALS(13, 14, true),
YIELD_STATEMENTS(13, 13, true),
/** \s */
SPACE_STRING_ESCAPES(14, 14, false),
RECORD_DECLARATIONS(14, 14, false),
TYPE_TEST_PATTERNS_IN_INSTANCEOF(14, 14, false);
SPACE_STRING_ESCAPES(14, 14, true),
RECORD_DECLARATIONS(14, 15, false),
TYPE_TEST_PATTERNS_IN_INSTANCEOF(14, 15, false),
SEALED_CLASSES(15, 15, false),
; // SUPPRESS CHECKSTYLE enum trailing semi is awesome
private final int minPreviewVersion;
@ -515,6 +520,12 @@ public class LanguageLevelChecker<T> {
@Override
public Void visit(ASTAnyTypeDeclaration node, T data) {
if ((node.getModifiers() & (AccessNode.SEALED | AccessNode.NON_SEALED)) != 0) {
check(node, PreviewFeature.SEALED_CLASSES, data);
} else if (node.isLocal() && node.getTypeKind() != TypeKind.CLASS) {
check(node, PreviewFeature.SEALED_CLASSES, data);
}
String simpleName = node.getSimpleName();
if ("var".equals(simpleName)) {
check(node, ReservedIdentifiers.VAR_AS_A_TYPE_NAME, data);

View File

@ -13,12 +13,12 @@ import java.io.IOException
class ASTPatternTest : ParserTestSpec({
parserTest("Test patterns only available on JDK 14+15 (preview)", javaVersions = JavaVersion.values().asList().minus(J14__PREVIEW).minus(J15__PREVIEW)) {
parserTest("Test patterns only available on JDK 14+15 (preview)", javaVersions = JavaVersion.except(J14__PREVIEW, J15__PREVIEW)) {
inContext(ExpressionParsingCtx) {
"obj instanceof Class c" should throwParseException {
it.message.shouldContain("Pattern Matching for instanceof is only supported with Java 14 Preview and Java 15 Preview")
it.message.shouldContain("Type test patterns in instanceof is a preview feature of JDK")
}
}
}

View File

@ -4,8 +4,7 @@
package net.sourceforge.pmd.lang.java.ast
import io.kotest.matchers.shouldBe
import net.sourceforge.pmd.lang.ast.test.matchNode
import net.sourceforge.pmd.lang.ast.test.shouldBe
class Java15KotlinTest: ParserTestSpec( {
@ -21,16 +20,16 @@ class Java15KotlinTest: ParserTestSpec( {
child<ASTPrimaryExpression> {
child<ASTPrimaryPrefix> {
child<ASTLiteral> {
it.isTextBlock shouldBe true
it.escapedStringLiteral shouldBe
it::isTextBlock shouldBe true
it::getEscapedStringLiteral shouldBe
"\"\"\"\n" +
" <html> \n" +
" <body>\n" +
" <p>Hello, world</p> \n" +
" </body> \n" +
" </html> \n" +
" \"\"\""
it.textBlockContent shouldBe
" <html> \n" +
" <body>\n" +
" <p>Hello, world</p> \n" +
" </body> \n" +
" </html> \n" +
" \"\"\""
it::getTextBlockContent shouldBe
"<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +

View File

@ -48,6 +48,11 @@ enum class JavaVersion : Comparable<JavaVersion> {
companion object {
val Latest = values().last()
val Earliest = values().first()
fun except(v1: JavaVersion, vararg versions: JavaVersion) =
values().toList() - v1 - versions
}
}