01 /**
02 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03 */
04 package net.sourceforge.pmd.lang.java.rule.optimizations;
05
06 import net.sourceforge.pmd.lang.ast.Node;
07 import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
08 import net.sourceforge.pmd.lang.java.ast.ASTDoStatement;
09 import net.sourceforge.pmd.lang.java.ast.ASTForInit;
10 import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
11 import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
12 import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement;
13 import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
14
15 public class AvoidInstantiatingObjectsInLoopsRule extends AbstractOptimizationRule {
16
17 @Override
18 public Object visit(ASTAllocationExpression node, Object data) {
19 if (insideLoop(node) && fourthParentNotThrow(node) && fourthParentNotReturn(node)) {
20 addViolation(data, node);
21 }
22 return data;
23 }
24
25 private boolean fourthParentNotThrow(ASTAllocationExpression node) {
26 return !(node.jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTThrowStatement);
27 }
28
29 private boolean fourthParentNotReturn(ASTAllocationExpression node) {
30 return !(node.jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTReturnStatement);
31 }
32
33 private boolean insideLoop(ASTAllocationExpression node) {
34 Node n = node.jjtGetParent();
35 while (n != null) {
36 if (n instanceof ASTDoStatement || n instanceof ASTWhileStatement || n instanceof ASTForStatement) {
37 return true;
38 } else if (n instanceof ASTForInit) {
39 /*
40 * init part is not technically inside the loop.
41 * Skip parent ASTForStatement but continue higher
42 * up to detect nested loops
43 */
44 n = n.jjtGetParent();
45 }
46 n = n.jjtGetParent();
47 }
48 return false;
49 }
50 }
|