1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.util.Objects;
20 import java.util.Stack;
21 import java.util.stream.Stream;
22
23
24
25
26
27 public class DescendingVisitor implements Visitor {
28 private final JavaClass clazz;
29
30 private final Visitor visitor;
31
32 private final Stack<Object> stack = new Stack<>();
33
34
35
36
37
38 public DescendingVisitor(final JavaClass clazz, final Visitor visitor) {
39 this.clazz = clazz;
40 this.visitor = visitor;
41 }
42
43 private <E extends Node> void accept(final E[] node) {
44 Stream.of(node).forEach(e -> e.accept(this));
45 }
46
47
48
49
50 public Object current() {
51 return stack.peek();
52 }
53
54
55
56
57 public Object predecessor() {
58 return predecessor(0);
59 }
60
61
62
63
64
65 public Object predecessor(final int level) {
66 final int size = stack.size();
67 if (size < 2 || level < 0) {
68 return null;
69 }
70 return stack.elementAt(size - (level + 2));
71 }
72
73
74
75
76 public void visit() {
77 clazz.accept(this);
78 }
79
80
81
82
83 @Override
84 public void visitAnnotation(final Annotations annotation) {
85 stack.push(annotation);
86 annotation.accept(visitor);
87 accept(annotation.getAnnotationEntries());
88 stack.pop();
89 }
90
91
92
93
94 @Override
95 public void visitAnnotationDefault(final AnnotationDefault obj) {
96 stack.push(obj);
97 obj.accept(visitor);
98 stack.pop();
99 }
100
101
102
103
104 @Override
105 public void visitAnnotationEntry(final AnnotationEntry annotationEntry) {
106 stack.push(annotationEntry);
107 annotationEntry.accept(visitor);
108 stack.pop();
109 }
110
111
112
113
114 @Override
115 public void visitBootstrapMethods(final BootstrapMethods bm) {
116 stack.push(bm);
117 bm.accept(visitor);
118
119
120
121
122
123 stack.pop();
124 }
125
126 @Override
127 public void visitCode(final Code code) {
128 stack.push(code);
129 code.accept(visitor);
130 accept(code.getExceptionTable());
131 accept(code.getAttributes());
132 stack.pop();
133 }
134
135 @Override
136 public void visitCodeException(final CodeException ce) {
137 stack.push(ce);
138 ce.accept(visitor);
139 stack.pop();
140 }
141
142 @Override
143 public void visitConstantClass(final ConstantClass constant) {
144 stack.push(constant);
145 constant.accept(visitor);
146 stack.pop();
147 }
148
149 @Override
150 public void visitConstantDouble(final ConstantDouble constant) {
151 stack.push(constant);
152 constant.accept(visitor);
153 stack.pop();
154 }
155
156
157 @Override
158 public void visitConstantDynamic(final ConstantDynamic obj) {
159 stack.push(obj);
160 obj.accept(visitor);
161 stack.pop();
162 }
163
164 @Override
165 public void visitConstantFieldref(final ConstantFieldref constant) {
166 stack.push(constant);
167 constant.accept(visitor);
168 stack.pop();
169 }
170
171 @Override
172 public void visitConstantFloat(final ConstantFloat constant) {
173 stack.push(constant);
174 constant.accept(visitor);
175 stack.pop();
176 }
177
178 @Override
179 public void visitConstantInteger(final ConstantInteger constant) {
180 stack.push(constant);
181 constant.accept(visitor);
182 stack.pop();
183 }
184
185 @Override
186 public void visitConstantInterfaceMethodref(final ConstantInterfaceMethodref constant) {
187 stack.push(constant);
188 constant.accept(visitor);
189 stack.pop();
190 }
191
192
193
194
195 @Override
196 public void visitConstantInvokeDynamic(final ConstantInvokeDynamic constant) {
197 stack.push(constant);
198 constant.accept(visitor);
199 stack.pop();
200 }
201
202 @Override
203 public void visitConstantLong(final ConstantLong constant) {
204 stack.push(constant);
205 constant.accept(visitor);
206 stack.pop();
207 }
208
209
210 @Override
211 public void visitConstantMethodHandle(final ConstantMethodHandle obj) {
212 stack.push(obj);
213 obj.accept(visitor);
214 stack.pop();
215 }
216
217 @Override
218 public void visitConstantMethodref(final ConstantMethodref constant) {
219 stack.push(constant);
220 constant.accept(visitor);
221 stack.pop();
222 }
223
224
225 @Override
226 public void visitConstantMethodType(final ConstantMethodType obj) {
227 stack.push(obj);
228 obj.accept(visitor);
229 stack.pop();
230 }
231
232
233 @Override
234 public void visitConstantModule(final ConstantModule obj) {
235 stack.push(obj);
236 obj.accept(visitor);
237 stack.pop();
238 }
239
240 @Override
241 public void visitConstantNameAndType(final ConstantNameAndType constant) {
242 stack.push(constant);
243 constant.accept(visitor);
244 stack.pop();
245 }
246
247
248 @Override
249 public void visitConstantPackage(final ConstantPackage obj) {
250 stack.push(obj);
251 obj.accept(visitor);
252 stack.pop();
253 }
254
255 @Override
256 public void visitConstantPool(final ConstantPool cp) {
257 stack.push(cp);
258 cp.accept(visitor);
259 Stream.of(cp.getConstantPool()).filter(Objects::nonNull).forEach(e -> e.accept(this));
260 stack.pop();
261 }
262
263 @Override
264 public void visitConstantString(final ConstantString constant) {
265 stack.push(constant);
266 constant.accept(visitor);
267 stack.pop();
268 }
269
270 @Override
271 public void visitConstantUtf8(final ConstantUtf8 constant) {
272 stack.push(constant);
273 constant.accept(visitor);
274 stack.pop();
275 }
276
277 @Override
278 public void visitConstantValue(final ConstantValue cv) {
279 stack.push(cv);
280 cv.accept(visitor);
281 stack.pop();
282 }
283
284 @Override
285 public void visitDeprecated(final Deprecated attribute) {
286 stack.push(attribute);
287 attribute.accept(visitor);
288 stack.pop();
289 }
290
291
292
293
294 @Override
295 public void visitEnclosingMethod(final EnclosingMethod obj) {
296 stack.push(obj);
297 obj.accept(visitor);
298 stack.pop();
299 }
300
301 @Override
302 public void visitExceptionTable(final ExceptionTable table) {
303 stack.push(table);
304 table.accept(visitor);
305 stack.pop();
306 }
307
308 @Override
309 public void visitField(final Field field) {
310 stack.push(field);
311 field.accept(visitor);
312 accept(field.getAttributes());
313 stack.pop();
314 }
315
316 @Override
317 public void visitInnerClass(final InnerClass inner) {
318 stack.push(inner);
319 inner.accept(visitor);
320 stack.pop();
321 }
322
323 @Override
324 public void visitInnerClasses(final InnerClasses ic) {
325 stack.push(ic);
326 ic.accept(visitor);
327 accept(ic.getInnerClasses());
328 stack.pop();
329 }
330
331 @Override
332 public void visitJavaClass(final JavaClass clazz) {
333 stack.push(clazz);
334 clazz.accept(visitor);
335 accept(clazz.getFields());
336 accept(clazz.getMethods());
337 accept(clazz.getAttributes());
338 clazz.getConstantPool().accept(this);
339 stack.pop();
340 }
341
342 @Override
343 public void visitLineNumber(final LineNumber number) {
344 stack.push(number);
345 number.accept(visitor);
346 stack.pop();
347 }
348
349 @Override
350 public void visitLineNumberTable(final LineNumberTable table) {
351 stack.push(table);
352 table.accept(visitor);
353 accept(table.getLineNumberTable());
354 stack.pop();
355 }
356
357 @Override
358 public void visitLocalVariable(final LocalVariable var) {
359 stack.push(var);
360 var.accept(visitor);
361 stack.pop();
362 }
363
364 @Override
365 public void visitLocalVariableTable(final LocalVariableTable table) {
366 stack.push(table);
367 table.accept(visitor);
368 accept(table.getLocalVariableTable());
369 stack.pop();
370 }
371
372
373
374
375 @Override
376 public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) {
377 stack.push(obj);
378 obj.accept(visitor);
379 stack.pop();
380 }
381
382 @Override
383 public void visitMethod(final Method method) {
384 stack.push(method);
385 method.accept(visitor);
386 accept(method.getAttributes());
387 stack.pop();
388 }
389
390
391
392
393 @Override
394 public void visitMethodParameter(final MethodParameter obj) {
395 stack.push(obj);
396 obj.accept(visitor);
397 stack.pop();
398 }
399
400
401
402
403 @Override
404 public void visitMethodParameters(final MethodParameters obj) {
405 stack.push(obj);
406 obj.accept(visitor);
407 Stream.of(obj.getParameters()).forEach(e -> e.accept(this));
408 stack.pop();
409 }
410
411
412 @Override
413 public void visitModule(final Module obj) {
414 stack.push(obj);
415 obj.accept(visitor);
416 accept(obj.getRequiresTable());
417 accept(obj.getExportsTable());
418 accept(obj.getOpensTable());
419 accept(obj.getProvidesTable());
420 stack.pop();
421 }
422
423
424 @Override
425 public void visitModuleExports(final ModuleExports obj) {
426 stack.push(obj);
427 obj.accept(visitor);
428 stack.pop();
429 }
430
431
432 @Override
433 public void visitModuleMainClass(final ModuleMainClass obj) {
434 stack.push(obj);
435 obj.accept(visitor);
436 stack.pop();
437 }
438
439
440 @Override
441 public void visitModuleOpens(final ModuleOpens obj) {
442 stack.push(obj);
443 obj.accept(visitor);
444 stack.pop();
445 }
446
447
448 @Override
449 public void visitModulePackages(final ModulePackages obj) {
450 stack.push(obj);
451 obj.accept(visitor);
452 stack.pop();
453 }
454
455
456 @Override
457 public void visitModuleProvides(final ModuleProvides obj) {
458 stack.push(obj);
459 obj.accept(visitor);
460 stack.pop();
461 }
462
463
464 @Override
465 public void visitModuleRequires(final ModuleRequires obj) {
466 stack.push(obj);
467 obj.accept(visitor);
468 stack.pop();
469 }
470
471
472 @Override
473 public void visitNestHost(final NestHost obj) {
474 stack.push(obj);
475 obj.accept(visitor);
476 stack.pop();
477 }
478
479
480 @Override
481 public void visitNestMembers(final NestMembers obj) {
482 stack.push(obj);
483 obj.accept(visitor);
484 stack.pop();
485 }
486
487
488
489
490 @Override
491 public void visitParameterAnnotation(final ParameterAnnotations obj) {
492 stack.push(obj);
493 obj.accept(visitor);
494 stack.pop();
495 }
496
497
498 @Override
499 public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) {
500 stack.push(obj);
501 obj.accept(visitor);
502 stack.pop();
503 }
504
505 @Override
506 public void visitSignature(final Signature attribute) {
507 stack.push(attribute);
508 attribute.accept(visitor);
509 stack.pop();
510 }
511
512 @Override
513 public void visitSourceFile(final SourceFile attribute) {
514 stack.push(attribute);
515 attribute.accept(visitor);
516 stack.pop();
517 }
518
519 @Override
520 public void visitStackMap(final StackMap table) {
521 stack.push(table);
522 table.accept(visitor);
523 accept(table.getStackMap());
524 stack.pop();
525 }
526
527 @Override
528 public void visitStackMapEntry(final StackMapEntry var) {
529 stack.push(var);
530 var.accept(visitor);
531 accept(var.getTypesOfLocals());
532 accept(var.getTypesOfStackItems());
533 stack.pop();
534 }
535
536
537
538
539
540
541 @Override
542 public void visitStackMapType(final StackMapType var) {
543 stack.push(var);
544 var.accept(visitor);
545 stack.pop();
546 }
547
548 @Override
549 public void visitSynthetic(final Synthetic attribute) {
550 stack.push(attribute);
551 attribute.accept(visitor);
552 stack.pop();
553 }
554
555 @Override
556 public void visitUnknown(final Unknown attribute) {
557 stack.push(attribute);
558 attribute.accept(visitor);
559 stack.pop();
560 }
561 }