View Javadoc

1   /*
2    * Created on Jan 11, 2005 
3    *
4    * $Id: AbstractOptimizationRule.java,v 1.4 2005/02/01 21:22:01 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      /***
31       * Check constructions like
32       * int i; 
33       * ++i;
34       * --i;
35       * i++;
36       * i*=1;
37       * i+=1;
38       */
39      private final boolean numericWithPrePost(ASTMethodDeclaration md, String varName) {
40          // ++i
41          List preinc = md.findChildrenOfType(ASTPreIncrementExpression.class);
42          if (preinc!=null && !preinc.isEmpty()) {
43              for (Iterator it = preinc.iterator() ; it.hasNext() ; ) {
44                  ASTPreIncrementExpression ie = (ASTPreIncrementExpression) it.next();
45                  if (((ASTName)ie.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0)).getImage().equals(varName)) {
46                      return true;
47                  }
48              }
49          }
50          
51          // --i
52          List predec = md.findChildrenOfType(ASTPreDecrementExpression.class);
53          if (predec!=null && !predec.isEmpty()) {
54              for (Iterator it = predec.iterator() ; it.hasNext() ; ) {
55                  ASTPreDecrementExpression de = (ASTPreDecrementExpression) it.next();
56                  if (((ASTName)de.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0)).getImage().equals(varName)) {
57                      return true;
58                  }
59              }
60          }
61          
62          List pf = md.findChildrenOfType(ASTPostfixExpression.class);
63          if (pf!=null && !pf.isEmpty()) {
64              for (Iterator it = pf.iterator() ; it.hasNext() ; ) {
65                  ASTPostfixExpression pe = (ASTPostfixExpression) it.next();
66  
67                  if (( pe.getImage().equals("++") || pe.getImage().equals("--"))) {
68                      SimpleNode first = (SimpleNode)pe.jjtGetChild(0);
69                      SimpleNode second = (SimpleNode)first.jjtGetChild(0);
70                      if (second.jjtGetNumChildren() == 0) {
71                          continue;
72                      }
73                      ASTName name = (ASTName)second.jjtGetChild(0);
74                      if (name.getImage().equals(varName)) {
75                          return true;
76                      }
77                  }
78              }
79          }
80          return false;
81      }
82  
83      protected final String getVarName(ASTLocalVariableDeclaration node) {
84          List l = node.findChildrenOfType(ASTVariableDeclaratorId.class);
85          if (l != null && l.size()>0) {
86              ASTVariableDeclaratorId vd = (ASTVariableDeclaratorId) l.get(0);
87              return vd.getImage();
88          }
89          return null;
90      }
91  
92  
93  
94      private final boolean variableAssigned(final String varName, final List assignements) {
95          if (assignements==null || assignements.isEmpty()) {
96              return false;
97          }
98          for (Iterator it = assignements.iterator() ; it.hasNext() ; ) {
99              final ASTAssignmentOperator a = (ASTAssignmentOperator) it.next();
100             // if node is assigned return true
101             SimpleNode firstChild = (SimpleNode)a.jjtGetParent().jjtGetChild(0);
102             SimpleNode otherChild =  (SimpleNode)firstChild.jjtGetChild(0);
103             if (otherChild.jjtGetNumChildren() == 0 || !(otherChild.jjtGetChild(0) instanceof ASTName)) {
104                 continue;
105             }
106             ASTName n = (ASTName) otherChild.jjtGetChild(0);
107             if (n.getImage().equals(varName)) {
108                 return true;
109             }
110         }
111         
112         return false;
113     }
114     
115     protected final boolean isVarWritterInMethod(String varName, ASTMethodDeclaration md) {
116         List assignements = md.findChildrenOfType(ASTAssignmentOperator.class);
117 
118         return (variableAssigned(varName, assignements)
119                 || numericWithPrePost(md, varName));
120     }
121 }