View Javadoc

    1   /*
    2    * AssignmentToNonFinalStaticRule.java
    3    *
    4    * Created on October 24, 2004, 8:56 AM
    5    */
    6
    7   package net.sourceforge.pmd.lang.java.rule.design;
    8
    9   import java.util.List;
    10  import java.util.Map;
    11
    12  import net.sourceforge.pmd.lang.ast.Node;
    13  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
    14  import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
    15  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
    16  import net.sourceforge.pmd.lang.java.symboltable.NameOccurrence;
    17  import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
    18
    19
    20  /**
    21   * @author Eric Olander
    22   */
    23  public class AssignmentToNonFinalStaticRule extends AbstractJavaRule {
    24
    25      public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
    26          Map<VariableNameDeclaration, List<NameOccurrence>> vars = node.getScope().getVariableDeclarations();
    27          for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry: vars.entrySet()) {
    28              VariableNameDeclaration decl = entry.getKey();
    29              if (!decl.getAccessNodeParent().isStatic() || decl.getAccessNodeParent().isFinal()) {
    30                  continue;
    31              }
    32
    33              if (initializedInConstructor(entry.getValue())) {
    34                  addViolation(data, decl.getNode(), decl.getImage());
    35              }
    36          }
    37          return super.visit(node, data);
    38      }
    39
    40      private boolean initializedInConstructor(List<NameOccurrence> usages) {
    41          boolean initInConstructor = false;
    42
    43          for (NameOccurrence occ: usages) {
    44              if (occ.isOnLeftHandSide()) { // specifically omitting prefix and postfix operators as there are legitimate usages of these with static fields, e.g. typesafe enum pattern.
    45          	Node node = occ.getLocation();
    46          	Node constructor = node.getFirstParentOfType(ASTConstructorDeclaration.class);
    47                  if (constructor != null) {
    48                      initInConstructor = true;
    49                  }
    50              }
    51          }
    52
    53          return initInConstructor;
    54      }
    55
    56  }