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