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