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 }