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