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 }