1
2
3
4
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
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
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
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 }