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 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
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
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
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
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 }