KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > typeresolution > visitors > PMDASMVisitor


1 /**
2  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3  */

4 package net.sourceforge.pmd.typeresolution.visitors;
5
6 import org.objectweb.asm.AnnotationVisitor;
7 import org.objectweb.asm.Attribute;
8 import org.objectweb.asm.ClassVisitor;
9 import org.objectweb.asm.FieldVisitor;
10 import org.objectweb.asm.Label;
11 import org.objectweb.asm.MethodVisitor;
12 import org.objectweb.asm.Type;
13 import org.objectweb.asm.signature.SignatureReader;
14 import org.objectweb.asm.signature.SignatureVisitor;
15
16 import java.util.ArrayList JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20
21 public class PMDASMVisitor implements ClassVisitor {
22
23     private Map JavaDoc packages = new HashMap JavaDoc();
24
25     private AnnotationVisitor annotationVisitor = new PMDAnnotationVisitor(this);
26
27     private FieldVisitor fieldVisitor = new PMDFieldVisitor(this);
28
29     private SignatureVisitor sigVisitor = new PMDSignatureVisitor(this);
30
31     private MethodVisitor methodVisitor = new PMDMethodVisitor(this);
32
33     public List JavaDoc innerClasses;
34
35     public Map JavaDoc getPackages() {
36         return packages;
37     }
38
39     public List JavaDoc getInnerClasses() {
40         return innerClasses;
41     }
42
43     private String JavaDoc parseClassName(String JavaDoc name) {
44         if (name == null) {
45             return null;
46         }
47
48         String JavaDoc className = name;
49         int n = name.lastIndexOf('/');
50         if (n > -1) {
51             className = name.substring(n + 1);
52         }
53         name = name.replace('/', '.');
54         packages.put(className, name);
55         n = className.indexOf('$');
56         if (n > -1) {
57             //TODO I don't think the first one, with Class$Inner is needed - come back and check
58
packages.put(className.substring(n + 1), name);
59             packages.put(className.replace('$', '.'), name);
60         }
61
62         return name;
63     }
64
65     private void parseClassName(String JavaDoc[] names) {
66         if (names != null) {
67             for (int i = 0; i < names.length; i++) {
68                 parseClassName(names[i]);
69             }
70         }
71     }
72
73     private void extractSignature(String JavaDoc sig) {
74         if (sig != null) {
75             new SignatureReader(sig).accept(sigVisitor);
76         }
77     }
78
79     /* Start ClassVisitor implementations */
80
81     public void visit(int version, int access, String JavaDoc name, String JavaDoc sig, String JavaDoc superName, String JavaDoc[] interfaces) {
82         parseClassName(name);
83         parseClassName(interfaces);
84         if (sig != null) {
85             extractSignature(sig);
86         }
87     }
88
89     public AnnotationVisitor visitAnnotation(String JavaDoc desc, boolean visible) {
90         addType(Type.getType(desc));
91         return annotationVisitor;
92     }
93
94     public FieldVisitor visitField(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc sig, Object JavaDoc value) {
95         if (sig != null) {
96             extractSignature(sig);
97         }
98
99         addType(Type.getType(desc));
100         if (value instanceof Type) {
101             addType((Type) value);
102         }
103         return fieldVisitor;
104     }
105
106     public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc sig, String JavaDoc[] exceptions) {
107         if (sig != null) {
108             extractSignature(sig);
109         }
110         addMethodDesc(desc);
111         parseClassName(exceptions);
112         return methodVisitor;
113     }
114
115     public void visitSource(String JavaDoc source, String JavaDoc debug) {
116     }
117
118     public void visitInnerClass(String JavaDoc name, String JavaDoc outerName, String JavaDoc innerName, int access) {
119         if (innerClasses == null) {
120             innerClasses = new ArrayList JavaDoc();
121         }
122         if (!innerClasses.contains(name.replace('/', '.'))) {
123             innerClasses.add(name.replace('/', '.'));
124         }
125         packages.put(innerName, name.replace('/', '.'));
126     }
127
128     public void visitOuterClass(String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
129     }
130
131     public void visitEnd() {
132     }
133
134     private void addMethodDesc(String JavaDoc desc) {
135         addTypes(desc);
136         addType(Type.getReturnType(desc));
137     }
138
139     private void addTypes(String JavaDoc desc) {
140         Type[] types = Type.getArgumentTypes(desc);
141         for (int i = 0; i < types.length; i++) {
142             addType(types[i]);
143         }
144     }
145
146     private void addType(Type t) {
147         switch (t.getSort()) {
148         case Type.ARRAY:
149             addType(t.getElementType());
150             break;
151         case Type.OBJECT:
152             parseClassName(t.getClassName().replace('.', '/'));
153             break;
154         }
155     }
156
157     public void visitAttribute(Attribute attr) {
158     }
159
160     /*
161      * Start visitors
162      */

163
164     private static class PMDFieldVisitor implements FieldVisitor {
165
166         private PMDASMVisitor parent;
167
168         public PMDFieldVisitor(PMDASMVisitor visitor) {
169             parent = visitor;
170         }
171
172         public AnnotationVisitor visitAnnotation(String JavaDoc desc, boolean visible) {
173             parent.addType(Type.getType(desc));
174             return parent.annotationVisitor;
175         }
176
177         public void visitAttribute(Attribute attr) {
178         }
179
180         public void visitEnd() {
181         }
182     }
183
184     private static class PMDAnnotationVisitor implements AnnotationVisitor {
185         private PMDASMVisitor parent;
186
187         public PMDAnnotationVisitor(PMDASMVisitor visitor) {
188             parent = visitor;
189         }
190
191         public AnnotationVisitor visitAnnotation(String JavaDoc name, String JavaDoc desc) {
192             parent.addType(Type.getType(desc));
193             return this;
194         }
195
196         public void visitEnum(String JavaDoc name, String JavaDoc desc, String JavaDoc value) {
197             parent.addType(Type.getType(desc));
198         }
199
200         public AnnotationVisitor visitArray(String JavaDoc name) {
201             return this;
202         }
203
204         public void visitEnd() {
205         }
206
207         public void visit(String JavaDoc name, Object JavaDoc value) {
208             if (value instanceof Type) {
209                 parent.addType((Type) value);
210             }
211         }
212     }
213
214     private static class PMDSignatureVisitor implements SignatureVisitor {
215         private PMDASMVisitor parent;
216
217         public PMDSignatureVisitor(PMDASMVisitor visitor) {
218             this.parent = visitor;
219         }
220
221         public void visitFormalTypeParameter(String JavaDoc name) {
222         }
223
224         public SignatureVisitor visitClassBound() {
225             return this;
226         }
227
228         public SignatureVisitor visitInterfaceBound() {
229             return this;
230         }
231
232         public SignatureVisitor visitSuperclass() {
233             return this;
234         }
235
236         public SignatureVisitor visitInterface() {
237             return this;
238         }
239
240         public SignatureVisitor visitParameterType() {
241             return this;
242         }
243
244         public SignatureVisitor visitReturnType() {
245             return this;
246         }
247
248         public SignatureVisitor visitExceptionType() {
249             return this;
250         }
251
252         public void visitBaseType(char descriptor) {
253         }
254
255         public void visitTypeVariable(String JavaDoc name) {
256         }
257
258         public SignatureVisitor visitArrayType() {
259             return this;
260         }
261
262         public void visitClassType(String JavaDoc name) {
263             parent.parseClassName(name);
264         }
265
266         public void visitInnerClassType(String JavaDoc name) {
267             parent.parseClassName(name);
268         }
269
270         public void visitTypeArgument() {
271         }
272
273         public SignatureVisitor visitTypeArgument(char wildcard) {
274             return this;
275         }
276
277         public void visitEnd() {
278         }
279     }
280
281     private static class PMDMethodVisitor implements MethodVisitor {
282         private PMDASMVisitor parent;
283
284         public PMDMethodVisitor(PMDASMVisitor visitor) {
285             parent = visitor;
286         }
287
288         public AnnotationVisitor visitParameterAnnotation(int parameter, String JavaDoc desc, boolean visible) {
289             parent.addType(Type.getType(desc));
290             return parent.annotationVisitor;
291         }
292
293         public AnnotationVisitor visitAnnotation(String JavaDoc name, String JavaDoc desc) {
294             parent.addType(Type.getType(desc));
295             return parent.annotationVisitor;
296         }
297
298         public void visitTypeInsn(int opcode, String JavaDoc desc) {
299             if (desc.charAt(0) == '[') {
300                 parent.addType(Type.getType(desc));
301             } else {
302                 parent.parseClassName(desc);
303             }
304         }
305
306         public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
307             parent.parseClassName(owner);
308             parent.addType(Type.getType(desc));
309         }
310
311         public void visitMethodInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
312             parent.parseClassName(owner);
313             parent.addMethodDesc(desc);
314         }
315
316         /**
317          * the constant to be loaded on the stack. This parameter must be a non null
318          * Integer, a Float, a Long, a Double a String (or a Type for .class
319          * constants, for classes whose version is 49.0 or more).
320          *
321          * @see org.objectweb.asm.MethodVisitor#visitLdcInsn(java.lang.Object)
322          */

323         public void visitLdcInsn(Object JavaDoc cst) {
324             if (cst instanceof Type) {
325                 parent.addType((Type) cst);
326             } else if (cst instanceof String JavaDoc) {
327                 parent.parseClassName((String JavaDoc) cst);
328             }
329         }
330         public void visitMultiANewArrayInsn(String JavaDoc desc, int dims) {
331             parent.addType(Type.getType(desc));
332         }
333
334         public void visitLocalVariable(String JavaDoc name, String JavaDoc desc, String JavaDoc sig, Label start, Label end, int index) {
335             parent.extractSignature(sig);
336         }
337
338         public void visitCode() {
339         }
340
341         public void visitFrame(int type, int nLocal, Object JavaDoc[] local, int nStack, Object JavaDoc[] stack) {
342         }
343
344         public void visitInsn(int opcode) {
345         }
346
347         public void visitIntInsn(int opcode, int operand) {
348         }
349
350         public void visitVarInsn(int opcode, int var) {
351         }
352
353         public void visitJumpInsn(int opcode, Label label) {
354         }
355
356         public void visitLabel(Label label) {
357         }
358
359         public void visitIincInsn(int var, int increment) {
360         }
361
362         public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
363         }
364
365         public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
366         }
367
368         public void visitTryCatchBlock(Label start, Label end, Label handler, String JavaDoc type) {
369             parent.parseClassName(type);
370         }
371
372         public void visitLineNumber(int line, Label start) {
373         }
374
375         public void visitMaxs(int maxStack, int maxLocals) {
376         }
377
378         public AnnotationVisitor visitAnnotationDefault() {
379             return parent.annotationVisitor;
380         }
381
382         public AnnotationVisitor visitAnnotation(String JavaDoc desc, boolean visible) {
383             parent.addType(Type.getType(desc));
384             return parent.annotationVisitor;
385         }
386
387         public void visitEnd() {
388         }
389
390         public void visitAttribute(Attribute attr) {
391         }
392
393     }
394 }
Popular Tags