1 /* 2 * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package com.sun.org.apache.bcel.internal.classfile; 21 22 import java.util.Stack; 23 24 /** 25 * Traverses a JavaClass with another Visitor object 'piggy-backed' that is 26 * applied to all components of a JavaClass object. I.e. this class supplies the 27 * traversal strategy, other classes can make use of it. 28 * 29 */ 30 public class DescendingVisitor implements Visitor 31 { 32 private final JavaClass clazz; 33 34 private final Visitor visitor; 35 36 private final Stack<Object> stack = new Stack<>(); 37 38 /** 39 * @return container of current entitity, i.e., predecessor during traversal 40 */ 41 public Object predecessor() 42 { 43 return predecessor(0); 44 } 45 46 /** 47 * @param level 48 * nesting level, i.e., 0 returns the direct predecessor 49 * @return container of current entitity, i.e., predecessor during traversal 50 */ 51 public Object predecessor(final int level) 52 { 53 final int size = stack.size(); 54 if ((size < 2) || (level < 0)) 55 { 56 return null; 57 } 58 return stack.elementAt(size - (level + 2)); // size - 1 == current 59 } 60 61 /** 62 * @return current object 63 */ 64 public Object current() 65 { 66 return stack.peek(); 67 } 68 69 /** 70 * @param clazz 71 * Class to traverse 72 * @param visitor 73 * visitor object to apply to all components 74 */ 75 public DescendingVisitor(final JavaClass clazz, final Visitor visitor) 76 { 77 this.clazz = clazz; 78 this.visitor = visitor; 79 } 80 81 /** 82 * Start traversal. 83 */ 84 public void visit() 85 { 86 clazz.accept(this); 87 } 88 89 @Override 90 public void visitJavaClass(final JavaClass _clazz) 91 { 92 stack.push(_clazz); 93 _clazz.accept(visitor); 94 final Field[] fields = _clazz.getFields(); 95 for (final Field field : fields) { 96 field.accept(this); 97 } 98 final Method[] methods = _clazz.getMethods(); 99 for (final Method method : methods) { 100 method.accept(this); 101 } 102 final Attribute[] attributes = _clazz.getAttributes(); 103 for (final Attribute attribute : attributes) { 104 attribute.accept(this); 105 } 106 _clazz.getConstantPool().accept(this); 107 stack.pop(); 108 } 109 110 /** 111 * @since 6.0 112 */ 113 @Override 114 public void visitAnnotation(final Annotations annotation) 115 { 116 stack.push(annotation); 117 annotation.accept(visitor); 118 final AnnotationEntry[] entries = annotation.getAnnotationEntries(); 119 for (final AnnotationEntry entrie : entries) { 120 entrie.accept(this); 121 } 122 stack.pop(); 123 } 124 125 /** 126 * @since 6.0 127 */ 128 @Override 129 public void visitAnnotationEntry(final AnnotationEntry annotationEntry) 130 { 131 stack.push(annotationEntry); 132 annotationEntry.accept(visitor); 133 stack.pop(); 134 } 135 136 @Override 137 public void visitField(final Field field) 138 { 139 stack.push(field); 140 field.accept(visitor); 141 final Attribute[] attributes = field.getAttributes(); 142 for (final Attribute attribute : attributes) { 143 attribute.accept(this); 144 } 145 stack.pop(); 146 } 147 148 @Override 149 public void visitConstantValue(final ConstantValue cv) 150 { 151 stack.push(cv); 152 cv.accept(visitor); 153 stack.pop(); 154 } 155 156 @Override 157 public void visitMethod(final Method method) 158 { 159 stack.push(method); 160 method.accept(visitor); 161 final Attribute[] attributes = method.getAttributes(); 162 for (final Attribute attribute : attributes) { 163 attribute.accept(this); 164 } 165 stack.pop(); 166 } 167 168 @Override 169 public void visitExceptionTable(final ExceptionTable table) 170 { 171 stack.push(table); 172 table.accept(visitor); 173 stack.pop(); 174 } 175 176 @Override 177 public void visitCode(final Code code) 178 { 179 stack.push(code); 180 code.accept(visitor); 181 final CodeException[] table = code.getExceptionTable(); 182 for (final CodeException element : table) { 183 element.accept(this); 184 } 185 final Attribute[] attributes = code.getAttributes(); 186 for (final Attribute attribute : attributes) { 187 attribute.accept(this); 188 } 189 stack.pop(); 190 } 191 192 @Override 193 public void visitCodeException(final CodeException ce) 194 { 195 stack.push(ce); 196 ce.accept(visitor); 197 stack.pop(); 198 } 199 200 @Override 201 public void visitLineNumberTable(final LineNumberTable table) 202 { 203 stack.push(table); 204 table.accept(visitor); 205 final LineNumber[] numbers = table.getLineNumberTable(); 206 for (final LineNumber number : numbers) { 207 number.accept(this); 208 } 209 stack.pop(); 210 } 211 212 @Override 213 public void visitLineNumber(final LineNumber number) 214 { 215 stack.push(number); 216 number.accept(visitor); 217 stack.pop(); 218 } 219 220 @Override 221 public void visitLocalVariableTable(final LocalVariableTable table) 222 { 223 stack.push(table); 224 table.accept(visitor); 225 final LocalVariable[] vars = table.getLocalVariableTable(); 226 for (final LocalVariable var : vars) { 227 var.accept(this); 228 } 229 stack.pop(); 230 } 231 232 @Override 233 public void visitStackMap(final StackMap table) 234 { 235 stack.push(table); 236 table.accept(visitor); 237 final StackMapEntry[] vars = table.getStackMap(); 238 for (final StackMapEntry var : vars) { 239 var.accept(this); 240 } 241 stack.pop(); 242 } 243 244 @Override 245 public void visitStackMapEntry(final StackMapEntry var) 246 { 247 stack.push(var); 248 var.accept(visitor); 249 stack.pop(); 250 } 251 252 @Override 253 public void visitLocalVariable(final LocalVariable var) 254 { 255 stack.push(var); 256 var.accept(visitor); 257 stack.pop(); 258 } 259 260 @Override 261 public void visitConstantPool(final ConstantPool cp) 262 { 263 stack.push(cp); 264 cp.accept(visitor); 265 final Constant[] constants = cp.getConstantPool(); 266 for (int i = 1; i < constants.length; i++) 267 { 268 if (constants[i] != null) 269 { 270 constants[i].accept(this); 271 } 272 } 273 stack.pop(); 274 } 275 276 @Override 277 public void visitConstantClass(final ConstantClass constant) 278 { 279 stack.push(constant); 280 constant.accept(visitor); 281 stack.pop(); 282 } 283 284 @Override 285 public void visitConstantDouble(final ConstantDouble constant) 286 { 287 stack.push(constant); 288 constant.accept(visitor); 289 stack.pop(); 290 } 291 292 @Override 293 public void visitConstantFieldref(final ConstantFieldref constant) 294 { 295 stack.push(constant); 296 constant.accept(visitor); 297 stack.pop(); 298 } 299 300 @Override 301 public void visitConstantFloat(final ConstantFloat constant) 302 { 303 stack.push(constant); 304 constant.accept(visitor); 305 stack.pop(); 306 } 307 308 @Override 309 public void visitConstantInteger(final ConstantInteger constant) 310 { 311 stack.push(constant); 312 constant.accept(visitor); 313 stack.pop(); 314 } 315 316 @Override 317 public void visitConstantInterfaceMethodref( 318 final ConstantInterfaceMethodref constant) 319 { 320 stack.push(constant); 321 constant.accept(visitor); 322 stack.pop(); 323 } 324 325 /** 326 * @since 6.0 327 */ 328 @Override 329 public void visitConstantInvokeDynamic( 330 final ConstantInvokeDynamic constant) 331 { 332 stack.push(constant); 333 constant.accept(visitor); 334 stack.pop(); 335 } 336 337 @Override 338 public void visitConstantLong(final ConstantLong constant) 339 { 340 stack.push(constant); 341 constant.accept(visitor); 342 stack.pop(); 343 } 344 345 @Override 346 public void visitConstantMethodref(final ConstantMethodref constant) 347 { 348 stack.push(constant); 349 constant.accept(visitor); 350 stack.pop(); 351 } 352 353 @Override 354 public void visitConstantNameAndType(final ConstantNameAndType constant) 355 { 356 stack.push(constant); 357 constant.accept(visitor); 358 stack.pop(); 359 } 360 361 @Override 362 public void visitConstantString(final ConstantString constant) 363 { 364 stack.push(constant); 365 constant.accept(visitor); 366 stack.pop(); 367 } 368 369 @Override 370 public void visitConstantUtf8(final ConstantUtf8 constant) 371 { 372 stack.push(constant); 373 constant.accept(visitor); 374 stack.pop(); 375 } 376 377 @Override 378 public void visitInnerClasses(final InnerClasses ic) 379 { 380 stack.push(ic); 381 ic.accept(visitor); 382 final InnerClass[] ics = ic.getInnerClasses(); 383 for (final InnerClass ic2 : ics) { 384 ic2.accept(this); 385 } 386 stack.pop(); 387 } 388 389 @Override 390 public void visitInnerClass(final InnerClass inner) 391 { 392 stack.push(inner); 393 inner.accept(visitor); 394 stack.pop(); 395 } 396 397 /** 398 * @since 6.0 399 */ 400 @Override 401 public void visitBootstrapMethods(final BootstrapMethods bm) 402 { 403 stack.push(bm); 404 bm.accept(visitor); 405 // BootstrapMethod[] bms = bm.getBootstrapMethods(); 406 // for (int i = 0; i < bms.length; i++) 407 // { 408 // bms[i].accept(this); 409 // } 410 stack.pop(); 411 } 412 413 @Override 414 public void visitDeprecated(final Deprecated attribute) 415 { 416 stack.push(attribute); 417 attribute.accept(visitor); 418 stack.pop(); 419 } 420 421 @Override 422 public void visitSignature(final Signature attribute) 423 { 424 stack.push(attribute); 425 attribute.accept(visitor); 426 stack.pop(); 427 } 428 429 @Override 430 public void visitSourceFile(final SourceFile attribute) 431 { 432 stack.push(attribute); 433 attribute.accept(visitor); 434 stack.pop(); 435 } 436 437 @Override 438 public void visitSynthetic(final Synthetic attribute) 439 { 440 stack.push(attribute); 441 attribute.accept(visitor); 442 stack.pop(); 443 } 444 445 @Override 446 public void visitUnknown(final Unknown attribute) 447 { 448 stack.push(attribute); 449 attribute.accept(visitor); 450 stack.pop(); 451 } 452 453 /** 454 * @since 6.0 455 */ 456 @Override 457 public void visitAnnotationDefault(final AnnotationDefault obj) 458 { 459 stack.push(obj); 460 obj.accept(visitor); 461 stack.pop(); 462 } 463 464 /** 465 * @since 6.0 466 */ 467 @Override 468 public void visitEnclosingMethod(final EnclosingMethod obj) 469 { 470 stack.push(obj); 471 obj.accept(visitor); 472 stack.pop(); 473 } 474 475 /** 476 * @since 6.0 477 */ 478 @Override 479 public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) 480 { 481 stack.push(obj); 482 obj.accept(visitor); 483 stack.pop(); 484 } 485 486 /** 487 * @since 6.0 488 */ 489 @Override 490 public void visitParameterAnnotation(final ParameterAnnotations obj) 491 { 492 stack.push(obj); 493 obj.accept(visitor); 494 stack.pop(); 495 } 496 497 /** 498 * @since 6.0 499 */ 500 @Override 501 public void visitMethodParameters(final MethodParameters obj) 502 { 503 stack.push(obj); 504 obj.accept(visitor); 505 final MethodParameter[] table = obj.getParameters(); 506 for (final MethodParameter element : table) { 507 element.accept(this); 508 } 509 stack.pop(); 510 } 511 512 /** 513 * @since 6.4.0 514 */ 515 @Override 516 public void visitMethodParameter(final MethodParameter obj) 517 { 518 stack.push(obj); 519 obj.accept(visitor); 520 stack.pop(); 521 } 522 523 /** @since 6.0 */ 524 @Override 525 public void visitConstantMethodType(final ConstantMethodType obj) { 526 stack.push(obj); 527 obj.accept(visitor); 528 stack.pop(); 529 } 530 531 /** @since 6.0 */ 532 @Override 533 public void visitConstantMethodHandle(final ConstantMethodHandle obj) { 534 stack.push(obj); 535 obj.accept(visitor); 536 stack.pop(); 537 } 538 539 /** @since 6.0 */ 540 @Override 541 public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) { 542 stack.push(obj); 543 obj.accept(visitor); 544 stack.pop(); 545 } 546 547 /** @since 6.1 */ 548 @Override 549 public void visitConstantPackage(final ConstantPackage obj) { 550 stack.push(obj); 551 obj.accept(visitor); 552 stack.pop(); 553 } 554 555 /** @since 6.1 */ 556 @Override 557 public void visitConstantModule(final ConstantModule obj) { 558 stack.push(obj); 559 obj.accept(visitor); 560 stack.pop(); 561 } 562 563 /** @since 6.3 */ 564 @Override 565 public void visitConstantDynamic(final ConstantDynamic obj) { 566 stack.push(obj); 567 obj.accept(visitor); 568 stack.pop(); 569 } 570 571 /** @since 6.4.0 */ 572 @Override 573 public void visitModule(final Module obj) { 574 stack.push(obj); 575 obj.accept(visitor); 576 final ModuleRequires[] rtable = obj.getRequiresTable(); 577 for (final ModuleRequires element : rtable) { 578 element.accept(this); 579 } 580 final ModuleExports[] etable = obj.getExportsTable(); 581 for (final ModuleExports element : etable) { 582 element.accept(this); 583 } 584 final ModuleOpens[] otable = obj.getOpensTable(); 585 for (final ModuleOpens element : otable) { 586 element.accept(this); 587 } 588 final ModuleProvides[] ptable = obj.getProvidesTable(); 589 for (final ModuleProvides element : ptable) { 590 element.accept(this); 591 } 592 stack.pop(); 593 } 594 595 /** @since 6.4.0 */ 596 @Override 597 public void visitModuleRequires(final ModuleRequires obj) { 598 stack.push(obj); 599 obj.accept(visitor); 600 stack.pop(); 601 } 602 603 /** @since 6.4.0 */ 604 @Override 605 public void visitModuleExports(final ModuleExports obj) { 606 stack.push(obj); 607 obj.accept(visitor); 608 stack.pop(); 609 } 610 611 /** @since 6.4.0 */ 612 @Override 613 public void visitModuleOpens(final ModuleOpens obj) { 614 stack.push(obj); 615 obj.accept(visitor); 616 stack.pop(); 617 } 618 619 /** @since 6.4.0 */ 620 @Override 621 public void visitModuleProvides(final ModuleProvides obj) { 622 stack.push(obj); 623 obj.accept(visitor); 624 stack.pop(); 625 } 626 627 /** @since 6.4.0 */ 628 @Override 629 public void visitModulePackages(final ModulePackages obj) { 630 stack.push(obj); 631 obj.accept(visitor); 632 stack.pop(); 633 } 634 635 /** @since 6.4.0 */ 636 @Override 637 public void visitModuleMainClass(final ModuleMainClass obj) { 638 stack.push(obj); 639 obj.accept(visitor); 640 stack.pop(); 641 } 642 643 /** @since 6.4.0 */ 644 @Override 645 public void visitNestHost(final NestHost obj) { 646 stack.push(obj); 647 obj.accept(visitor); 648 stack.pop(); 649 } 650 651 /** @since 6.4.0 */ 652 @Override 653 public void visitNestMembers(final NestMembers obj) { 654 stack.push(obj); 655 obj.accept(visitor); 656 stack.pop(); 657 } 658 }