UselessOperationOnImmutable xref

View Javadoc
1 package net.sourceforge.pmd.rules;
2 
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Set;
6 
7 import net.sourceforge.pmd.AbstractJavaRule;
8 import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
9 import net.sourceforge.pmd.ast.ASTStatementExpression;
10 import net.sourceforge.pmd.ast.ASTType;
11 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
12 import net.sourceforge.pmd.ast.Node;
13 import net.sourceforge.pmd.ast.SimpleNode;
14 import net.sourceforge.pmd.symboltable.NameOccurrence;
15 import net.sourceforge.pmd.util.CollectionUtil;
16 
17 /**
18  * An operation on an Immutable object (String, BigDecimal or BigInteger) won't change
19  * the object itself. The result of the operation is a new object. Therefore,
20  * ignoring the operation result is an error.
21  */
22 public class UselessOperationOnImmutable extends AbstractJavaRule {
23 
24 /**
25  * These are the BigDecimal methods which are immutable
26  */
27 private static final Set<String> decMethods = CollectionUtil.asSet(new String[] { ".abs", ".add", ".divide", ".divideToIntegralValue", ".max", ".min", ".movePointLeft", ".movePointRight", ".multiply", ".negate", ".plus", ".pow", ".remainder", ".round", ".scaleByPowerOfTen", ".setScale", ".stripTrailingZeros", ".subtract", ".ulp" });
28 
29 /**
30  * These are the BigInteger methods which are immutable
31  */
32 private static final Set<String> intMethods = CollectionUtil.asSet(new String[] { ".abs", ".add", ".and", ".andNot", ".clearBit", ".divide", ".flipBit", ".gcd", ".max", ".min", ".mod", ".modInverse", ".modPow", ".multiply", ".negate", ".nextProbablePrine", ".not", ".or", ".pow", ".remainder", ".setBit", ".shiftLeft", ".shiftRight", ".subtract", ".xor" });
33 
34 /**
35  * These are the String methods which are immutable
36  */
37 private static final Set<String> strMethods = CollectionUtil.asSet(new String[] { ".concat", ".intern", ".replace", ".replaceAll", ".replaceFirst", ".substring", ".toLowerCase", ".toString", ".toUpperCase", ".trim" });
38 
39 /**
40  * These are the classes that the rule can apply to
41  */
42 private static final Map<String, Set<String>> mapClasses = new HashMap<String, Set<String>>();
43 static {
44 mapClasses.put("java.math.BigDecimal", decMethods);
45 mapClasses.put("BigDecimal", decMethods);
46 mapClasses.put("java.math.BigInteger", intMethods);
47 mapClasses.put("BigInteger", intMethods);
48 mapClasses.put("java.lang.String", strMethods);
49 mapClasses.put("String", strMethods);
50 }
51 
52 public Object visit(ASTLocalVariableDeclaration node, Object data) {
53 
54 ASTVariableDeclaratorId var = getDeclaration(node);
55 if (var == null) {
56 return super.visit(node, data);
57 }
58 String variableName = var.getImage();
59 for (NameOccurrence no: var.getUsages()) {
60 // FIXME - getUsages will return everything with the same name as the variable, 
61 // see JUnit test, case 6. Changing to SimpleNode below, revisit when getUsages is fixed
62 SimpleNode sn = no.getLocation();
63 Node primaryExpression = sn.jjtGetParent().jjtGetParent();
64 Class<? extends Node> parentClass = primaryExpression.jjtGetParent().getClass();
65 if (parentClass.equals(ASTStatementExpression.class)) {
66 String methodCall = sn.getImage().substring(variableName.length());
67 ASTType nodeType = node.getTypeNode();
68 if ( nodeType != null ) {
69 if ( mapClasses.get(nodeType.getTypeImage()).contains(methodCall)) {
70 addViolation(data, sn);
71 }
72 }
73 }
74 }
75 return super.visit(node, data);
76 }
77 
78 /**
79  * This method checks the variable declaration if it is on a class we care
80  * about. If it is, it returns the DeclaratorId
81  * 
82  * @param node
83  * The ASTLocalVariableDeclaration which is a problem
84  * @return ASTVariableDeclaratorId
85  */
86 private ASTVariableDeclaratorId getDeclaration(ASTLocalVariableDeclaration node) {
87 ASTType type = node.getTypeNode();
88 if (mapClasses.keySet().contains(type.getTypeImage())) {
89 return node.findChildrenOfType(ASTVariableDeclaratorId.class).get(0);
90 }
91 return null;
92 }
93 }

AltStyle によって変換されたページ (->オリジナル) /