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