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