View Javadoc

1   /*
2    * AssignmentToNonFinalStaticRule.java
3    *
4    * Created on October 24, 2004, 8:56 AM
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()) { // specifically omitting prefix and postfix operators as there are legitimate usages of these with static fields, e.g. typesafe enum pattern.
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  }