Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 172 |  | Methods: | 17
| NCLOC: | 130 |  | Classes: | 9
Source file | Conditionals | Statements | Methods | TOTAL
TypeSet.java | 87.5% | 98% | 100% | 96.4% |

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 |  | */
4 |  | package net.sourceforge.pmd.symboltable;
5 |  |
6 |  | import java.util.ArrayList;
7 |  | import java.util.HashMap;
8 |  | import java.util.HashSet;
9 |  | import java.util.Iterator;
10 |  | import java.util.List;
11 |  | import java.util.Map;
12 |  | import java.util.Set;
13 |  |
14 |  | /**
15 |  | * Keeps track of the types encountered in a ASTCompilationUnit
16 |  | */
17 |  | public class TypeSet {
18 |  |
19 |  |
20 |  | /**
21 |  | * TODO should Resolver provide a canResolve() and a resolve()?
22 |  | * Requiring 2 calls seems clunky... but so does this
23 |  | * throwing an exception for flow control...
24 |  | */
25 |  | public interface Resolver {
26 |  | Class resolve(String name) throws ClassNotFoundException;
27 |  | }
28 |  |
29 |  | public static class ExplicitImportResolver implements Resolver {
30 |  | private Set importStmts;
31 |  |
32 | 8 | public ExplicitImportResolver(Set importStmts) {
33 | 8 | this.importStmts = importStmts;
34 |  | }
35 |  |
36 | 7 | public Class resolve(String name) throws ClassNotFoundException {
37 | 7 | for (Iterator i = importStmts.iterator(); i.hasNext();) {
38 | 3 | String importStmt = (String) i.next();
39 | 3 | if (importStmt.endsWith(name)) {
40 | 2 | return Class.forName(importStmt);
41 |  | }
42 |  | }
43 | 5 | throw new ClassNotFoundException("Type " + name + " not found");
44 |  | }
45 |  | }
46 |  |
47 |  | public static class CurrentPackageResolver implements Resolver {
48 |  | private String pkg;
49 |  |
50 | 8 | public CurrentPackageResolver(String pkg) {
51 | 8 | this.pkg = pkg;
52 |  | }
53 |  |
54 | 6 | public Class resolve(String name) throws ClassNotFoundException {
55 | 6 | return Class.forName(pkg + name);
56 |  | }
57 |  | }
58 |  |
59 |  | // TODO cite the JLS section on implicit imports
60 |  | public static class ImplicitImportResolver implements Resolver {
61 | 6 | public Class resolve(String name) throws ClassNotFoundException {
62 | 6 | return Class.forName("java.lang." + name);
63 |  | }
64 |  | }
65 |  |
66 |  | public static class ImportOnDemandResolver implements Resolver {
67 |  | private Set importStmts;
68 |  |
69 | 9 | public ImportOnDemandResolver(Set importStmts) {
70 | 9 | this.importStmts = importStmts;
71 |  | }
72 |  |
73 | 7 | public Class resolve(String name) throws ClassNotFoundException {
74 | 7 | for (Iterator i = importStmts.iterator(); i.hasNext();) {
75 | 8 | String importStmt = (String) i.next();
76 | 8 | if (importStmt.endsWith("*")) {
77 | 8 | try {
78 | 8 | String importPkg = importStmt.substring(0, importStmt.indexOf('*') - 1);
79 | 8 | return Class.forName(importPkg + '.' + name);
80 |  | } catch (ClassNotFoundException cnfe) {
81 |  | }
82 |  | }
83 |  | }
84 | 4 | throw new ClassNotFoundException("Type " + name + " not found");
85 |  | }
86 |  | }
87 |  |
88 |  | public static class PrimitiveTypeResolver implements Resolver {
89 |  | private Map primitiveTypes = new HashMap();
90 |  |
91 | 8 | public PrimitiveTypeResolver() {
92 | 8 | primitiveTypes.put("int", int.class);
93 | 8 | primitiveTypes.put("float", float.class);
94 | 8 | primitiveTypes.put("double", double.class);
95 | 8 | primitiveTypes.put("long", long.class);
96 | 8 | primitiveTypes.put("boolean", boolean.class);
97 | 8 | primitiveTypes.put("byte", byte.class);
98 | 8 | primitiveTypes.put("short", short.class);
99 | 8 | primitiveTypes.put("char", char.class);
100 |  | }
101 |  |
102 | 11 | public Class resolve(String name) throws ClassNotFoundException {
103 | 11 | if (!primitiveTypes.containsKey(name)) {
104 | 7 | throw new ClassNotFoundException();
105 |  | }
106 | 4 | return (Class) primitiveTypes.get(name);
107 |  | }
108 |  | }
109 |  |
110 |  | public static class VoidResolver implements Resolver {
111 | 8 | public Class resolve(String name) throws ClassNotFoundException {
112 | 8 | if (name.equals("void")) {
113 | 2 | return void.class;
114 |  | }
115 | 6 | throw new ClassNotFoundException();
116 |  | }
117 |  | }
118 |  |
119 |  | public static class FullyQualifiedNameResolver implements Resolver {
120 | 2 | public Class resolve(String name) throws ClassNotFoundException {
121 | 2 | return Class.forName(name);
122 |  | }
123 |  | }
124 |  |
125 |  | private String pkg;
126 |  | private Set imports = new HashSet();
127 |  | private List resolvers = new ArrayList();
128 |  |
129 | 2 | public void setASTCompilationUnitPackage(String pkg) {
130 | 2 | this.pkg = pkg;
131 |  | }
132 |  |
133 | 1 | public String getASTCompilationUnitPackage() {
134 | 1 | return pkg;
135 |  | }
136 |  |
137 | 3 | public void addImport(String importString) {
138 | 3 | imports.add(importString);
139 |  | }
140 |  |
141 | 1 | public int getImportsCount() {
142 | 1 | return imports.size();
143 |  | }
144 |  |
145 | 8 | public Class findClass(String name) throws ClassNotFoundException {
146 |  | // we don't build the resolvers until now since we first want to get all the imports
147 | 8 | if (resolvers.isEmpty()) {
148 | 7 | buildResolvers();
149 |  | }
150 |  |
151 | 35 | for (Iterator i = resolvers.iterator(); i.hasNext();) {
152 | 35 | Resolver resolver = (Resolver) i.next();
153 | 35 | try {
154 | 35 | return resolver.resolve(name);
155 |  | } catch (ClassNotFoundException cnfe) {
156 |  | }
157 |  | }
158 |  |
159 | 0 | throw new ClassNotFoundException("Type " + name + " not found");
160 |  | }
161 |  |
162 | 7 | private void buildResolvers() {
163 | 7 | resolvers.add(new PrimitiveTypeResolver());
164 | 7 | resolvers.add(new VoidResolver());
165 | 7 | resolvers.add(new ExplicitImportResolver(imports));
166 | 7 | resolvers.add(new CurrentPackageResolver(pkg));
167 | 7 | resolvers.add(new ImplicitImportResolver());
168 | 7 | resolvers.add(new ImportOnDemandResolver(imports));
169 | 7 | resolvers.add(new FullyQualifiedNameResolver());
170 |  | }
171 |  |
172 |  | }