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 }