forked from phoedos/pmd
Make annotation an interface
This commit is contained in:
Clément Fournier
committed by
Andreas Dangel
parent
ec5e1e43f8
commit
839698dc21
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -12,31 +12,12 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* MemberValue ::= {@linkplain ASTAnnotation Annotation}
|
||||
* | {@linkplain ASTMemberValueArrayInitializer MemberValueArrayInitializer}
|
||||
* | < any expression, excluding assignment expressions and lambda expressions >
|
||||
* MemberValue ::= {@link ASTAnnotation Annotation}
|
||||
* | {@link ASTMemberValueArrayInitializer MemberValueArrayInitializer}
|
||||
* | {@link ASTExpression < any expression, excluding assignment expressions and lambda expressions >}
|
||||
*
|
||||
* </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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user