1 |
| |
2 |
| |
3 |
| |
4 |
| package net.sourceforge.pmd.rules; |
5 |
| |
6 |
| import net.sourceforge.pmd.AbstractRule; |
7 |
| import net.sourceforge.pmd.ast.ASTArguments; |
8 |
| import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration; |
9 |
| import net.sourceforge.pmd.ast.ASTCompilationUnit; |
10 |
| import net.sourceforge.pmd.ast.ASTConstructorDeclaration; |
11 |
| import net.sourceforge.pmd.ast.ASTEnumDeclaration; |
12 |
| import net.sourceforge.pmd.ast.ASTExplicitConstructorInvocation; |
13 |
| import net.sourceforge.pmd.ast.ASTLiteral; |
14 |
| import net.sourceforge.pmd.ast.ASTMethodDeclaration; |
15 |
| import net.sourceforge.pmd.ast.ASTMethodDeclarator; |
16 |
| import net.sourceforge.pmd.ast.ASTName; |
17 |
| import net.sourceforge.pmd.ast.ASTPrimaryExpression; |
18 |
| import net.sourceforge.pmd.ast.ASTPrimaryPrefix; |
19 |
| import net.sourceforge.pmd.ast.ASTPrimarySuffix; |
20 |
| import net.sourceforge.pmd.ast.AccessNode; |
21 |
| import net.sourceforge.pmd.ast.Node; |
22 |
| import net.sourceforge.pmd.ast.SimpleNode; |
23 |
| |
24 |
| import java.util.ArrayList; |
25 |
| import java.util.Collections; |
26 |
| import java.util.HashMap; |
27 |
| import java.util.Iterator; |
28 |
| import java.util.List; |
29 |
| import java.util.Map; |
30 |
| import java.util.Set; |
31 |
| |
32 |
| |
33 |
| |
34 |
| |
35 |
| |
36 |
| |
37 |
| |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| public final class ConstructorCallsOverridableMethod extends AbstractRule { |
44 |
| |
45 |
| |
46 |
| |
47 |
| |
48 |
| |
49 |
| |
50 |
| |
51 |
| |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| |
62 |
| |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| |
69 |
| |
70 |
| |
71 |
| |
72 |
| |
73 |
| |
74 |
| |
75 |
| |
76 |
| |
77 |
| |
78 |
| |
79 |
| |
80 |
| |
81 |
| |
82 |
| |
83 |
| |
84 |
| |
85 |
| |
86 |
| |
87 |
| |
88 |
| |
89 |
| |
90 |
| |
91 |
| |
92 |
| |
93 |
| |
94 |
| |
95 |
| |
96 |
| |
97 |
| |
98 |
| |
99 |
| |
100 |
| |
101 |
| |
102 |
| |
103 |
| |
104 |
| |
105 |
| |
106 |
| |
107 |
| |
108 |
| |
109 |
| |
110 |
| |
111 |
| |
112 |
| |
113 |
| |
114 |
| |
115 |
| |
116 |
| |
117 |
| |
118 |
| |
119 |
| |
120 |
| |
121 |
| |
122 |
| |
123 |
| |
124 |
| |
125 |
| |
126 |
| |
127 |
| |
128 |
| |
129 |
| |
130 |
| |
131 |
| |
132 |
| |
133 |
| |
134 |
| |
135 |
| |
136 |
| |
137 |
| |
138 |
| |
139 |
| |
140 |
| |
141 |
| |
142 |
| |
143 |
| |
144 |
| |
145 |
| |
146 |
| |
147 |
| |
148 |
| |
149 |
| |
150 |
| |
151 |
| |
152 |
| |
153 |
| |
154 |
| |
155 |
| private static class MethodInvocation { |
156 |
| private String m_Name; |
157 |
| private ASTPrimaryExpression m_Ape; |
158 |
| private List m_ReferenceNames; |
159 |
| private List m_QualifierNames; |
160 |
| private int m_ArgumentSize; |
161 |
| private boolean m_Super; |
162 |
| |
163 |
9
| private MethodInvocation(ASTPrimaryExpression ape, List qualifierNames, List referenceNames, String name, int argumentSize, boolean superCall) {
|
164 |
9
| m_Ape = ape;
|
165 |
9
| m_QualifierNames = qualifierNames;
|
166 |
9
| m_ReferenceNames = referenceNames;
|
167 |
9
| m_Name = name;
|
168 |
9
| m_ArgumentSize = argumentSize;
|
169 |
9
| m_Super = superCall;
|
170 |
| } |
171 |
| |
172 |
9
| public boolean isSuper() {
|
173 |
9
| return m_Super;
|
174 |
| } |
175 |
| |
176 |
6
| public String getName() {
|
177 |
6
| return m_Name;
|
178 |
| } |
179 |
| |
180 |
4
| public int getArgumentCount() {
|
181 |
4
| return m_ArgumentSize;
|
182 |
| } |
183 |
| |
184 |
9
| public List getReferenceNames() {
|
185 |
9
| return m_ReferenceNames;
|
186 |
| } |
187 |
| |
188 |
9
| public List getQualifierNames() {
|
189 |
9
| return m_QualifierNames;
|
190 |
| } |
191 |
| |
192 |
3
| public ASTPrimaryExpression getASTPrimaryExpression() {
|
193 |
3
| return m_Ape;
|
194 |
| } |
195 |
| |
196 |
11
| public static MethodInvocation getMethod(ASTPrimaryExpression node) {
|
197 |
11
| MethodInvocation meth = null;
|
198 |
11
| int i = node.jjtGetNumChildren();
|
199 |
11
| if (i > 1) {
|
200 |
| |
201 |
9
| Node lastNode = node.jjtGetChild(i - 1);
|
202 |
9
| if ((lastNode.jjtGetNumChildren() == 1) && (lastNode.jjtGetChild(0) instanceof ASTArguments)) {
|
203 |
| |
204 |
| |
205 |
9
| List varNames = new ArrayList();
|
206 |
9
| List packagesAndClasses = new ArrayList();
|
207 |
9
| String methodName = null;
|
208 |
9
| ASTArguments args = (ASTArguments) lastNode.jjtGetChild(0);
|
209 |
9
| int numOfArguments = args.getArgumentCount();
|
210 |
9
| boolean superFirst = false;
|
211 |
9
| int thisIndex = -1;
|
212 |
| |
213 |
9
| FIND_SUPER_OR_THIS: {
|
214 |
| |
215 |
| |
216 |
| |
217 |
| |
218 |
| |
219 |
9
| for (int x = 0; x < i - 1; x++) {
|
220 |
9
| Node child = node.jjtGetChild(x);
|
221 |
9
| if (child instanceof ASTPrimarySuffix) {
|
222 |
0
| ASTPrimarySuffix child2 = (ASTPrimarySuffix) child;
|
223 |
| |
224 |
| |
225 |
0
| if (child2.getImage() == null && child2.jjtGetNumChildren() == 0) {
|
226 |
0
| thisIndex = x;
|
227 |
0
| break;
|
228 |
| } |
229 |
| |
230 |
| |
231 |
| |
232 |
9
| } else if (child instanceof ASTPrimaryPrefix) {
|
233 |
9
| ASTPrimaryPrefix child2 = (ASTPrimaryPrefix) child;
|
234 |
9
| if (getNameFromPrefix(child2) == null) {
|
235 |
0
| if (child2.getImage() == null) {
|
236 |
0
| thisIndex = x;
|
237 |
0
| break;
|
238 |
| } else { |
239 |
0
| superFirst = true;
|
240 |
0
| thisIndex = x;
|
241 |
| |
242 |
| |
243 |
0
| break;
|
244 |
| } |
245 |
| } |
246 |
| } |
247 |
| |
248 |
| |
249 |
| |
250 |
| } |
251 |
| } |
252 |
| |
253 |
9
| if (thisIndex != -1) {
|
254 |
| |
255 |
| |
256 |
0
| if (superFirst) {
|
257 |
| |
258 |
0
| FIRSTNODE:{
|
259 |
0
| ASTPrimaryPrefix child = (ASTPrimaryPrefix) node.jjtGetChild(0);
|
260 |
0
| String name = child.getImage();
|
261 |
0
| if (i == 2) {
|
262 |
0
| methodName = name;
|
263 |
| } else { |
264 |
0
| varNames.add(name);
|
265 |
| } |
266 |
| } |
267 |
0
| OTHERNODES:{
|
268 |
0
| for (int x = 1; x < i - 1; x++) {
|
269 |
0
| Node child = node.jjtGetChild(x);
|
270 |
0
| ASTPrimarySuffix ps = (ASTPrimarySuffix) child;
|
271 |
0
| if (ps.isArguments() == false) {
|
272 |
0
| String name = ((ASTPrimarySuffix) child).getImage();
|
273 |
0
| if (x == i - 2) {
|
274 |
0
| methodName = name;
|
275 |
| } else { |
276 |
0
| varNames.add(name);
|
277 |
| } |
278 |
| } |
279 |
| } |
280 |
| } |
281 |
| } else { |
282 |
0
| FIRSTNODE:{
|
283 |
0
| if (thisIndex == 1) {
|
284 |
0
| ASTPrimaryPrefix child = (ASTPrimaryPrefix) node.jjtGetChild(0);
|
285 |
0
| String toParse = getNameFromPrefix(child);
|
286 |
| |
287 |
0
| java.util.StringTokenizer st = new java.util.StringTokenizer(toParse, ".");
|
288 |
0
| while (st.hasMoreTokens()) {
|
289 |
0
| packagesAndClasses.add(st.nextToken());
|
290 |
| } |
291 |
| } |
292 |
| } |
293 |
0
| OTHERNODES:{
|
294 |
| |
295 |
| |
296 |
0
| for (int x = thisIndex + 1; x < i - 1; x++) {
|
297 |
0
| ASTPrimarySuffix child = (ASTPrimarySuffix) node.jjtGetChild(x);
|
298 |
0
| if (child.isArguments() == false) {
|
299 |
0
| String name = child.getImage();
|
300 |
| |
301 |
0
| if (x == i - 2) {
|
302 |
0
| methodName = name;
|
303 |
| } else { |
304 |
0
| varNames.add(name);
|
305 |
| } |
306 |
| } |
307 |
| } |
308 |
| } |
309 |
| } |
310 |
| } else { |
311 |
| |
312 |
9
| FIRSTNODE:{
|
313 |
9
| ASTPrimaryPrefix child = (ASTPrimaryPrefix) node.jjtGetChild(0);
|
314 |
9
| String toParse = getNameFromPrefix(child);
|
315 |
| |
316 |
9
| java.util.StringTokenizer st = new java.util.StringTokenizer(toParse, ".");
|
317 |
9
| while (st.hasMoreTokens()) {
|
318 |
9
| String value = st.nextToken();
|
319 |
9
| if (!st.hasMoreTokens()) {
|
320 |
9
| if (i == 2) {
|
321 |
9
| methodName = value;
|
322 |
| } else { |
323 |
0
| varNames.add(value);
|
324 |
| } |
325 |
| } else { |
326 |
0
| varNames.add(value);
|
327 |
| } |
328 |
| } |
329 |
| } |
330 |
9
| OTHERNODES:{
|
331 |
9
| for (int x = 1; x < i - 1; x++) {
|
332 |
0
| ASTPrimarySuffix child = (ASTPrimarySuffix) node.jjtGetChild(x);
|
333 |
0
| if (child.isArguments() == false) {
|
334 |
0
| String name = child.getImage();
|
335 |
0
| if (x == i - 2) {
|
336 |
0
| methodName = name;
|
337 |
| } else { |
338 |
0
| varNames.add(name);
|
339 |
| } |
340 |
| } |
341 |
| } |
342 |
| } |
343 |
| } |
344 |
9
| meth = new MethodInvocation(node, packagesAndClasses, varNames, methodName, numOfArguments, superFirst);
|
345 |
| } |
346 |
| } |
347 |
11
| return meth;
|
348 |
| } |
349 |
| |
350 |
0
| public void show() {
|
351 |
0
| System.out.println("<MethodInvocation>");
|
352 |
0
| List pkg = getQualifierNames();
|
353 |
0
| System.out.println(" <Qualifiers>");
|
354 |
0
| for (Iterator it = pkg.iterator(); it.hasNext();) {
|
355 |
0
| String name = (String) it.next();
|
356 |
0
| System.out.println(" " + name);
|
357 |
| } |
358 |
0
| System.out.println(" </Qualifiers>");
|
359 |
0
| System.out.println(" <Super>" + isSuper() + "</Super>");
|
360 |
0
| List vars = getReferenceNames();
|
361 |
0
| System.out.println(" <References>");
|
362 |
0
| for (Iterator it = vars.iterator(); it.hasNext();) {
|
363 |
0
| String name = (String) it.next();
|
364 |
0
| System.out.println(" " + name);
|
365 |
| } |
366 |
0
| System.out.println(" </References>");
|
367 |
0
| System.out.println(" <Name>" + getName() + "</Name>");
|
368 |
0
| System.out.println("</MethodInvocation>");
|
369 |
| } |
370 |
| } |
371 |
| |
372 |
| private static final class ConstructorInvocation { |
373 |
| private ASTExplicitConstructorInvocation m_Eci; |
374 |
| private String name; |
375 |
| private int count = 0; |
376 |
| |
377 |
1
| public ConstructorInvocation(ASTExplicitConstructorInvocation eci) {
|
378 |
1
| m_Eci = eci;
|
379 |
1
| List l = new ArrayList();
|
380 |
1
| eci.findChildrenOfType(ASTArguments.class, l);
|
381 |
1
| if (l.size() > 0) {
|
382 |
1
| ASTArguments aa = (ASTArguments) l.get(0);
|
383 |
1
| count = aa.getArgumentCount();
|
384 |
| } |
385 |
1
| name = eci.getImage();
|
386 |
| } |
387 |
| |
388 |
2
| public ASTExplicitConstructorInvocation getASTExplicitConstructorInvocation() {
|
389 |
2
| return m_Eci;
|
390 |
| } |
391 |
| |
392 |
1
| public int getArgumentCount() {
|
393 |
1
| return count;
|
394 |
| } |
395 |
| |
396 |
0
| public String getName() {
|
397 |
0
| return name;
|
398 |
| } |
399 |
| } |
400 |
| |
401 |
| private static final class MethodHolder { |
402 |
| private ASTMethodDeclarator amd; |
403 |
| private boolean dangerous; |
404 |
| private String called; |
405 |
| |
406 |
10
| public MethodHolder(ASTMethodDeclarator amd) {
|
407 |
10
| this.amd = amd;
|
408 |
| } |
409 |
| |
410 |
7
| public void setCalledMethod(String name) {
|
411 |
7
| this.called = name;
|
412 |
| } |
413 |
| |
414 |
3
| public String getCalled() {
|
415 |
3
| return this.called;
|
416 |
| } |
417 |
| |
418 |
12
| public ASTMethodDeclarator getASTMethodDeclarator() {
|
419 |
12
| return amd;
|
420 |
| } |
421 |
| |
422 |
10
| public boolean isDangerous() {
|
423 |
10
| return dangerous;
|
424 |
| } |
425 |
| |
426 |
7
| public void setDangerous() {
|
427 |
7
| dangerous = true;
|
428 |
| } |
429 |
| } |
430 |
| |
431 |
| private final class ConstructorHolder { |
432 |
| private ASTConstructorDeclaration m_Cd; |
433 |
| private boolean m_Dangerous; |
434 |
| private ConstructorInvocation m_Ci; |
435 |
| private boolean m_CiInitialized; |
436 |
| |
437 |
10
| public ConstructorHolder(ASTConstructorDeclaration cd) {
|
438 |
10
| m_Cd = cd;
|
439 |
| } |
440 |
| |
441 |
1
| public ASTConstructorDeclaration getASTConstructorDeclaration() {
|
442 |
1
| return m_Cd;
|
443 |
| } |
444 |
| |
445 |
2
| public ConstructorInvocation getCalledConstructor() {
|
446 |
2
| if (m_CiInitialized == false) {
|
447 |
1
| initCI();
|
448 |
| } |
449 |
2
| return m_Ci;
|
450 |
| } |
451 |
| |
452 |
9
| public ASTExplicitConstructorInvocation getASTExplicitConstructorInvocation() {
|
453 |
9
| ASTExplicitConstructorInvocation eci = null;
|
454 |
9
| if (m_CiInitialized == false) {
|
455 |
9
| initCI();
|
456 |
| } |
457 |
9
| if (m_Ci != null) {
|
458 |
1
| eci = m_Ci.getASTExplicitConstructorInvocation();
|
459 |
| } |
460 |
9
| return eci;
|
461 |
| } |
462 |
| |
463 |
10
| private void initCI() {
|
464 |
10
| List expressions = new ArrayList();
|
465 |
10
| m_Cd.findChildrenOfType(ASTExplicitConstructorInvocation.class, expressions);
|
466 |
10
| if (!expressions.isEmpty()) {
|
467 |
1
| ASTExplicitConstructorInvocation eci = (ASTExplicitConstructorInvocation) expressions.get(0);
|
468 |
1
| m_Ci = new ConstructorInvocation(eci);
|
469 |
| |
470 |
| } |
471 |
10
| m_CiInitialized = true;
|
472 |
| } |
473 |
| |
474 |
3
| public boolean isDangerous() {
|
475 |
3
| return m_Dangerous;
|
476 |
| } |
477 |
| |
478 |
1
| public void setDangerous(boolean dangerous) {
|
479 |
1
| m_Dangerous = dangerous;
|
480 |
| } |
481 |
| } |
482 |
| |
483 |
| |
484 |
| |
485 |
| |
486 |
| private static class EvalPackage { |
487 |
38
| public EvalPackage() {
|
488 |
| } |
489 |
| |
490 |
9
| public EvalPackage(String className) {
|
491 |
9
| m_ClassName = className;
|
492 |
9
| calledMethods = new ArrayList();
|
493 |
9
| allMethodsOfClass = new HashMap();
|
494 |
9
| calledConstructors = new ArrayList();
|
495 |
9
| allPrivateConstructorsOfClass = new HashMap();
|
496 |
| } |
497 |
| |
498 |
| public String m_ClassName; |
499 |
| public List calledMethods; |
500 |
| public Map allMethodsOfClass; |
501 |
| |
502 |
| public List calledConstructors; |
503 |
| public Map allPrivateConstructorsOfClass; |
504 |
| } |
505 |
| |
506 |
| private static final class NullEvalPackage extends EvalPackage { |
507 |
38
| public NullEvalPackage() {
|
508 |
38
| m_ClassName = "";
|
509 |
38
| calledMethods = Collections.EMPTY_LIST;
|
510 |
38
| allMethodsOfClass = Collections.EMPTY_MAP;
|
511 |
38
| calledConstructors = Collections.EMPTY_LIST;
|
512 |
38
| allPrivateConstructorsOfClass = Collections.EMPTY_MAP;
|
513 |
| } |
514 |
| } |
515 |
| |
516 |
| private static final NullEvalPackage nullEvalPackage = new NullEvalPackage(); |
517 |
| |
518 |
| |
519 |
| |
520 |
| |
521 |
| |
522 |
| private final List evalPackages = new ArrayList(); |
523 |
| |
524 |
132
| private EvalPackage getCurrentEvalPackage() {
|
525 |
132
| return (EvalPackage) evalPackages.get(evalPackages.size() - 1);
|
526 |
| } |
527 |
| |
528 |
| |
529 |
| |
530 |
| |
531 |
9
| private void putEvalPackage(EvalPackage ep) {
|
532 |
9
| evalPackages.add(ep);
|
533 |
| } |
534 |
| |
535 |
9
| private void removeCurrentEvalPackage() {
|
536 |
9
| evalPackages.remove(evalPackages.size() - 1);
|
537 |
| } |
538 |
| |
539 |
10
| private void clearEvalPackages() {
|
540 |
10
| evalPackages.clear();
|
541 |
| } |
542 |
| |
543 |
| |
544 |
| |
545 |
| |
546 |
| |
547 |
9
| private Object visitClassDec(ASTClassOrInterfaceDeclaration node, Object data) {
|
548 |
9
| String className = node.getImage();
|
549 |
9
| if (!node.isFinal() && !node.isStatic()) {
|
550 |
9
| putEvalPackage(new EvalPackage(className));
|
551 |
| } else { |
552 |
0
| putEvalPackage(nullEvalPackage);
|
553 |
| } |
554 |
| |
555 |
9
| super.visit((ASTClassOrInterfaceDeclaration) node, data);
|
556 |
| |
557 |
| |
558 |
9
| if (!(getCurrentEvalPackage() instanceof NullEvalPackage)) {
|
559 |
| |
560 |
9
| while (evaluateDangerOfMethods(getCurrentEvalPackage().allMethodsOfClass)) {
|
561 |
| } |
562 |
| |
563 |
9
| evaluateDangerOfConstructors1(getCurrentEvalPackage().allPrivateConstructorsOfClass, getCurrentEvalPackage().allMethodsOfClass.keySet());
|
564 |
9
| while (evaluateDangerOfConstructors2(getCurrentEvalPackage().allPrivateConstructorsOfClass)) {
|
565 |
| } |
566 |
| |
567 |
| |
568 |
9
| for (Iterator it = getCurrentEvalPackage().calledMethods.iterator(); it.hasNext();) {
|
569 |
7
| MethodInvocation meth = (MethodInvocation) it.next();
|
570 |
| |
571 |
7
| for (Iterator it2 = getCurrentEvalPackage().allMethodsOfClass.keySet().iterator(); it2.hasNext();) {
|
572 |
8
| MethodHolder h = (MethodHolder) it2.next();
|
573 |
8
| if (h.isDangerous()) {
|
574 |
5
| String methName = h.getASTMethodDeclarator().getImage();
|
575 |
5
| int count = h.getASTMethodDeclarator().getParameterCount();
|
576 |
5
| if (meth.getName().equals(methName) && meth.getArgumentCount() == count) {
|
577 |
3
| addViolation(data, meth.getASTPrimaryExpression(), "method '" + h.getCalled() + "'");
|
578 |
| } |
579 |
| } |
580 |
| } |
581 |
| } |
582 |
| |
583 |
9
| for (Iterator privConstIter = getCurrentEvalPackage().allPrivateConstructorsOfClass.keySet().iterator(); privConstIter.hasNext();) {
|
584 |
1
| ConstructorHolder ch = (ConstructorHolder) privConstIter.next();
|
585 |
1
| if (ch.isDangerous()) {
|
586 |
| |
587 |
1
| int paramCount = ch.getASTConstructorDeclaration().getParameterCount();
|
588 |
1
| for (Iterator calledConstIter = getCurrentEvalPackage().calledConstructors.iterator(); calledConstIter.hasNext();) {
|
589 |
1
| ConstructorInvocation ci = (ConstructorInvocation) calledConstIter.next();
|
590 |
1
| if (ci.getArgumentCount() == paramCount) {
|
591 |
| |
592 |
1
| addViolation(data, ci.getASTExplicitConstructorInvocation(), "constructor");
|
593 |
| } |
594 |
| } |
595 |
| } |
596 |
| } |
597 |
| } |
598 |
| |
599 |
9
| removeCurrentEvalPackage();
|
600 |
9
| return data;
|
601 |
| } |
602 |
| |
603 |
| |
604 |
| |
605 |
| |
606 |
| |
607 |
| |
608 |
| |
609 |
| |
610 |
| |
611 |
| |
612 |
| |
613 |
| |
614 |
| |
615 |
| |
616 |
| |
617 |
9
| private boolean evaluateDangerOfMethods(Map classMethodMap) {
|
618 |
| |
619 |
9
| boolean found = false;
|
620 |
9
| for (Iterator methodsIter = classMethodMap.keySet().iterator(); methodsIter.hasNext();) {
|
621 |
10
| MethodHolder h = (MethodHolder) methodsIter.next();
|
622 |
10
| List calledMeths = (List) classMethodMap.get(h);
|
623 |
10
| for (Iterator calledMethsIter = calledMeths.iterator(); calledMethsIter.hasNext() && (h.isDangerous() == false);) {
|
624 |
| |
625 |
0
| MethodInvocation meth = (MethodInvocation) calledMethsIter.next();
|
626 |
| |
627 |
0
| for (Iterator innerMethsIter = classMethodMap.keySet().iterator(); innerMethsIter.hasNext();) {
|
628 |
0
| MethodHolder h3 = (MethodHolder) innerMethsIter.next();
|
629 |
0
| if (h3.isDangerous()) {
|
630 |
0
| String matchMethodName = h3.getASTMethodDeclarator().getImage();
|
631 |
0
| int matchMethodParamCount = h3.getASTMethodDeclarator().getParameterCount();
|
632 |
| |
633 |
0
| if (matchMethodName.equals(meth.getName()) && matchMethodParamCount == meth.getArgumentCount()) {
|
634 |
0
| h.setDangerous();
|
635 |
0
| h.setCalledMethod(matchMethodName);
|
636 |
0
| found = true;
|
637 |
0
| break;
|
638 |
| } |
639 |
| } |
640 |
| } |
641 |
| } |
642 |
| } |
643 |
9
| return found;
|
644 |
| } |
645 |
| |
646 |
| |
647 |
| |
648 |
| |
649 |
| |
650 |
| |
651 |
| |
652 |
9
| private void evaluateDangerOfConstructors1(Map classConstructorMap, Set evaluatedMethods) {
|
653 |
| |
654 |
9
| for (Iterator constIter = classConstructorMap.keySet().iterator(); constIter.hasNext();) {
|
655 |
1
| ConstructorHolder ch = (ConstructorHolder) constIter.next();
|
656 |
1
| if (!ch.isDangerous()) {
|
657 |
| |
658 |
1
| List calledMeths = (List) classConstructorMap.get(ch);
|
659 |
| |
660 |
1
| for (Iterator calledMethsIter = calledMeths.iterator(); calledMethsIter.hasNext() && !ch.isDangerous();) {
|
661 |
1
| MethodInvocation meth = (MethodInvocation) calledMethsIter.next();
|
662 |
1
| String methName = meth.getName();
|
663 |
1
| int methArgCount = meth.getArgumentCount();
|
664 |
| |
665 |
1
| for (Iterator evaldMethsIter = evaluatedMethods.iterator(); evaldMethsIter.hasNext();) {
|
666 |
1
| MethodHolder h = (MethodHolder) evaldMethsIter.next();
|
667 |
1
| if (h.isDangerous()) {
|
668 |
1
| String matchName = h.getASTMethodDeclarator().getImage();
|
669 |
1
| int matchParamCount = h.getASTMethodDeclarator().getParameterCount();
|
670 |
1
| if (methName.equals(matchName) && (methArgCount == matchParamCount)) {
|
671 |
1
| ch.setDangerous(true);
|
672 |
| |
673 |
1
| break;
|
674 |
| } |
675 |
| } |
676 |
| |
677 |
| } |
678 |
| } |
679 |
| } |
680 |
| } |
681 |
| } |
682 |
| |
683 |
| |
684 |
| |
685 |
| |
686 |
| |
687 |
| |
688 |
| |
689 |
| |
690 |
| |
691 |
| |
692 |
9
| private boolean evaluateDangerOfConstructors2(Map classConstructorMap) {
|
693 |
9
| boolean found = false;
|
694 |
| |
695 |
9
| for (Iterator constIter = classConstructorMap.keySet().iterator(); constIter.hasNext();) {
|
696 |
1
| ConstructorHolder ch = (ConstructorHolder) constIter.next();
|
697 |
1
| ConstructorInvocation calledC = ch.getCalledConstructor();
|
698 |
1
| if (calledC == null || ch.isDangerous()) {
|
699 |
1
| continue;
|
700 |
| } |
701 |
| |
702 |
| |
703 |
0
| int cCount = calledC.getArgumentCount();
|
704 |
0
| for (Iterator innerConstIter = classConstructorMap.keySet().iterator(); innerConstIter.hasNext() && !ch.isDangerous();) {
|
705 |
0
| ConstructorHolder h2 = (ConstructorHolder) innerConstIter.next();
|
706 |
0
| if (h2.isDangerous()) {
|
707 |
0
| int matchConstArgCount = h2.getASTConstructorDeclaration().getParameterCount();
|
708 |
0
| if (matchConstArgCount == cCount) {
|
709 |
0
| ch.setDangerous(true);
|
710 |
0
| found = true;
|
711 |
| |
712 |
| } |
713 |
| } |
714 |
| } |
715 |
| } |
716 |
9
| return found;
|
717 |
| } |
718 |
| |
719 |
10
| public Object visit(ASTCompilationUnit node, Object data) {
|
720 |
10
| clearEvalPackages();
|
721 |
10
| return super.visit(node, data);
|
722 |
| } |
723 |
| |
724 |
1
| public Object visit(ASTEnumDeclaration node, Object data) {
|
725 |
| |
726 |
1
| return data;
|
727 |
| } |
728 |
| |
729 |
| |
730 |
| |
731 |
| |
732 |
| |
733 |
9
| public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
|
734 |
9
| if (!node.isInterface()) {
|
735 |
9
| return visitClassDec(node, data);
|
736 |
| } else { |
737 |
0
| putEvalPackage(nullEvalPackage);
|
738 |
0
| Object o = super.visit(node, data);
|
739 |
0
| removeCurrentEvalPackage();
|
740 |
0
| return o;
|
741 |
| } |
742 |
| } |
743 |
| |
744 |
| |
745 |
| |
746 |
| |
747 |
| |
748 |
| |
749 |
| |
750 |
| |
751 |
| |
752 |
| |
753 |
| |
754 |
| |
755 |
| |
756 |
| |
757 |
| |
758 |
| |
759 |
10
| public Object visit(ASTConstructorDeclaration node, Object data) {
|
760 |
10
| if (!(getCurrentEvalPackage() instanceof NullEvalPackage)) {
|
761 |
10
| List calledMethodsOfConstructor = new ArrayList();
|
762 |
10
| ConstructorHolder ch = new ConstructorHolder(node);
|
763 |
10
| addCalledMethodsOfNode(node, calledMethodsOfConstructor, getCurrentEvalPackage().m_ClassName);
|
764 |
10
| if (!node.isPrivate()) {
|
765 |
| |
766 |
9
| getCurrentEvalPackage().calledMethods.addAll(calledMethodsOfConstructor);
|
767 |
| |
768 |
| |
769 |
| |
770 |
9
| ASTExplicitConstructorInvocation eci = ch.getASTExplicitConstructorInvocation();
|
771 |
9
| if (eci != null && eci.isThis()) {
|
772 |
1
| getCurrentEvalPackage().calledConstructors.add(ch.getCalledConstructor());
|
773 |
| } |
774 |
| } else { |
775 |
| |
776 |
| |
777 |
1
| getCurrentEvalPackage().allPrivateConstructorsOfClass.put(ch, calledMethodsOfConstructor);
|
778 |
| } |
779 |
| } |
780 |
10
| return super.visit(node, data);
|
781 |
| } |
782 |
| |
783 |
| |
784 |
| |
785 |
| |
786 |
| |
787 |
| |
788 |
10
| public Object visit(ASTMethodDeclarator node, Object data) {
|
789 |
10
| if (!(getCurrentEvalPackage() instanceof NullEvalPackage)) {
|
790 |
10
| AccessNode parent = (AccessNode) node.jjtGetParent();
|
791 |
10
| MethodHolder h = new MethodHolder(node);
|
792 |
10
| if (!parent.isAbstract() && !parent.isPrivate() && !parent.isStatic() && !parent.isFinal()) {
|
793 |
7
| h.setDangerous();
|
794 |
7
| ASTMethodDeclaration decl = (ASTMethodDeclaration) node.getFirstParentOfType(ASTMethodDeclaration.class);
|
795 |
7
| h.setCalledMethod(decl.getMethodName());
|
796 |
| } |
797 |
10
| List l = new ArrayList();
|
798 |
10
| addCalledMethodsOfNode((SimpleNode) parent, l, getCurrentEvalPackage().m_ClassName);
|
799 |
10
| getCurrentEvalPackage().allMethodsOfClass.put(h, l);
|
800 |
| } |
801 |
10
| return super.visit(node, data);
|
802 |
| } |
803 |
| |
804 |
| |
805 |
10
| private static void addCalledMethodsOfNode(AccessNode node, List calledMethods, String className) {
|
806 |
10
| List expressions = new ArrayList();
|
807 |
10
| node.findChildrenOfType(ASTPrimaryExpression.class, expressions, false);
|
808 |
10
| addCalledMethodsOfNodeImpl(expressions, calledMethods, className);
|
809 |
| } |
810 |
| |
811 |
| |
812 |
| |
813 |
| |
814 |
10
| private static void addCalledMethodsOfNode(SimpleNode node, List calledMethods, String className) {
|
815 |
10
| List expressions = new ArrayList();
|
816 |
10
| node.findChildrenOfType(ASTPrimaryExpression.class, expressions);
|
817 |
10
| addCalledMethodsOfNodeImpl(expressions, calledMethods, className);
|
818 |
| } |
819 |
| |
820 |
20
| private static void addCalledMethodsOfNodeImpl(List expressions, List calledMethods, String className) {
|
821 |
20
| for (Iterator it = expressions.iterator(); it.hasNext();) {
|
822 |
13
| ASTPrimaryExpression ape = (ASTPrimaryExpression) it.next();
|
823 |
13
| MethodInvocation meth = findMethod(ape, className);
|
824 |
13
| if (meth != null) {
|
825 |
| |
826 |
9
| calledMethods.add(meth);
|
827 |
| } |
828 |
| } |
829 |
| } |
830 |
| |
831 |
| |
832 |
| |
833 |
| |
834 |
| |
835 |
| |
836 |
| |
837 |
13
| private static MethodInvocation findMethod(ASTPrimaryExpression node, String className) {
|
838 |
13
| if (node.jjtGetNumChildren() > 0
|
839 |
| && node.jjtGetChild(0).jjtGetNumChildren() > 0 |
840 |
| && node.jjtGetChild(0).jjtGetChild(0) instanceof ASTLiteral) { |
841 |
2
| return null;
|
842 |
| } |
843 |
11
| MethodInvocation meth = MethodInvocation.getMethod(node);
|
844 |
11
| boolean found = false;
|
845 |
| |
846 |
| |
847 |
| |
848 |
11
| if (meth != null) {
|
849 |
| |
850 |
9
| if ((meth.getReferenceNames().size() == 0) && !meth.isSuper()) {
|
851 |
| |
852 |
| |
853 |
9
| List packClass = meth.getQualifierNames();
|
854 |
9
| if (packClass.size() > 0) {
|
855 |
0
| for (Iterator it = packClass.iterator(); it.hasNext();) {
|
856 |
0
| String name = (String) it.next();
|
857 |
0
| if (name.equals(className)) {
|
858 |
0
| found = true;
|
859 |
0
| break;
|
860 |
| } |
861 |
| } |
862 |
| } else { |
863 |
9
| found = true;
|
864 |
| } |
865 |
| } |
866 |
| } |
867 |
| |
868 |
11
| return found ? meth : null;
|
869 |
| } |
870 |
| |
871 |
| |
872 |
| |
873 |
| |
874 |
18
| private static String getNameFromPrefix(ASTPrimaryPrefix node) {
|
875 |
18
| String name = null;
|
876 |
| |
877 |
18
| if (node.jjtGetNumChildren() == 1) {
|
878 |
18
| Node nnode = node.jjtGetChild(0);
|
879 |
18
| if (nnode instanceof ASTName) {
|
880 |
18
| name = ((ASTName) nnode).getImage();
|
881 |
| } |
882 |
| } |
883 |
18
| return name;
|
884 |
| } |
885 |
| |
886 |
| } |