1
2
3
4 package net.sourceforge.pmd.lang.java.rule;
5
6 import java.util.List;
7
8 import net.sourceforge.pmd.lang.ast.Node;
9 import net.sourceforge.pmd.lang.java.ast.ASTAdditiveExpression;
10 import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
11 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
12 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
13 import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence;
14 import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public abstract class AbstractPoorMethodCall extends AbstractJavaRule {
29
30
31
32
33
34
35 protected abstract String targetTypename();
36
37
38
39
40
41
42
43 protected abstract String[] methodNames();
44
45
46
47
48
49
50
51
52 protected abstract boolean isViolationArgument(Node arg);
53
54
55
56
57
58
59
60
61 private boolean isNotedMethod(NameOccurrence occurrence) {
62
63 if (occurrence == null) {
64 return false;
65 }
66
67 String methodCall = occurrence.getImage();
68 String[] methodNames = methodNames();
69
70 for (String element : methodNames) {
71 if (methodCall.indexOf(element) != -1) {
72 return true;
73 }
74 }
75 return false;
76 }
77
78
79
80
81
82
83
84
85 @Override
86 public Object visit(ASTVariableDeclaratorId node, Object data) {
87 if (!targetTypename().equals(node.getNameDeclaration().getTypeImage())) {
88 return data;
89 }
90
91 for (NameOccurrence occ : node.getUsages()) {
92 JavaNameOccurrence jocc = (JavaNameOccurrence)occ;
93 if (isNotedMethod(jocc.getNameForWhichThisIsAQualifier())) {
94 Node parent = jocc.getLocation().jjtGetParent().jjtGetParent();
95 if (parent instanceof ASTPrimaryExpression) {
96
97 if (parent.hasDescendantOfType(ASTAdditiveExpression.class)) {
98 return data;
99 }
100 List<ASTLiteral> literals = parent.findDescendantsOfType(ASTLiteral.class);
101 for (int l = 0; l < literals.size(); l++) {
102 ASTLiteral literal = literals.get(l);
103 if (isViolationArgument(literal)) {
104 addViolation(data, jocc.getLocation());
105 }
106 }
107 }
108 }
109 }
110 return data;
111 }
112 }