1
2
3
4 package net.sourceforge.pmd.lang.java.rule.design;
5
6 import net.sourceforge.pmd.lang.ast.Node;
7 import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
8 import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
9 import net.sourceforge.pmd.lang.java.ast.ASTInitializer;
10 import net.sourceforge.pmd.lang.java.ast.ASTName;
11 import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
12 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
13 import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
14
15 public class CompareObjectsWithEqualsRule extends AbstractJavaRule {
16
17 private boolean hasName(Node n) {
18 return n.jjtGetNumChildren() > 0 && n.jjtGetChild(0) instanceof ASTName;
19 }
20
21
22
23
24
25
26
27
28 private boolean isAllocation(Node n) {
29 return n.jjtGetNumChildren() > 0 && n.jjtGetChild(0) instanceof ASTAllocationExpression && n.jjtGetParent().jjtGetNumChildren() == 1;
30 }
31
32 public Object visit(ASTEqualityExpression node, Object data) {
33 Node c0 = node.jjtGetChild(0).jjtGetChild(0);
34 Node c1 = node.jjtGetChild(1).jjtGetChild(0);
35
36
37
38 if ((isAllocation(c0)) || (isAllocation(c1))) {
39 addViolation(data, node);
40 return data;
41 }
42
43
44 if (!hasName(c0) || !hasName(c1)) {
45 return data;
46 }
47
48
49 if (isQualifiedName(c0.jjtGetChild(0)) || isQualifiedName(c1.jjtGetChild(0))) {
50 return data;
51 }
52
53
54 if (!node.getParentsOfType(ASTInitializer.class).isEmpty()) {
55 return data;
56 }
57
58 ASTName n0 = (ASTName) c0.jjtGetChild(0);
59 ASTName n1 = (ASTName) c1.jjtGetChild(0);
60
61 if (n0.getNameDeclaration() instanceof VariableNameDeclaration && n1.getNameDeclaration() instanceof VariableNameDeclaration) {
62 VariableNameDeclaration nd0 = (VariableNameDeclaration) n0.getNameDeclaration();
63 VariableNameDeclaration nd1 = (VariableNameDeclaration) n1.getNameDeclaration();
64
65
66
67 if (nd0.isArray() || nd1.isArray()) {
68 return data;
69 }
70
71 if (nd0.isReferenceType() && nd1.isReferenceType()) {
72
73 ASTReferenceType type0 = (ASTReferenceType)((Node) nd0.getAccessNodeParent()).jjtGetChild(0).jjtGetChild(0);
74 ASTReferenceType type1 = (ASTReferenceType)((Node) nd1.getAccessNodeParent()).jjtGetChild(0).jjtGetChild(0);
75
76 if (type0.getType() != null && type0.getType().equals(type1.getType()) && type0.getType().isEnum()) {
77 return data;
78 }
79
80 addViolation(data, node);
81 }
82 }
83
84 return data;
85 }
86 }