View Javadoc

    1   /*
    2    * Created on Jan 11, 2005
    3    *
    4    * $Id: AbstractOptimizationRule.java,v 1.7 2006/02/10 14:26:31 tomcopeland Exp $
    5    */
    6   package net.sourceforge.pmd.rules.optimization;
    7
    8   import net.sourceforge.pmd.AbstractRule;
    9   import net.sourceforge.pmd.Rule;
    10  import net.sourceforge.pmd.ast.ASTAssignmentOperator;
    11  import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
    12  import net.sourceforge.pmd.ast.ASTMethodDeclaration;
    13  import net.sourceforge.pmd.ast.ASTName;
    14  import net.sourceforge.pmd.ast.ASTPostfixExpression;
    15  import net.sourceforge.pmd.ast.ASTPreDecrementExpression;
    16  import net.sourceforge.pmd.ast.ASTPreIncrementExpression;
    17  import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
    18  import net.sourceforge.pmd.ast.SimpleNode;
    19
    20  import java.util.Iterator;
    21  import java.util.List;
    22
    23  /***
    24   * Base class with utility methods for optimization rules
    25   *
    26   * @author mgriffa
    27   */
    28  public class AbstractOptimizationRule extends AbstractRule implements Rule {
    29
    30      protected final boolean isVarWritterInMethod(String varName, ASTMethodDeclaration md) {
    31          List assignments = md.findChildrenOfType(ASTAssignmentOperator.class);
    32          return (variableAssigned(varName, assignments) || numericWithPrePost(md, varName));
    33      }
    34
    35      // TODO - symbol table?
    36      protected final String getVarName(ASTLocalVariableDeclaration node) {
    37          List l = node.findChildrenOfType(ASTVariableDeclaratorId.class);
    38          if (l != null && l.size() > 0) {
    39              ASTVariableDeclaratorId vd = (ASTVariableDeclaratorId) l.get(0);
    40              return vd.getImage();
    41          }
    42          return null;
    43      }
    44
    45      /***
    46       * Check constructions like
    47       * int i;
    48       * ++i;
    49       * --i;
    50       * i++;
    51       * i*=1;
    52       * i+=1;
    53       */
    54      private final boolean numericWithPrePost(ASTMethodDeclaration md, String varName) {
    55          // ++i
    56          List preinc = md.findChildrenOfType(ASTPreIncrementExpression.class);
    57          if (preinc != null && !preinc.isEmpty()) {
    58              for (Iterator it = preinc.iterator(); it.hasNext();) {
    59                  ASTPreIncrementExpression ie = (ASTPreIncrementExpression) it.next();
    60                  if (((ASTName) ie.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0)).getImage().equals(varName)) {
    61                      return true;
    62                  }
    63              }
    64          }
    65
    66          // --i
    67          List predec = md.findChildrenOfType(ASTPreDecrementExpression.class);
    68          if (predec != null && !predec.isEmpty()) {
    69              for (Iterator it = predec.iterator(); it.hasNext();) {
    70                  ASTPreDecrementExpression de = (ASTPreDecrementExpression) it.next();
    71                  if (((ASTName) de.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0)).getImage().equals(varName)) {
    72                      return true;
    73                  }
    74              }
    75          }
    76
    77          List pf = md.findChildrenOfType(ASTPostfixExpression.class);
    78          if (pf != null && !pf.isEmpty()) {
    79              for (Iterator it = pf.iterator(); it.hasNext();) {
    80                  ASTPostfixExpression pe = (ASTPostfixExpression) it.next();
    81
    82                  if ((pe.getImage().equals("++") || pe.getImage().equals("--"))) {
    83                      SimpleNode first = (SimpleNode) pe.jjtGetChild(0);
    84                      SimpleNode second = (SimpleNode) first.jjtGetChild(0);
    85                      if (second.jjtGetNumChildren() == 0) {
    86                          continue;
    87                      }
    88                      ASTName name = (ASTName) second.jjtGetChild(0);
    89                      if (name.getImage().equals(varName)) {
    90                          return true;
    91                      }
    92                  }
    93              }
    94          }
    95          return false;
    96      }
    97
    98
    99      private final boolean variableAssigned(final String varName, final List assignments) {
    100         if (assignments == null || assignments.isEmpty()) {
    101             return false;
    102         }
    103         for (Iterator it = assignments.iterator(); it.hasNext();) {
    104             final ASTAssignmentOperator a = (ASTAssignmentOperator) it.next();
    105             // if node is assigned return true
    106             SimpleNode firstChild = (SimpleNode) a.jjtGetParent().jjtGetChild(0);
    107             SimpleNode otherChild = (SimpleNode) firstChild.jjtGetChild(0);
    108             if (otherChild.jjtGetNumChildren() == 0 || !(otherChild.jjtGetChild(0) instanceof ASTName)) {
    109                 continue;
    110             }
    111             ASTName n = (ASTName) otherChild.jjtGetChild(0);
    112             if (n.getImage().equals(varName)) {
    113                 return true;
    114             }
    115         }
    116
    117         return false;
    118     }
    119
    120 }