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.ASTClassOrInterfaceDeclaration;
7   import net.sourceforge.pmd.ast.ASTFormalParameter;
8   import net.sourceforge.pmd.ast.ASTMethodDeclaration;
9   import net.sourceforge.pmd.symboltable.NameOccurrence;
10  import net.sourceforge.pmd.symboltable.Scope;
11  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
12  
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.Map;
16  
17  public class MethodArgumentCouldBeFinal extends AbstractOptimizationRule {
18  
19      public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
20          if (node.isInterface()) {
21              return data;
22          }
23          return super.visit(node, data);
24      }
25  
26      public Object visit(ASTMethodDeclaration meth, Object data) {
27          if (meth.isNative() || meth.isAbstract()) {
28              return data;
29          }
30          Scope s = meth.getScope();
31          Map decls = s.getVariableDeclarations();
32          for (Iterator i = decls.keySet().iterator(); i.hasNext();) {
33              VariableNameDeclaration var = (VariableNameDeclaration) i.next();
34              if (!var.getAccessNodeParent().isFinal() && (var.getAccessNodeParent() instanceof ASTFormalParameter) && !assigned((List) decls.get(var))) {
35                  addViolation(data, var.getAccessNodeParent(), var.getImage());
36              }
37          }
38          return data;
39      }
40  
41      private boolean assigned(List usages) {
42          for (Iterator j = usages.iterator(); j.hasNext();) {
43              NameOccurrence occ = (NameOccurrence) j.next();
44              if (occ.isOnLeftHandSide() || occ.isSelfAssignment()) {
45                  return true;
46              }
47              continue;
48          }
49          return false;
50      }
51  }