/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.unnecessary;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
public class UnnecessaryModifierRule extends AbstractJavaRule {
@Override
public Object visit(ASTEnumDeclaration node, Object data) {
if (node.isStatic()) {
// a static enum
addViolation(data, node, getMessage());
}
return super.visit(node, data);
}
public Object visit(ASTAnnotationTypeDeclaration node, Object data) {
if (node.isAbstract()) {
// an abstract annotation
addViolation(data, node, getMessage());
}
if (!node.isNested()) {
return super.visit(node, data);
}
Node parent = node.jjtGetParent().jjtGetParent().jjtGetParent();
boolean isParentInterfaceOrAnnotation = parent instanceof ASTAnnotationTypeDeclaration
|| parent instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) parent).isInterface();
// a public annotation within an interface or annotation
if (node.isPublic() && isParentInterfaceOrAnnotation) {
addViolation(data, node, getMessage());
}
if (node.isStatic()) {
// a static annotation
addViolation(data, node, getMessage());
}
return super.visit(node, data);
}
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
if (node.isInterface() && node.isAbstract()) {
// an abstract interface
addViolation(data, node, getMessage());
}
if (!node.isNested()) {
return super.visit(node, data);
}
Node parent = node.jjtGetParent().jjtGetParent().jjtGetParent();
boolean isParentInterfaceOrAnnotation = parent instanceof ASTAnnotationTypeDeclaration
|| parent instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) parent).isInterface();
// a public interface within an interface or annotation
if (node.isInterface() && node.isPublic() && isParentInterfaceOrAnnotation) {
addViolation(data, node, getMessage());
}
if (node.isInterface() && node.isStatic()) {
// a static interface
addViolation(data, node, getMessage());
}
// a public and/or static class within an interface or annotation
if (!node.isInterface() && (node.isPublic() || node.isStatic()) && isParentInterfaceOrAnnotation) {
addViolation(data, node, getMessage());
}
return super.visit(node, data);
}
public Object visit(ASTMethodDeclaration node, Object data) {
if (node.isSyntacticallyPublic() || node.isSyntacticallyAbstract()) {
check(node, data);
}
return super.visit(node, data);
}
public Object visit(ASTFieldDeclaration node, Object data) {
if (node.isSyntacticallyPublic() || node.isSyntacticallyStatic() || node.isSyntacticallyFinal()) {
check(node, data);
}
return super.visit(node, data);
}
public Object visit(ASTAnnotationMethodDeclaration node, Object data) {
if (node.isPublic() || node.isAbstract()) {
check(node, data);
}
return super.visit(node, data);
}
private void check(Node fieldOrMethod, Object data) {
// third ancestor could be an AllocationExpression
// if this is a method in an anonymous inner class
Node parent = fieldOrMethod.jjtGetParent().jjtGetParent().jjtGetParent();
if (parent instanceof ASTAnnotationTypeDeclaration
|| parent instanceof ASTClassOrInterfaceDeclaration
&& ((ASTClassOrInterfaceDeclaration) parent).isInterface()) {
addViolation(data, fieldOrMethod);
}
}
}