1
2
3
4 package net.sourceforge.pmd.lang.java.rule.design;
5
6 import java.util.List;
7 import java.util.Map;
8
9 import net.sourceforge.pmd.lang.ast.Node;
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.AccessNode;
13 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
14 import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence;
15 import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
16 import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
17
18
19
20
21
22
23 public class AssignmentToNonFinalStaticRule extends AbstractJavaRule {
24
25 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
26 Map<VariableNameDeclaration, List<NameOccurrence>> vars = node.getScope().getDeclarations(VariableNameDeclaration.class);
27 for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry: vars.entrySet()) {
28 VariableNameDeclaration decl = entry.getKey();
29 AccessNode accessNodeParent = (AccessNode)decl.getAccessNodeParent();
30 if (!accessNodeParent.isStatic() || accessNodeParent.isFinal()) {
31 continue;
32 }
33
34 if (initializedInConstructor(entry.getValue())) {
35 addViolation(data, decl.getNode(), decl.getImage());
36 }
37 }
38 return super.visit(node, data);
39 }
40
41 private boolean initializedInConstructor(List<NameOccurrence> usages) {
42 boolean initInConstructor = false;
43
44 for (NameOccurrence occ: usages) {
45 if (((JavaNameOccurrence)occ).isOnLeftHandSide()) {
46 Node node = occ.getLocation();
47 Node constructor = node.getFirstParentOfType(ASTConstructorDeclaration.class);
48 if (constructor != null) {
49 initInConstructor = true;
50 }
51 }
52 }
53
54 return initInConstructor;
55 }
56
57 }