1
2
3
4
5
6
7 package net.sourceforge.pmd.rules.design;
8
9 import net.sourceforge.pmd.AbstractRule;
10 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
11 import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
12 import net.sourceforge.pmd.ast.SimpleNode;
13 import net.sourceforge.pmd.symboltable.NameOccurrence;
14 import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
15
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19
20
21 /***
22 *
23 * @author Eric Olander
24 */
25 public class AssignmentToNonFinalStatic extends AbstractRule {
26
27 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
28 Map vars = node.getScope().getVariableDeclarations();
29 for (Iterator i = vars.keySet().iterator(); i.hasNext();) {
30 VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
31 if (!decl.getAccessNodeParent().isStatic() || decl.getAccessNodeParent().isFinal()) {
32 continue;
33 }
34
35 if (initializedInConstructor((List)vars.get(decl))) {
36 addViolation(data, decl.getNode(), decl.getImage());
37 }
38 }
39 return super.visit(node, data);
40 }
41
42 private boolean initializedInConstructor(List usages) {
43 boolean initInConstructor = false;
44
45 for (Iterator j = usages.iterator(); j.hasNext();) {
46 NameOccurrence occ = (NameOccurrence)j.next();
47 if (occ.isOnLeftHandSide()) {
48 SimpleNode node = occ.getLocation();
49 SimpleNode constructor = (SimpleNode)node.getFirstParentOfType(ASTConstructorDeclaration.class);
50 if (constructor != null) {
51 initInConstructor = true;
52 }
53 }
54 }
55
56 return initInConstructor;
57 }
58
59 }