1
2
3
4 package net.sourceforge.pmd.lang.java.typeresolution;
5
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.logging.Level;
12 import java.util.logging.Logger;
13
14 import net.sourceforge.pmd.lang.ast.AbstractNode;
15 import net.sourceforge.pmd.lang.ast.Node;
16 import net.sourceforge.pmd.lang.java.ast.ASTAdditiveExpression;
17 import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
18 import net.sourceforge.pmd.lang.java.ast.ASTAndExpression;
19 import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
20 import net.sourceforge.pmd.lang.java.ast.ASTArrayDimsAndInits;
21 import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
22 import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
23 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody;
24 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
25 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
26 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
27 import net.sourceforge.pmd.lang.java.ast.ASTConditionalAndExpression;
28 import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
29 import net.sourceforge.pmd.lang.java.ast.ASTConditionalOrExpression;
30 import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
31 import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
32 import net.sourceforge.pmd.lang.java.ast.ASTExclusiveOrExpression;
33 import net.sourceforge.pmd.lang.java.ast.ASTExpression;
34 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
35 import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
36 import net.sourceforge.pmd.lang.java.ast.ASTInclusiveOrExpression;
37 import net.sourceforge.pmd.lang.java.ast.ASTInstanceOfExpression;
38 import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
39 import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation;
40 import net.sourceforge.pmd.lang.java.ast.ASTMultiplicativeExpression;
41 import net.sourceforge.pmd.lang.java.ast.ASTName;
42 import net.sourceforge.pmd.lang.java.ast.ASTNormalAnnotation;
43 import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
44 import net.sourceforge.pmd.lang.java.ast.ASTPackageDeclaration;
45 import net.sourceforge.pmd.lang.java.ast.ASTPostfixExpression;
46 import net.sourceforge.pmd.lang.java.ast.ASTPreDecrementExpression;
47 import net.sourceforge.pmd.lang.java.ast.ASTPreIncrementExpression;
48 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
49 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
50 import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
51 import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
52 import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
53 import net.sourceforge.pmd.lang.java.ast.ASTRelationalExpression;
54 import net.sourceforge.pmd.lang.java.ast.ASTShiftExpression;
55 import net.sourceforge.pmd.lang.java.ast.ASTSingleMemberAnnotation;
56 import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
57 import net.sourceforge.pmd.lang.java.ast.ASTType;
58 import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
59 import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
60 import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpressionNotPlusMinus;
61 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
62 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
63 import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter;
64 import net.sourceforge.pmd.lang.java.ast.TypeNode;
65
66
67
68
69
70
71
72 public class ClassTypeResolver extends JavaParserVisitorAdapter {
73
74 private static final Logger LOG = Logger.getLogger(ClassTypeResolver.class.getName());
75
76 private static final Map<String, Class<?>> PRIMITIVE_TYPES;
77 private static final Map<String, String> JAVA_LANG;
78
79 static {
80
81 Map<String, Class<?>> thePrimitiveTypes = new HashMap<String, Class<?>>();
82 thePrimitiveTypes.put("void", Void.TYPE);
83 thePrimitiveTypes.put("boolean", Boolean.TYPE);
84 thePrimitiveTypes.put("byte", Byte.TYPE);
85 thePrimitiveTypes.put("char", Character.TYPE);
86 thePrimitiveTypes.put("short", Short.TYPE);
87 thePrimitiveTypes.put("int", Integer.TYPE);
88 thePrimitiveTypes.put("long", Long.TYPE);
89 thePrimitiveTypes.put("float", Float.TYPE);
90 thePrimitiveTypes.put("double", Double.TYPE);
91 PRIMITIVE_TYPES = Collections.unmodifiableMap(thePrimitiveTypes);
92
93 Map<String, String> theJavaLang = new HashMap<String, String>();
94 theJavaLang.put("Boolean", "java.lang.Boolean");
95 theJavaLang.put("Byte", "java.lang.Byte");
96 theJavaLang.put("Character", "java.lang.Character");
97 theJavaLang.put("CharSequence", "java.lang.CharSequence");
98 theJavaLang.put("Class", "java.lang.Class");
99 theJavaLang.put("ClassLoader", "java.lang.ClassLoader");
100 theJavaLang.put("Cloneable", "java.lang.Cloneable");
101 theJavaLang.put("Comparable", "java.lang.Comparable");
102 theJavaLang.put("Compiler", "java.lang.Compiler");
103 theJavaLang.put("Double", "java.lang.Double");
104 theJavaLang.put("Float", "java.lang.Float");
105 theJavaLang.put("InheritableThreadLocal", "java.lang.InheritableThreadLocal");
106 theJavaLang.put("Integer", "java.lang.Integer");
107 theJavaLang.put("Long", "java.lang.Long");
108 theJavaLang.put("Math", "java.lang.Math");
109 theJavaLang.put("Number", "java.lang.Number");
110 theJavaLang.put("Object", "java.lang.Object");
111 theJavaLang.put("Package", "java.lang.Package");
112 theJavaLang.put("Process", "java.lang.Process");
113 theJavaLang.put("Runnable", "java.lang.Runnable");
114 theJavaLang.put("Runtime", "java.lang.Runtime");
115 theJavaLang.put("RuntimePermission", "java.lang.RuntimePermission");
116 theJavaLang.put("SecurityManager", "java.lang.SecurityManager");
117 theJavaLang.put("Short", "java.lang.Short");
118 theJavaLang.put("StackTraceElement", "java.lang.StackTraceElement");
119 theJavaLang.put("StrictMath", "java.lang.StrictMath");
120 theJavaLang.put("String", "java.lang.String");
121 theJavaLang.put("StringBuffer", "java.lang.StringBuffer");
122 theJavaLang.put("System", "java.lang.System");
123 theJavaLang.put("Thread", "java.lang.Thread");
124 theJavaLang.put("ThreadGroup", "java.lang.ThreadGroup");
125 theJavaLang.put("ThreadLocal", "java.lang.ThreadLocal");
126 theJavaLang.put("Throwable", "java.lang.Throwable");
127 theJavaLang.put("Void", "java.lang.Void");
128 JAVA_LANG = Collections.unmodifiableMap(theJavaLang);
129 }
130
131 private final PMDASMClassLoader pmdClassLoader;
132 private Map<String, String> importedClasses;
133 private List<String> importedOnDemand;
134 private int anonymousClassCounter = 0;
135
136 public ClassTypeResolver() {
137 this(ClassTypeResolver.class.getClassLoader());
138 }
139
140 public ClassTypeResolver(ClassLoader classLoader) {
141 pmdClassLoader = PMDASMClassLoader.getInstance(classLoader);
142 }
143
144
145 @Override
146 public Object visit(ASTCompilationUnit node, Object data) {
147 String className = null;
148 try {
149 importedOnDemand = new ArrayList<String>();
150 importedClasses = new HashMap<String, String>();
151 className = getClassName(node);
152 if (className != null) {
153 populateClassName(node, className);
154 }
155 } catch (ClassNotFoundException e) {
156 if (LOG.isLoggable(Level.FINE)) {
157 LOG.log(Level.FINE, "Could not find class " + className + ", due to: " + e);
158 }
159 } catch (NoClassDefFoundError e) {
160 if (LOG.isLoggable(Level.FINE)) {
161 LOG.log(Level.FINE, "Could not find class " + className + ", due to: " + e);
162 }
163 } catch (LinkageError e) {
164 if (LOG.isLoggable(Level.WARNING)) {
165 LOG.log(Level.WARNING, "Could not find class " + className + ", due to: " + e);
166 }
167 } finally {
168 populateImports(node);
169 }
170 return super.visit(node, data);
171 }
172
173 @Override
174 public Object visit(ASTImportDeclaration node, Object data) {
175 ASTName importedType = (ASTName)node.jjtGetChild(0);
176 if (importedType.getType() != null) {
177 node.setType(importedType.getType());
178 } else {
179 populateType(node, importedType.getImage());
180 }
181
182 if (node.getType() != null) {
183 node.setPackage(node.getType().getPackage());
184 }
185 return data;
186 }
187
188 @Override
189 public Object visit(ASTTypeDeclaration node, Object data) {
190 super.visit(node, data);
191 rollupTypeUnary(node);
192 return data;
193 }
194
195 @Override
196 public Object visit(ASTClassOrInterfaceType node, Object data) {
197 String typeName = node.getImage();
198 if (node.jjtGetParent().hasDescendantOfType(ASTClassOrInterfaceBody.class)) {
199 anonymousClassCounter++;
200 AbstractNode parent = node.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
201 if (parent == null) {
202 parent = node.getFirstParentOfType(ASTEnumDeclaration.class);
203 }
204 typeName = parent.getImage() + "$" + anonymousClassCounter;
205 }
206 populateType(node, typeName);
207 return data;
208 }
209
210 @Override
211 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
212 populateType(node, node.getImage());
213 return super.visit(node, data);
214 }
215
216 @Override
217 public Object visit(ASTEnumDeclaration node, Object data) {
218 populateType(node, node.getImage());
219 return super.visit(node, data);
220 }
221
222 @Override
223 public Object visit(ASTAnnotationTypeDeclaration node, Object data) {
224 populateType(node, node.getImage());
225 return super.visit(node, data);
226 }
227
228 @Override
229 public Object visit(ASTName node, Object data) {
230
231
232
233
234
235
236 if (node.getNameDeclaration() == null) {
237
238
239
240 if (!(node.jjtGetParent() instanceof ASTPackageDeclaration || node.jjtGetParent() instanceof ASTImportDeclaration)) {
241 String name = node.getImage();
242 if (name.indexOf('.') != -1) {
243 name = name.substring(0, name.indexOf('.'));
244 }
245 populateType(node, name);
246 }
247 } else {
248
249 if (node.getNameDeclaration().getNode() instanceof TypeNode) {
250 node.setType(((TypeNode)node.getNameDeclaration().getNode()).getType());
251 }
252 }
253 return super.visit(node, data);
254 }
255
256 @Override
257 public Object visit(ASTFieldDeclaration node, Object data) {
258 super.visit(node, data);
259 rollupTypeUnary(node);
260 return data;
261 }
262
263 @Override
264 public Object visit(ASTVariableDeclarator node, Object data) {
265 super.visit(node, data);
266 rollupTypeUnary(node);
267 return data;
268 }
269
270 @Override
271 public Object visit(ASTVariableDeclaratorId node, Object data) {
272 if (node == null || node.getNameDeclaration() == null) {
273 return super.visit(node, data);
274 }
275 String name = node.getNameDeclaration().getTypeImage();
276 if (name != null) {
277 if (name.indexOf('.') != -1) {
278 name = name.substring(0, name.indexOf('.'));
279 }
280 populateType(node, name);
281 }
282 return super.visit(node, data);
283 }
284
285 @Override
286 public Object visit(ASTType node, Object data) {
287 super.visit(node, data);
288 rollupTypeUnary(node);
289 return data;
290 }
291
292 @Override
293 public Object visit(ASTReferenceType node, Object data) {
294 super.visit(node, data);
295 rollupTypeUnary(node);
296 return data;
297 }
298
299 @Override
300 public Object visit(ASTPrimitiveType node, Object data) {
301 populateType(node, node.getImage());
302 return super.visit(node, data);
303 }
304
305 @Override
306 public Object visit(ASTExpression node, Object data) {
307 super.visit(node, data);
308 rollupTypeUnary(node);
309 return data;
310 }
311
312 @Override
313 public Object visit(ASTConditionalExpression node, Object data) {
314 super.visit(node, data);
315 if (node.isTernary()) {
316
317 } else {
318 rollupTypeUnary(node);
319 }
320 return data;
321 }
322
323 @Override
324 public Object visit(ASTConditionalOrExpression node, Object data) {
325 populateType(node, "boolean");
326 return super.visit(node, data);
327 }
328
329 @Override
330 public Object visit(ASTConditionalAndExpression node, Object data) {
331 populateType(node, "boolean");
332 return super.visit(node, data);
333 }
334
335 @Override
336 public Object visit(ASTInclusiveOrExpression node, Object data) {
337 super.visit(node, data);
338 rollupTypeBinaryNumericPromotion(node);
339 return data;
340 }
341
342 @Override
343 public Object visit(ASTExclusiveOrExpression node, Object data) {
344 super.visit(node, data);
345 rollupTypeBinaryNumericPromotion(node);
346 return data;
347 }
348
349 @Override
350 public Object visit(ASTAndExpression node, Object data) {
351 super.visit(node, data);
352 rollupTypeBinaryNumericPromotion(node);
353 return data;
354 }
355
356 @Override
357 public Object visit(ASTEqualityExpression node, Object data) {
358 populateType(node, "boolean");
359 return super.visit(node, data);
360 }
361
362 @Override
363 public Object visit(ASTInstanceOfExpression node, Object data) {
364 populateType(node, "boolean");
365 return super.visit(node, data);
366 }
367
368 @Override
369 public Object visit(ASTRelationalExpression node, Object data) {
370 populateType(node, "boolean");
371 return super.visit(node, data);
372 }
373
374 @Override
375 public Object visit(ASTShiftExpression node, Object data) {
376 super.visit(node, data);
377
378 rollupTypeUnaryNumericPromotion(node);
379 return data;
380 }
381
382 @Override
383 public Object visit(ASTAdditiveExpression node, Object data) {
384 super.visit(node, data);
385 rollupTypeBinaryNumericPromotion(node);
386 return data;
387 }
388
389 @Override
390 public Object visit(ASTMultiplicativeExpression node, Object data) {
391 super.visit(node, data);
392 rollupTypeBinaryNumericPromotion(node);
393 return data;
394 }
395
396 @Override
397 public Object visit(ASTUnaryExpression node, Object data) {
398 super.visit(node, data);
399 rollupTypeUnaryNumericPromotion(node);
400 return data;
401 }
402
403 @Override
404 public Object visit(ASTPreIncrementExpression node, Object data) {
405 super.visit(node, data);
406 rollupTypeUnary(node);
407 return data;
408 }
409
410 @Override
411 public Object visit(ASTPreDecrementExpression node, Object data) {
412 super.visit(node, data);
413 rollupTypeUnary(node);
414 return data;
415 }
416
417 @Override
418 public Object visit(ASTUnaryExpressionNotPlusMinus node, Object data) {
419 super.visit(node, data);
420 if ("!".equals(node.getImage())) {
421 populateType(node, "boolean");
422 } else {
423 rollupTypeUnary(node);
424 }
425 return data;
426 }
427
428 @Override
429 public Object visit(ASTPostfixExpression node, Object data) {
430 super.visit(node, data);
431 rollupTypeUnary(node);
432 return data;
433 }
434
435 @Override
436 public Object visit(ASTCastExpression node, Object data) {
437 super.visit(node, data);
438 rollupTypeUnary(node);
439 return data;
440 }
441
442 @Override
443 public Object visit(ASTPrimaryExpression node, Object data) {
444 super.visit(node, data);
445 if (node.jjtGetNumChildren() == 1) {
446 rollupTypeUnary(node);
447 } else {
448
449 }
450 return data;
451 }
452
453 @Override
454 public Object visit(ASTPrimaryPrefix node, Object data) {
455 super.visit(node, data);
456 if (node.getImage() == null) {
457 rollupTypeUnary(node);
458 } else {
459
460 }
461 return data;
462 }
463
464 @Override
465 public Object visit(ASTPrimarySuffix node, Object data) {
466 super.visit(node, data);
467
468 return data;
469 }
470
471 @Override
472 public Object visit(ASTNullLiteral node, Object data) {
473
474 return super.visit(node, data);
475 }
476
477 @Override
478 public Object visit(ASTBooleanLiteral node, Object data) {
479 populateType(node, "boolean");
480 return super.visit(node, data);
481 }
482
483 @Override
484 public Object visit(ASTLiteral node, Object data) {
485 super.visit(node, data);
486 if (node.jjtGetNumChildren() != 0) {
487 rollupTypeUnary(node);
488 } else {
489 if (node.isIntLiteral()) {
490 populateType(node, "int");
491 } else if (node.isLongLiteral()) {
492 populateType(node, "long");
493 } else if (node.isFloatLiteral()) {
494 populateType(node, "float");
495 } else if (node.isDoubleLiteral()) {
496 populateType(node, "double");
497 } else if (node.isCharLiteral()) {
498 populateType(node, "char");
499 } else if (node.isStringLiteral()) {
500 populateType(node, "java.lang.String");
501 } else {
502 throw new IllegalStateException("PMD error, unknown literal type!");
503 }
504 }
505 return data;
506 }
507
508 @Override
509 public Object visit(ASTAllocationExpression node, Object data) {
510 super.visit(node, data);
511
512 if (node.jjtGetNumChildren() >= 2 && node.jjtGetChild(1) instanceof ASTArrayDimsAndInits
513 || node.jjtGetNumChildren() >= 3 && node.jjtGetChild(2) instanceof ASTArrayDimsAndInits) {
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532 } else {
533 rollupTypeUnary(node);
534 }
535 return data;
536 }
537
538 @Override
539 public Object visit(ASTStatementExpression node, Object data) {
540 super.visit(node, data);
541 rollupTypeUnary(node);
542 return data;
543 }
544
545 @Override
546 public Object visit(ASTNormalAnnotation node, Object data) {
547 super.visit(node, data);
548 rollupTypeUnary(node);
549 return data;
550 }
551
552 @Override
553 public Object visit(ASTMarkerAnnotation node, Object data) {
554 super.visit(node, data);
555 rollupTypeUnary(node);
556 return data;
557 }
558
559 @Override
560 public Object visit(ASTSingleMemberAnnotation node, Object data) {
561 super.visit(node, data);
562 rollupTypeUnary(node);
563 return data;
564 }
565
566
567 private void rollupTypeUnary(TypeNode typeNode) {
568 if (typeNode instanceof Node) {
569 Node node = (Node)typeNode;
570 if (node.jjtGetNumChildren() >= 1) {
571 Node child = node.jjtGetChild(0);
572 if (child instanceof TypeNode) {
573 typeNode.setType(((TypeNode)child).getType());
574 }
575 }
576 }
577 }
578
579
580 private void rollupTypeUnaryNumericPromotion(TypeNode typeNode) {
581 if (typeNode instanceof Node) {
582 Node node = (Node)typeNode;
583 if (node.jjtGetNumChildren() >= 1) {
584 Node child = node.jjtGetChild(0);
585 if (child instanceof TypeNode) {
586 Class<?> type = ((TypeNode)child).getType();
587 if (type != null) {
588 if ("byte".equals(type.getName()) || "short".equals(type.getName())
589 || "char".equals(type.getName())) {
590 populateType(typeNode, "int");
591 } else {
592 typeNode.setType(((TypeNode)child).getType());
593 }
594 }
595 }
596 }
597 }
598 }
599
600
601 private void rollupTypeBinaryNumericPromotion(TypeNode typeNode) {
602 if (typeNode instanceof Node) {
603 Node node = (Node)typeNode;
604 if (node.jjtGetNumChildren() >= 2) {
605 Node child1 = node.jjtGetChild(0);
606 Node child2 = node.jjtGetChild(1);
607 if (child1 instanceof TypeNode && child2 instanceof TypeNode) {
608 Class<?> type1 = ((TypeNode)child1).getType();
609 Class<?> type2 = ((TypeNode)child2).getType();
610 if (type1 != null && type2 != null) {
611
612 if ("java.lang.String".equals(type1.getName()) || "java.lang.String".equals(type2.getName())) {
613 populateType(typeNode, "java.lang.String");
614 } else if ("boolean".equals(type1.getName()) || "boolean".equals(type2.getName())) {
615 populateType(typeNode, "boolean");
616 } else if ("double".equals(type1.getName()) || "double".equals(type2.getName())) {
617 populateType(typeNode, "double");
618 } else if ("float".equals(type1.getName()) || "float".equals(type2.getName())) {
619 populateType(typeNode, "float");
620 } else if ("long".equals(type1.getName()) || "long".equals(type2.getName())) {
621 populateType(typeNode, "long");
622 } else {
623 populateType(typeNode, "int");
624 }
625 } else if (type1 != null || type2 != null) {
626
627
628 if (type1 != null && "java.lang.String".equals(type1.getName())
629 || type2 != null && "java.lang.String".equals(type2.getName())) {
630 populateType(typeNode, "java.lang.String");
631 }
632 }
633 }
634 }
635 }
636 }
637
638 private void populateType(TypeNode node, String className) {
639
640 String qualifiedName = className;
641 Class<?> myType = PRIMITIVE_TYPES.get(className);
642 if (myType == null && importedClasses != null) {
643 if (importedClasses.containsKey(className)) {
644 qualifiedName = importedClasses.get(className);
645 } else if (importedClasses.containsValue(className)) {
646 qualifiedName = className;
647 }
648 if (qualifiedName != null) {
649 try {
650
651
652
653
654
655 myType = pmdClassLoader.loadClass(qualifiedName);
656 } catch (ClassNotFoundException e) {
657 myType = processOnDemand(qualifiedName);
658 } catch (NoClassDefFoundError e) {
659 myType = processOnDemand(qualifiedName);
660 } catch (LinkageError e) {
661 myType = processOnDemand(qualifiedName);
662 }
663 }
664 }
665 if (myType == null && qualifiedName != null && !qualifiedName.contains(".")) {
666
667 try {
668 myType = pmdClassLoader.loadClass("java.lang." + qualifiedName);
669 } catch (Exception e) {
670
671 }
672 }
673 if (myType != null) {
674 node.setType(myType);
675 }
676 }
677
678
679
680
681 public boolean classNameExists(String fullyQualifiedClassName) {
682 try {
683 pmdClassLoader.loadClass(fullyQualifiedClassName);
684 return true;
685 } catch (ClassNotFoundException e) {
686 return false;
687 } catch (NoClassDefFoundError e) {
688 return false;
689 }
690 }
691
692 public Class<?> loadClass(String fullyQualifiedClassName) {
693 try {
694 return pmdClassLoader.loadClass(fullyQualifiedClassName);
695 } catch (ClassNotFoundException e) {
696 return null;
697 }
698 }
699
700 private Class<?> processOnDemand(String qualifiedName) {
701 for (String entry : importedOnDemand) {
702 try {
703 return pmdClassLoader.loadClass(entry + "." + qualifiedName);
704 } catch (Throwable e) {
705 }
706 }
707 return null;
708 }
709
710 private String getClassName(ASTCompilationUnit node) {
711 ASTClassOrInterfaceDeclaration classDecl = node.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class);
712 if (classDecl == null) {
713 return null;
714 }
715 if (node.declarationsAreInDefaultPackage()) {
716 return classDecl.getImage();
717 }
718 ASTPackageDeclaration pkgDecl = node.getPackageDeclaration();
719 importedOnDemand.add(pkgDecl.getPackageNameImage());
720 return pkgDecl.getPackageNameImage() + "." + classDecl.getImage();
721 }
722
723
724
725
726
727
728 private void populateImports(ASTCompilationUnit node) {
729 List<ASTImportDeclaration> theImportDeclarations = node.findChildrenOfType(ASTImportDeclaration.class);
730
731 importedClasses.putAll(JAVA_LANG);
732
733
734 for (ASTImportDeclaration anImportDeclaration : theImportDeclarations) {
735 String strPackage = anImportDeclaration.getPackageName();
736 if (anImportDeclaration.isImportOnDemand()) {
737 importedOnDemand.add(strPackage);
738 } else if (!anImportDeclaration.isImportOnDemand()) {
739 String strName = anImportDeclaration.getImportedName();
740 importedClasses.put(strName, strName);
741 importedClasses.put(strName.substring(strPackage.length() + 1), strName);
742 }
743 }
744 }
745
746 private void populateClassName(ASTCompilationUnit node, String className) throws ClassNotFoundException {
747 node.setType(pmdClassLoader.loadClass(className));
748 importedClasses.putAll(pmdClassLoader.getImportedClasses(className));
749 }
750
751 }