Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 119 |  | Methods: | 4
| NCLOC: | 89 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
ClassTypeResolver.java | 72.2% | 95.7% | 100% | 89.7% |

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
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 |  | * If the outer class wasn't found then we'll get in here
55 |  | *
56 |  | * @param node
57 |  | */
58 | 18 | private void populateImports(ASTCompilationUnit node) {
59 | 18 | List theImportDeclarations = node.findChildrenOfType(ASTImportDeclaration.class);
60 | 18 | importedClasses = new HashMap();
61 |  |
62 |  | // go through the imports
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 |  | * TODO - the map right now contains just class names. if we use a map of
105 |  | * classname/class then we don't have to hit the class loader for every type -
106 |  | * much faster
107 |  | */
108 | 28 | myType = pmdClassLoader.loadClass(qualifiedName);
109 |  | } catch (ClassNotFoundException e) {
110 |  | //@TODO What should we do if it's not found?
111 |  | }
112 |  | }
113 |  | }
114 | 28 | if (myType != null) {
115 | 20 | node.setType(myType);
116 |  | }
117 | 28 | return data;
118 |  | }
119 |  | }