1 |
| |
2 |
| |
3 |
| |
4 |
| package net.sourceforge.pmd.typeresolution; |
5 |
| |
6 |
| import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration; |
7 |
| import net.sourceforge.pmd.ast.ASTClassOrInterfaceType; |
8 |
| import net.sourceforge.pmd.ast.ASTCompilationUnit; |
9 |
| import net.sourceforge.pmd.ast.ASTImportDeclaration; |
10 |
| import net.sourceforge.pmd.ast.ASTName; |
11 |
| import net.sourceforge.pmd.ast.ASTPackageDeclaration; |
12 |
| import net.sourceforge.pmd.ast.JavaParserVisitorAdapter; |
13 |
| |
14 |
| import java.util.Collections; |
15 |
| import java.util.HashMap; |
16 |
| import java.util.Iterator; |
17 |
| import java.util.List; |
18 |
| import java.util.Map; |
19 |
| |
20 |
| public class ClassTypeResolver extends JavaParserVisitorAdapter { |
21 |
| |
22 |
| private static Map myPrimitiveTypes; |
23 |
| |
24 |
| private static PMDASMClassLoader pmdClassLoader = new PMDASMClassLoader(); |
25 |
| |
26 |
| static { |
27 |
2
| Map thePrimitiveTypes = new HashMap();
|
28 |
2
| thePrimitiveTypes.put("short", Short.TYPE);
|
29 |
2
| thePrimitiveTypes.put("byte", Byte.TYPE);
|
30 |
2
| thePrimitiveTypes.put("char", Character.TYPE);
|
31 |
2
| thePrimitiveTypes.put("int", Integer.TYPE);
|
32 |
2
| thePrimitiveTypes.put("long", Long.TYPE);
|
33 |
2
| thePrimitiveTypes.put("float", Float.TYPE);
|
34 |
2
| thePrimitiveTypes.put("double", Double.TYPE);
|
35 |
2
| thePrimitiveTypes.put("boolean", Boolean.TYPE);
|
36 |
2
| thePrimitiveTypes.put("void", Void.TYPE);
|
37 |
2
| myPrimitiveTypes = Collections.unmodifiableMap(thePrimitiveTypes);
|
38 |
| } |
39 |
| |
40 |
| private Map importedClasses; |
41 |
| |
42 |
| private String className; |
43 |
| |
44 |
18
| public Object visit(ASTCompilationUnit node, Object data) {
|
45 |
18
| try {
|
46 |
18
| populateClassName(node);
|
47 |
| } catch (ClassNotFoundException e) { |
48 |
18
| populateImports(node);
|
49 |
| } |
50 |
18
| return super.visit(node, data);
|
51 |
| } |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| |
57 |
| |
58 |
18
| private void populateImports(ASTCompilationUnit node) {
|
59 |
18
| List theImportDeclarations = node.findChildrenOfType(ASTImportDeclaration.class);
|
60 |
18
| importedClasses = new HashMap();
|
61 |
| |
62 |
| |
63 |
18
| for (Iterator anIterator = theImportDeclarations.iterator(); anIterator.hasNext();) {
|
64 |
13
| ASTImportDeclaration anImportDeclaration = (ASTImportDeclaration) anIterator.next();
|
65 |
13
| if (!anImportDeclaration.isImportOnDemand()) {
|
66 |
10
| String strPackage = anImportDeclaration.getPackageName();
|
67 |
10
| String strName = anImportDeclaration.getImportedName();
|
68 |
10
| importedClasses.put(strName, strName);
|
69 |
10
| importedClasses.put(strName.substring(strPackage.length() + 1), strName);
|
70 |
| } |
71 |
| } |
72 |
| |
73 |
18
| importedClasses.put("String", "java.lang.String");
|
74 |
18
| importedClasses.put("Object", "java.lang.Object");
|
75 |
| } |
76 |
| |
77 |
18
| private void populateClassName(ASTCompilationUnit node) throws ClassNotFoundException {
|
78 |
18
| ASTClassOrInterfaceDeclaration decl = (ASTClassOrInterfaceDeclaration) node
|
79 |
| .getFirstChildOfType(ASTClassOrInterfaceDeclaration.class); |
80 |
18
| if (decl != null) {
|
81 |
18
| ASTPackageDeclaration pkgDecl = (ASTPackageDeclaration) node
|
82 |
| .getFirstChildOfType(ASTPackageDeclaration.class); |
83 |
18
| className = pkgDecl == null ? decl.getImage() : ((ASTName) pkgDecl.jjtGetChild(0)).getImage() + "."
|
84 |
| + decl.getImage(); |
85 |
18
| pmdClassLoader.loadClass(className);
|
86 |
0
| importedClasses = pmdClassLoader.getImportedClasses(className);
|
87 |
| } |
88 |
| } |
89 |
| |
90 |
28
| public Object visit(ASTClassOrInterfaceType node, Object data) {
|
91 |
| |
92 |
28
| String className = node.getImage();
|
93 |
28
| String qualifiedName = className;
|
94 |
28
| Class myType = (Class) myPrimitiveTypes.get(className);
|
95 |
28
| if (myType == null && importedClasses != null) {
|
96 |
28
| if (importedClasses.containsKey(className)) {
|
97 |
17
| qualifiedName = (String) importedClasses.get(className);
|
98 |
11
| } else if (importedClasses.containsValue(className)) {
|
99 |
0
| qualifiedName = className;
|
100 |
| } |
101 |
28
| if (qualifiedName != null) {
|
102 |
28
| try {
|
103 |
| |
104 |
| |
105 |
| |
106 |
| |
107 |
| |
108 |
28
| myType = pmdClassLoader.loadClass(qualifiedName);
|
109 |
| } catch (ClassNotFoundException e) { |
110 |
| |
111 |
| } |
112 |
| } |
113 |
| } |
114 |
28
| if (myType != null) {
|
115 |
20
| node.setType(myType);
|
116 |
| } |
117 |
28
| return data;
|
118 |
| } |
119 |
| } |