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