1
2
3
4 package net.sourceforge.pmd.lang.java.rule.design;
5
6 import net.sourceforge.pmd.lang.ast.Node;
7 import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
8 import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
9 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
10 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
11 import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
12 import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
13 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
14 import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
15 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
16 import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public class FieldDeclarationsShouldBeAtStartOfClassRule extends AbstractJavaRule {
36
37 private BooleanProperty ignoreEnumDeclarations = new BooleanProperty("ignoreEnumDeclarations", "Ignore Enum Declarations that precede fields.", true, 1.0f);
38 private BooleanProperty ignoreAnonymousClassDeclarations = new BooleanProperty("ignoreAnonymousClassDeclarations", "Ignore Field Declarations, that are initialized with anonymous class declarations", true, 2.0f);
39
40
41
42
43 public FieldDeclarationsShouldBeAtStartOfClassRule() {
44 definePropertyDescriptor(ignoreEnumDeclarations);
45 definePropertyDescriptor(ignoreAnonymousClassDeclarations);
46 }
47
48 @Override
49 public Object visit(ASTFieldDeclaration node, Object data) {
50 Node parent = node.jjtGetParent().jjtGetParent();
51 for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
52 Node child = parent.jjtGetChild(i);
53 if (child.jjtGetNumChildren() > 0) {
54 child = skipAnnotations(child);
55 }
56 if (child.equals(node)) {
57 break;
58 }
59 if (child instanceof ASTFieldDeclaration) {
60 continue;
61 }
62 if (node.hasDescendantOfType(ASTClassOrInterfaceBodyDeclaration.class) && getProperty(ignoreAnonymousClassDeclarations).booleanValue()) {
63 continue;
64 }
65 if (child instanceof ASTClassOrInterfaceDeclaration
66 || child instanceof ASTMethodDeclaration
67 || child instanceof ASTConstructorDeclaration
68 || child instanceof ASTAnnotationTypeDeclaration) {
69 addViolation(data, node);
70 break;
71 }
72 if (child instanceof ASTEnumDeclaration && !getProperty(ignoreEnumDeclarations).booleanValue()) {
73 addViolation(data, node);
74 break;
75 }
76 }
77 return data;
78 }
79
80
81
82
83
84
85
86 private Node skipAnnotations(Node child) {
87 Node nextChild = child.jjtGetChild(0);
88 for (int j = 0; j < child.jjtGetNumChildren(); j++) {
89 if (!(child.jjtGetChild(j) instanceof ASTAnnotation)) {
90 nextChild = child.jjtGetChild(j);
91 break;
92 }
93 }
94 return nextChild;
95 }
96 }