1 package org.apache.river.tool.classdepend;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35 import org.objectweb.asm.AnnotationVisitor;
36 import org.objectweb.asm.ClassVisitor;
37 import org.objectweb.asm.FieldVisitor;
38 import org.objectweb.asm.Label;
39 import org.objectweb.asm.MethodVisitor;
40 import org.objectweb.asm.Opcodes;
41 import org.objectweb.asm.Type;
42 import org.objectweb.asm.signature.SignatureReader;
43 import org.objectweb.asm.signature.SignatureVisitor;
44
45
46
47
48
49 abstract class AbstractDependencyVisitor extends ClassVisitor {
50
51 AbstractDependencyVisitor() {
52 super(Opcodes.ASM5);
53 }
54
55 abstract protected void addName(String name);
56
57
58
59 @Override
60 public void visit(int version, int access, String name, String signature,
61 String superName, String[] interfaces)
62 {
63 if (signature == null) {
64 addNameInternal(superName, false);
65 addNames(interfaces);
66 } else {
67 addSignature(signature);
68 }
69 super.visit(version, access, name, signature, superName, interfaces);
70 }
71
72 @Override
73 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
74 addDesc(desc);
75 AnnotationVisitor ann = super.visitAnnotation(desc, visible);
76 if (ann != null) return new AnnotationVisit(Opcodes.ASM5, ann);
77 return null;
78 }
79
80 @Override
81 public FieldVisitor visitField(int access, String name, String desc,
82 String signature, Object value)
83 {
84 if (signature == null) {
85 addDesc(desc);
86 } else {
87 addTypeSignature(signature);
88 }
89 if (value instanceof Type) {
90 addType((Type) value);
91 }
92 return super.visitField(access, name, desc, signature, value);
93 }
94
95 @Override
96 public MethodVisitor visitMethod(int access, String name, String desc,
97 String signature, String[] exceptions)
98 {
99 if (signature == null) {
100 addMethodDesc(desc);
101 } else {
102 addSignature(signature);
103 }
104 addNames(exceptions);
105 return new MethodVisit(Opcodes.ASM5, super.visitMethod(api, desc, desc, desc, exceptions));
106 }
107
108 @Override
109 public void visitInnerClass(String name, String outerName,
110 String innerName, int access)
111 {
112
113
114 addNameInternal(outerName, false);
115 addNameInternal(name, false);
116 super.visitInnerClass(name, outerName, innerName, access);
117 }
118
119
120
121 private void addNameInternal(String name, boolean transientField) {
122 if (name != null) {
123 addName(name.replace('/', '.'));
124 }
125 }
126
127 private void addNames(String[] names) {
128 if (names != null) {
129 int l = names.length;
130 for (int i = 0; i < l; i++) {
131 String name = names[i];
132 addNameInternal(name, false);
133 }
134 }
135 }
136
137 private void addDesc(String desc) {
138 addType(Type.getType(desc));
139 }
140
141 private void addMethodDesc(String desc) {
142 addType(Type.getReturnType(desc));
143 Type [] type = Type.getArgumentTypes(desc);
144 int l = type.length;
145 for (int i = 0; i < l; i++) {
146 addType(type[i]);
147 }
148 }
149
150 private void addType(Type t) {
151 switch (t.getSort()) {
152 case Type.ARRAY:
153 addType(t.getElementType());
154 break;
155 case Type.OBJECT:
156 addNameInternal(t.getClassName(), false);
157 break;
158 }
159 }
160
161 private void addSignature(String signature) {
162 new SignatureReader(signature).accept(new SignatureVisit(Opcodes.ASM5));
163 }
164
165 private void addTypeSignature(String signature) {
166 new SignatureReader(signature).acceptType(new SignatureVisit(Opcodes.ASM5));
167 }
168
169
170
171
172 private class AnnotationVisit extends AnnotationVisitor {
173
174 public AnnotationVisit(int i, AnnotationVisitor av) {
175 super(i, av);
176 }
177
178 @Override
179 public void visit(String name, Object value) {
180 if (value instanceof Type) {
181 addType((Type) value);
182 }
183 super.visit(name, value);
184 }
185
186 @Override
187 public void visitEnum(String name, String desc, String value) {
188 addDesc(desc);
189 super.visitEnum(name,desc,value);
190 }
191
192 @Override
193 public AnnotationVisitor visitAnnotation(String name, String desc) {
194 addDesc(desc);
195 AnnotationVisitor ann = super.visitAnnotation(name, desc);
196 if (ann != null) return new AnnotationVisit( Opcodes.ASM5, ann);
197 return null;
198 }
199
200 }
201
202
203
204
205
206 private class MethodVisit extends MethodVisitor {
207
208 public MethodVisit(int i, MethodVisitor mv) {
209 super(i, mv);
210 }
211
212 @Override
213 public AnnotationVisitor visitParameterAnnotation(int parameter,
214 String desc,
215 boolean visible)
216 {
217 addDesc(desc);
218 AnnotationVisitor ann = super.visitParameterAnnotation(parameter, desc, visible);
219 if (ann != null) return new AnnotationVisit(Opcodes.ASM5, ann );
220 return null;
221 }
222 @Override
223 public void visitTypeInsn(int opcode, String desc) {
224 if (desc.charAt(0) == '[') {
225 addDesc(desc);
226 } else {
227 addNameInternal(desc, false);
228 }
229 super.visitTypeInsn(opcode, desc);
230 }
231
232 @Override
233 public void visitFieldInsn(int opcode, String owner, String name,
234 String desc)
235 {
236 addNameInternal(owner, false);
237 addDesc(desc);
238 super.visitFieldInsn(opcode, owner, name, desc);
239 }
240
241 String pattern = "^\\[{0,2}L{0,1}(\\w+[/.]{1}[\\w$\\d/.]+);{0,1}$";
242 Pattern arrayOfObjects = Pattern.compile(pattern);
243 @Override
244 public void visitMethodInsn(int opcode, String owner, String name,
245 String desc, boolean itf)
246 {
247
248
249
250
251
252
253
254
255
256
257
258 Matcher match = arrayOfObjects.matcher(owner);
259 while (match.find()){
260 String object = match.group(1);
261 addNameInternal(object, false);
262 }
263 addMethodDesc(desc);
264 super.visitMethodInsn(opcode, owner, name, desc, itf);
265 }
266
267 @Override
268 public void visitLdcInsn(Object cst) {
269 if (cst instanceof Type) {
270 addType((Type) cst);
271 }
272 super.visitLdcInsn(cst);
273 }
274
275 @Override
276 public void visitMultiANewArrayInsn(String desc, int dims) {
277 addDesc(desc);
278 super.visitMultiANewArrayInsn(desc,dims);
279 }
280
281 @Override
282 public void visitLocalVariable(String name, String desc, String signature,
283 Label start, Label end, int index)
284 {
285 if (signature != null) {
286 addTypeSignature(signature);
287 }
288 super.visitLocalVariable(name, desc, signature, start, end, index);
289 }
290
291 @Override
292 public void visitTryCatchBlock(Label start, Label end, Label handler,
293 String type)
294 {
295 addNameInternal(type, false);
296 super.visitTryCatchBlock(start, end, handler, type);
297 }
298 }
299
300
301
302
303 private class SignatureVisit extends SignatureVisitor {
304
305 public SignatureVisit(int i) {
306 super(i);
307 }
308
309 @Override
310 public void visitTypeVariable(String name) {
311
312
313 super.visitTypeVariable(name);
314 }
315
316 @Override
317 public void visitClassType(String name) {
318 addNameInternal(name, false);
319 super.visitClassType(name);
320 }
321
322 @Override
323 public void visitInnerClassType(String name) {
324
325 super.visitInnerClassType(name);
326 }
327
328 }
329 }