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 }