View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.lang.java.rule.unusedcode;
    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.ASTMethodDeclaration;
    13  import net.sourceforge.pmd.lang.java.ast.JavaNode;
    14  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
    15  import net.sourceforge.pmd.lang.java.symboltable.NameOccurrence;
    16  import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
    17  import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
    18
    19  public class UnusedFormalParameterRule extends AbstractJavaRule {
    20
    21      private static final BooleanProperty CHECKALL_DESCRIPTOR = new BooleanProperty("checkAll", "Check all methods, including non-private ones", false, 1.0f);
    22
    23      public UnusedFormalParameterRule() {
    24  	definePropertyDescriptor(CHECKALL_DESCRIPTOR);
    25      }
    26
    27      public Object visit(ASTConstructorDeclaration node, Object data) {
    28          check(node, data);
    29          return data;
    30      }
    31
    32      public Object visit(ASTMethodDeclaration node, Object data) {
    33          if (!node.isPrivate() && !getProperty(CHECKALL_DESCRIPTOR)) {
    34              return data;
    35          }
    36          if (!node.isNative() && !node.isAbstract()) {
    37              check(node, data);
    38          }
    39          return data;
    40      }
    41
    42      private void check(Node node, Object data) {
    43          Node parent = node.jjtGetParent().jjtGetParent().jjtGetParent();
    44          if (parent instanceof ASTClassOrInterfaceDeclaration && !((ASTClassOrInterfaceDeclaration) parent).isInterface()) {
    45              Map<VariableNameDeclaration, List<NameOccurrence>> vars = ((JavaNode)node).getScope().getVariableDeclarations();
    46              for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry: vars.entrySet()) {
    47                  VariableNameDeclaration nameDecl = entry.getKey();
    48                  if (actuallyUsed(nameDecl, entry.getValue())) {
    49                      continue;
    50                  }
    51                  addViolation(data, nameDecl.getNode(), new Object[]{node instanceof ASTMethodDeclaration ? "method" : "constructor", nameDecl.getImage()});
    52              }
    53          }
    54      }
    55
    56      private boolean actuallyUsed(VariableNameDeclaration nameDecl, List<NameOccurrence> usages) {
    57          for (NameOccurrence occ: usages) {
    58              if (occ.isOnLeftHandSide()) {
    59                  if (nameDecl.isArray() && occ.getLocation().jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) {
    60                      // array element access
    61                      return true;
    62                  }
    63                  continue;
    64              } else {
    65                  return true;
    66              }
    67          }
    68          return false;
    69      }
    70
    71
    72  }