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.RuleContext;
11 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
12 import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
13 import net.sourceforge.pmd.ast.SimpleNode;
14 import net.sourceforge.pmd.symboltable.NameOccurrence;
15 import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
16
17 import java.text.MessageFormat;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21
22
23 /***
24 *
25 * @author Eric Olander
26 */
27 public class AssignmentToNonFinalStatic extends AbstractRule {
28
29 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
30 Map vars = node.getScope().getVariableDeclarations();
31 for (Iterator i = vars.keySet().iterator(); i.hasNext();) {
32 VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
33 if (!decl.getAccessNodeParent().isStatic() || decl.getAccessNodeParent().isFinal()) {
34 continue;
35 }
36
37 if (initializedInConstructor((List)vars.get(decl))) {
38 ((RuleContext) data).getReport().addRuleViolation(createRuleViolation((RuleContext) data, decl, MessageFormat.format(getMessage(), new Object[]{decl.getImage()})));
39 }
40 }
41 return super.visit(node, data);
42 }
43
44 private boolean initializedInConstructor(List usages) {
45 boolean initInConstructor = false;
46
47 for (Iterator j = usages.iterator(); j.hasNext();) {
48 NameOccurrence occ = (NameOccurrence)j.next();
49 if (occ.isOnLeftHandSide()) {
50 SimpleNode node = occ.getLocation();
51 SimpleNode constructor = (SimpleNode)node.getFirstParentOfType(ASTConstructorDeclaration.class);
52 if (constructor != null) {
53 initInConstructor = true;
54 }
55 }
56 }
57
58 return initInConstructor;
59 }
60
61 }