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