View Javadoc

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