Make annotation an interface

This commit is contained in:
Clément Fournier
2019-03-21 15:07:55 +01:00
committed by Andreas Dangel
parent ec5e1e43f8
commit 839698dc21
9 changed files with 56 additions and 126 deletions

View File

@ -3007,9 +3007,10 @@ void RSIGNEDSHIFT(): // TODO 7.0.0 make #void
/* Annotation syntax follows. */
void Annotation():
void Annotation() #void:
{}
{
(
LOOKAHEAD( "@" Name() "(" ( <IDENTIFIER> "=" | ")" ))
NormalAnnotation()
|
@ -3017,24 +3018,32 @@ void Annotation():
SingleMemberAnnotation()
|
MarkerAnnotation()
)
{checkForBadAnnotationUsage();}
}
void AnnotationBase(Node n) #void:
{String name = null;}
{
"@" name=VoidName() {n.setImage(name);}
}
void NormalAnnotation():
{}
{
"@" Name() "(" [ MemberValuePairs() ] ")" {checkForBadAnnotationUsage();}
AnnotationBase(jjtThis) "(" [ MemberValuePairs() ] ")"
}
void MarkerAnnotation():
{}
{
"@" Name() {checkForBadAnnotationUsage();}
AnnotationBase(jjtThis)
}
void SingleMemberAnnotation():
{}
{
"@" Name() "(" MemberValue() ")" {checkForBadAnnotationUsage();}
AnnotationBase(jjtThis) "(" MemberValue() ")"
}
void MemberValuePairs():
@ -3049,13 +3058,14 @@ void MemberValuePair():
t=<IDENTIFIER> { jjtThis.setImage(t.image); } "=" MemberValue()
}
void MemberValue():
void MemberValue() #void:
{}
{
Annotation()
|
MemberValueArrayInitializer()
|
// Constant expression
ConditionalExpression()
}

View File

@ -5,15 +5,13 @@
package net.sourceforge.pmd.lang.java.ast;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
/**
* Represents an annotation. This node has three possible children,
* that correspond to specific syntactic variants.
* Represents an annotation. This node has three specific syntactic variants,
* represented by nodes that implement this interface.
*
* <pre>
*
@ -22,30 +20,16 @@ import net.sourceforge.pmd.Rule;
* | {@linkplain ASTMarkerAnnotation MarkerAnnotation}
*
* </pre>
*
*/
public class ASTAnnotation extends AbstractJavaTypeNode {
private static final List<String> UNUSED_RULES
= Arrays.asList("UnusedPrivateField", "UnusedLocalVariable", "UnusedPrivateMethod", "UnusedFormalParameter");
private static final List<String> SERIAL_RULES = Arrays.asList("BeanMembersShouldSerialize", "MissingSerialVersionUID");
public ASTAnnotation(int id) {
super(id);
}
public ASTAnnotation(JavaParser p, int id) {
super(p, id);
}
public interface ASTAnnotation extends TypeNode, ASTMemberValue {
/**
* Returns the name of the annotation as it is used,
* eg {@code java.lang.Override} or {@code Override}.
*/
public String getAnnotationName() {
return jjtGetChild(0).jjtGetChild(0).getImage();
default String getAnnotationName() {
return getImage();
}
// @formatter:off
@ -72,41 +56,41 @@ public class ASTAnnotation extends AbstractJavaTypeNode {
* @return True if this annotation suppresses the given rule
*/
// @formatter:on
public boolean suppresses(Rule rule) {
default boolean suppresses(Rule rule) {
if (jjtGetChild(0) instanceof ASTMarkerAnnotation) {
return false;
}
// if (SuppressWarnings.class.equals(getType())) { // typeres is not always on
if (isSuppressWarnings()) {
if (TypeHelper.isA(this, "java.lang.SuppressWarnings")) {
for (ASTLiteral element : findDescendantsOfType(ASTLiteral.class)) {
if (element.hasImageEqualTo("\"PMD\"") || element.hasImageEqualTo("\"PMD." + rule.getName() + "\"")
// Check for standard annotations values
|| element.hasImageEqualTo("\"all\"")
|| element.hasImageEqualTo("\"serial\"") && SERIAL_RULES.contains(rule.getName())
|| element.hasImageEqualTo("\"unused\"") && UNUSED_RULES.contains(rule.getName())) {
|| element.hasImageEqualTo("\"all\"")) {
return true;
} else if (element.hasImageEqualTo("\"serial\"")) {
switch (rule.getName()) {
case "BeanMembersShouldSerialize":
case "MissingSerialVersionUID":
return true;
default:
return false;
}
} else if (element.hasImageEqualTo("\"unused\"")) {
switch (rule.getName()) {
case "UnusedPrivateField":
case "UnusedLocalVariable":
case "UnusedPrivateMethod":
case "UnusedFormalParameter":
return true;
default:
return false;
}
}
}
}
return false;
}
private boolean isSuppressWarnings() {
return "SuppressWarnings".equals(getAnnotationName()) || "java.lang.SuppressWarnings".equals(getAnnotationName());
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
@Override
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
}

View File

@ -35,7 +35,7 @@ package net.sourceforge.pmd.lang.java.ast;
*
* </pre>
*/
public interface ASTExpression extends JavaNode, TypeNode {
public interface ASTExpression extends JavaNode, TypeNode, ASTMemberValue {
/**
* Always returns true. This is to allow XPath queries

View File

@ -10,14 +10,14 @@ package net.sourceforge.pmd.lang.java.ast;
*
* <pre>
*
* MarkerAnnotation ::= "@" {@linkplain ASTAnnotation Name}
* MarkerAnnotation ::= "@" Name
*
* </pre>
*
* @see ASTSingleMemberAnnotation
* @see ASTNormalAnnotation
*/
public class ASTMarkerAnnotation extends AbstractJavaTypeNode {
public class ASTMarkerAnnotation extends AbstractJavaTypeNode implements ASTAnnotation {
public ASTMarkerAnnotation(int id) {
super(id);
@ -41,19 +41,4 @@ public class ASTMarkerAnnotation extends AbstractJavaTypeNode {
}
/**
* Returns the name of the annotation as it is used,
* eg {@code java.lang.Override} or {@code Override}.
*/
public String getAnnotationName() {
return jjtGetChild(0).getImage();
}
@Override
public ASTAnnotation jjtGetParent() {
return (ASTAnnotation) super.jjtGetParent();
}
}

View File

@ -12,31 +12,12 @@ package net.sourceforge.pmd.lang.java.ast;
*
* <pre>
*
* MemberValue ::= {@linkplain ASTAnnotation Annotation}
* | {@linkplain ASTMemberValueArrayInitializer MemberValueArrayInitializer}
* | &lt; any expression, excluding assignment expressions and lambda expressions &gt;
* MemberValue ::= {@link ASTAnnotation Annotation}
* | {@link ASTMemberValueArrayInitializer MemberValueArrayInitializer}
* | {@link ASTExpression &lt; any expression, excluding assignment expressions and lambda expressions &gt;}
*
* </pre>
*/
public class ASTMemberValue extends AbstractJavaNode {
public ASTMemberValue(int id) {
super(id);
}
public interface ASTMemberValue extends JavaNode {
public ASTMemberValue(JavaParser p, int id) {
super(p, id);
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
@Override
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
visitor.visit(this, data);
}
}

View File

@ -18,9 +18,8 @@ import java.util.Iterator;
*
* </pre>
*
*
*/
public class ASTMemberValueArrayInitializer extends AbstractJavaNode implements Iterable<ASTMemberValue> {
public class ASTMemberValueArrayInitializer extends AbstractJavaNode implements Iterable<ASTMemberValue>, ASTMemberValue {
public ASTMemberValueArrayInitializer(int id) {
super(id);
}

View File

@ -11,14 +11,14 @@ package net.sourceforge.pmd.lang.java.ast;
*
* <pre>
*
* NormalAnnotation ::= "@" {@linkplain ASTName Name} "(" {@linkplain ASTMemberValuePairs MemberValuePairs}? ")"
* NormalAnnotation ::= "@" Name "(" {@linkplain ASTMemberValuePairs MemberValuePairs}? ")"
*
* </pre>
*
* @see ASTSingleMemberAnnotation
* @see ASTMarkerAnnotation
*/
public class ASTNormalAnnotation extends AbstractJavaTypeNode {
public class ASTNormalAnnotation extends AbstractJavaTypeNode implements ASTAnnotation {
public ASTNormalAnnotation(int id) {
super(id);
}
@ -40,18 +40,4 @@ public class ASTNormalAnnotation extends AbstractJavaTypeNode {
visitor.visit(this, data);
}
/**
* Returns the name of the annotation as it is used,
* eg {@code java.lang.Override} or {@code Override}.
*/
public String getAnnotationName() {
return jjtGetChild(0).getImage();
}
@Override
public ASTAnnotation jjtGetParent() {
return (ASTAnnotation) super.jjtGetParent();
}
}

View File

@ -10,14 +10,14 @@ package net.sourceforge.pmd.lang.java.ast;
*
* <pre>
*
* SingleMemberAnnotation ::= "@" {@linkplain ASTName Name} "(" {@linkplain ASTMemberValue MemberValue} ")"
* SingleMemberAnnotation ::= "@" Name "(" {@linkplain ASTMemberValue MemberValue} ")"
*
* </pre>
*
* @see ASTMarkerAnnotation
* @see ASTNormalAnnotation
*/
public class ASTSingleMemberAnnotation extends AbstractJavaTypeNode {
public class ASTSingleMemberAnnotation extends AbstractJavaTypeNode implements ASTAnnotation {
public ASTSingleMemberAnnotation(int id) {
super(id);
}
@ -43,21 +43,7 @@ public class ASTSingleMemberAnnotation extends AbstractJavaTypeNode {
* set by this annotation.
*/
public ASTMemberValue getMemberValue() {
return (ASTMemberValue) jjtGetChild(1);
return (ASTMemberValue) jjtGetChild(0);
}
/**
* Returns the name of the annotation as it is used,
* eg {@code java.lang.Override} or {@code Override}.
*/
public String getAnnotationName() {
return jjtGetChild(0).getImage();
}
@Override
public ASTAnnotation jjtGetParent() {
return (ASTAnnotation) super.jjtGetParent();
}
}

View File

@ -28,8 +28,7 @@ public interface Annotatable extends JavaNode {
default ASTAnnotation getAnnotation(String annotQualifiedName) {
List<ASTAnnotation> annotations = getDeclaredAnnotations();
for (ASTAnnotation annotation : annotations) {
ASTName name = annotation.getFirstDescendantOfType(ASTName.class);
if (name != null && TypeHelper.isA(name, annotQualifiedName)) {
if (TypeHelper.isA(annotation, annotQualifiedName)) {
return annotation;
}
}