1 /*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2011 INRIA, France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.objectweb.asm; 31 32 /** 33 * A visitor to visit a Java method. The methods of this class must be called in 34 * the following order: ( <tt>visitParameter</tt> )* [ 35 * <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> | 36 * <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> | 37 * <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> | 38 * <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> | 39 * <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> | 40 * <tt>visitTryCatchAnnotation</tt> | <tt>visitLocalVariable</tt> | 41 * <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )* 42 * <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the 43 * <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must be called in 44 * the sequential order of the bytecode instructions of the visited code, 45 * <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated 46 * instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the 47 * labels passed as arguments have been visited, 48 * <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the 49 * corresponding try catch block has been visited, and the 50 * <tt>visitLocalVariable</tt>, <tt>visitLocalVariableAnnotation</tt> and 51 * <tt>visitLineNumber</tt> methods must be called <i>after</i> the labels 52 * passed as arguments have been visited. 53 * 54 * @author Eric Bruneton 55 */ 56 public abstract class MethodVisitor { 57 58 /** 59 * The ASM API version implemented by this visitor. The value of this field 60 * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. 61 */ 62 protected final int api; 63 64 /** 65 * The method visitor to which this visitor must delegate method calls. May 66 * be null. 67 */ 68 protected MethodVisitor mv; 69 70 /** 71 * Constructs a new {@link MethodVisitor}. 72 * 73 * @param api 74 * the ASM API version implemented by this visitor. Must be one 75 * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. 76 */ MethodVisitor(final int api)77 public MethodVisitor(final int api) { 78 this(api, null); 79 } 80 81 /** 82 * Constructs a new {@link MethodVisitor}. 83 * 84 * @param api 85 * the ASM API version implemented by this visitor. Must be one 86 * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. 87 * @param mv 88 * the method visitor to which this visitor must delegate method 89 * calls. May be null. 90 */ MethodVisitor(final int api, final MethodVisitor mv)91 public MethodVisitor(final int api, final MethodVisitor mv) { 92 if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { 93 throw new IllegalArgumentException(); 94 } 95 this.api = api; 96 this.mv = mv; 97 } 98 99 // ------------------------------------------------------------------------- 100 // Parameters, annotations and non standard attributes 101 // ------------------------------------------------------------------------- 102 103 /** 104 * Visits a parameter of this method. 105 * 106 * @param name 107 * parameter name or null if none is provided. 108 * @param access 109 * the parameter's access flags, only <tt>ACC_FINAL</tt>, 110 * <tt>ACC_SYNTHETIC</tt> or/and <tt>ACC_MANDATED</tt> are 111 * allowed (see {@link Opcodes}). 112 */ visitParameter(String name, int access)113 public void visitParameter(String name, int access) { 114 if (api < Opcodes.ASM5) { 115 throw new RuntimeException(); 116 } 117 if (mv != null) { 118 mv.visitParameter(name, access); 119 } 120 } 121 122 /** 123 * Visits the default value of this annotation interface method. 124 * 125 * @return a visitor to the visit the actual default value of this 126 * annotation interface method, or <tt>null</tt> if this visitor is 127 * not interested in visiting this default value. The 'name' 128 * parameters passed to the methods of this annotation visitor are 129 * ignored. Moreover, exacly one visit method must be called on this 130 * annotation visitor, followed by visitEnd. 131 */ visitAnnotationDefault()132 public AnnotationVisitor visitAnnotationDefault() { 133 if (mv != null) { 134 return mv.visitAnnotationDefault(); 135 } 136 return null; 137 } 138 139 /** 140 * Visits an annotation of this method. 141 * 142 * @param desc 143 * the class descriptor of the annotation class. 144 * @param visible 145 * <tt>true</tt> if the annotation is visible at runtime. 146 * @return a visitor to visit the annotation values, or <tt>null</tt> if 147 * this visitor is not interested in visiting this annotation. 148 */ visitAnnotation(String desc, boolean visible)149 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 150 if (mv != null) { 151 return mv.visitAnnotation(desc, visible); 152 } 153 return null; 154 } 155 156 /** 157 * Visits an annotation on a type in the method signature. 158 * 159 * @param typeRef 160 * a reference to the annotated type. The sort of this type 161 * reference must be {@link TypeReference#METHOD_TYPE_PARAMETER 162 * METHOD_TYPE_PARAMETER}, 163 * {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND 164 * METHOD_TYPE_PARAMETER_BOUND}, 165 * {@link TypeReference#METHOD_RETURN METHOD_RETURN}, 166 * {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER}, 167 * {@link TypeReference#METHOD_FORMAL_PARAMETER 168 * METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS 169 * THROWS}. See {@link TypeReference}. 170 * @param typePath 171 * the path to the annotated type argument, wildcard bound, array 172 * element type, or static inner type within 'typeRef'. May be 173 * <tt>null</tt> if the annotation targets 'typeRef' as a whole. 174 * @param desc 175 * the class descriptor of the annotation class. 176 * @param visible 177 * <tt>true</tt> if the annotation is visible at runtime. 178 * @return a visitor to visit the annotation values, or <tt>null</tt> if 179 * this visitor is not interested in visiting this annotation. 180 */ visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible)181 public AnnotationVisitor visitTypeAnnotation(int typeRef, 182 TypePath typePath, String desc, boolean visible) { 183 if (api < Opcodes.ASM5) { 184 throw new RuntimeException(); 185 } 186 if (mv != null) { 187 return mv.visitTypeAnnotation(typeRef, typePath, desc, visible); 188 } 189 return null; 190 } 191 192 /** 193 * Visits an annotation of a parameter this method. 194 * 195 * @param parameter 196 * the parameter index. 197 * @param desc 198 * the class descriptor of the annotation class. 199 * @param visible 200 * <tt>true</tt> if the annotation is visible at runtime. 201 * @return a visitor to visit the annotation values, or <tt>null</tt> if 202 * this visitor is not interested in visiting this annotation. 203 */ visitParameterAnnotation(int parameter, String desc, boolean visible)204 public AnnotationVisitor visitParameterAnnotation(int parameter, 205 String desc, boolean visible) { 206 if (mv != null) { 207 return mv.visitParameterAnnotation(parameter, desc, visible); 208 } 209 return null; 210 } 211 212 /** 213 * Visits a non standard attribute of this method. 214 * 215 * @param attr 216 * an attribute. 217 */ visitAttribute(Attribute attr)218 public void visitAttribute(Attribute attr) { 219 if (mv != null) { 220 mv.visitAttribute(attr); 221 } 222 } 223 224 /** 225 * Starts the visit of the method's code, if any (i.e. non abstract method). 226 */ visitCode()227 public void visitCode() { 228 if (mv != null) { 229 mv.visitCode(); 230 } 231 } 232 233 /** 234 * Visits the current state of the local variables and operand stack 235 * elements. This method must(*) be called <i>just before</i> any 236 * instruction <b>i</b> that follows an unconditional branch instruction 237 * such as GOTO or THROW, that is the target of a jump instruction, or that 238 * starts an exception handler block. The visited types must describe the 239 * values of the local variables and of the operand stack elements <i>just 240 * before</i> <b>i</b> is executed.<br> 241 * <br> 242 * (*) this is mandatory only for classes whose version is greater than or 243 * equal to {@link Opcodes#V1_6 V1_6}. <br> 244 * <br> 245 * The frames of a method must be given either in expanded form, or in 246 * compressed form (all frames must use the same format, i.e. you must not 247 * mix expanded and compressed frames within a single method): 248 * <ul> 249 * <li>In expanded form, all frames must have the F_NEW type.</li> 250 * <li>In compressed form, frames are basically "deltas" from the state of 251 * the previous frame: 252 * <ul> 253 * <li>{@link Opcodes#F_SAME} representing frame with exactly the same 254 * locals as the previous frame and with the empty stack.</li> 255 * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same 256 * locals as the previous frame and with single value on the stack ( 257 * <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the 258 * type of the stack item).</li> 259 * <li>{@link Opcodes#F_APPEND} representing frame with current locals are 260 * the same as the locals in the previous frame, except that additional 261 * locals are defined (<code>nLocal</code> is 1, 2 or 3 and 262 * <code>local</code> elements contains values representing added types).</li> 263 * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the 264 * same as the locals in the previous frame, except that the last 1-3 locals 265 * are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li> 266 * <li>{@link Opcodes#F_FULL} representing complete frame data.</li> 267 * </ul> 268 * </li> 269 * </ul> 270 * <br> 271 * In both cases the first frame, corresponding to the method's parameters 272 * and access flags, is implicit and must not be visited. Also, it is 273 * illegal to visit two or more frames for the same code location (i.e., at 274 * least one instruction must be visited between two calls to visitFrame). 275 * 276 * @param type 277 * the type of this stack map frame. Must be 278 * {@link Opcodes#F_NEW} for expanded frames, or 279 * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, 280 * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or 281 * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for 282 * compressed frames. 283 * @param nLocal 284 * the number of local variables in the visited frame. 285 * @param local 286 * the local variable types in this frame. This array must not be 287 * modified. Primitive types are represented by 288 * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, 289 * {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, 290 * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or 291 * {@link Opcodes#UNINITIALIZED_THIS} (long and double are 292 * represented by a single element). Reference types are 293 * represented by String objects (representing internal names), 294 * and uninitialized types by Label objects (this label 295 * designates the NEW instruction that created this uninitialized 296 * value). 297 * @param nStack 298 * the number of operand stack elements in the visited frame. 299 * @param stack 300 * the operand stack types in this frame. This array must not be 301 * modified. Its content has the same format as the "local" 302 * array. 303 * @throws IllegalStateException 304 * if a frame is visited just after another one, without any 305 * instruction between the two (unless this frame is a 306 * Opcodes#F_SAME frame, in which case it is silently ignored). 307 */ visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack)308 public void visitFrame(int type, int nLocal, Object[] local, int nStack, 309 Object[] stack) { 310 if (mv != null) { 311 mv.visitFrame(type, nLocal, local, nStack, stack); 312 } 313 } 314 315 // ------------------------------------------------------------------------- 316 // Normal instructions 317 // ------------------------------------------------------------------------- 318 319 /** 320 * Visits a zero operand instruction. 321 * 322 * @param opcode 323 * the opcode of the instruction to be visited. This opcode is 324 * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, 325 * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, 326 * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, 327 * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, 328 * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, 329 * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, 330 * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, 331 * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, 332 * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, 333 * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, 334 * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, 335 * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, 336 * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, 337 * or MONITOREXIT. 338 */ visitInsn(int opcode)339 public void visitInsn(int opcode) { 340 if (mv != null) { 341 mv.visitInsn(opcode); 342 } 343 } 344 345 /** 346 * Visits an instruction with a single int operand. 347 * 348 * @param opcode 349 * the opcode of the instruction to be visited. This opcode is 350 * either BIPUSH, SIPUSH or NEWARRAY. 351 * @param operand 352 * the operand of the instruction to be visited.<br> 353 * When opcode is BIPUSH, operand value should be between 354 * Byte.MIN_VALUE and Byte.MAX_VALUE.<br> 355 * When opcode is SIPUSH, operand value should be between 356 * Short.MIN_VALUE and Short.MAX_VALUE.<br> 357 * When opcode is NEWARRAY, operand value should be one of 358 * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, 359 * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, 360 * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, 361 * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. 362 */ visitIntInsn(int opcode, int operand)363 public void visitIntInsn(int opcode, int operand) { 364 if (mv != null) { 365 mv.visitIntInsn(opcode, operand); 366 } 367 } 368 369 /** 370 * Visits a local variable instruction. A local variable instruction is an 371 * instruction that loads or stores the value of a local variable. 372 * 373 * @param opcode 374 * the opcode of the local variable instruction to be visited. 375 * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, 376 * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. 377 * @param var 378 * the operand of the instruction to be visited. This operand is 379 * the index of a local variable. 380 */ visitVarInsn(int opcode, int var)381 public void visitVarInsn(int opcode, int var) { 382 if (mv != null) { 383 mv.visitVarInsn(opcode, var); 384 } 385 } 386 387 /** 388 * Visits a type instruction. A type instruction is an instruction that 389 * takes the internal name of a class as parameter. 390 * 391 * @param opcode 392 * the opcode of the type instruction to be visited. This opcode 393 * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. 394 * @param type 395 * the operand of the instruction to be visited. This operand 396 * must be the internal name of an object or array class (see 397 * {@link Type#getInternalName() getInternalName}). 398 */ visitTypeInsn(int opcode, String type)399 public void visitTypeInsn(int opcode, String type) { 400 if (mv != null) { 401 mv.visitTypeInsn(opcode, type); 402 } 403 } 404 405 /** 406 * Visits a field instruction. A field instruction is an instruction that 407 * loads or stores the value of a field of an object. 408 * 409 * @param opcode 410 * the opcode of the type instruction to be visited. This opcode 411 * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. 412 * @param owner 413 * the internal name of the field's owner class (see 414 * {@link Type#getInternalName() getInternalName}). 415 * @param name 416 * the field's name. 417 * @param desc 418 * the field's descriptor (see {@link Type Type}). 419 */ visitFieldInsn(int opcode, String owner, String name, String desc)420 public void visitFieldInsn(int opcode, String owner, String name, 421 String desc) { 422 if (mv != null) { 423 mv.visitFieldInsn(opcode, owner, name, desc); 424 } 425 } 426 427 /** 428 * Visits a method instruction. A method instruction is an instruction that 429 * invokes a method. 430 * 431 * @param opcode 432 * the opcode of the type instruction to be visited. This opcode 433 * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or 434 * INVOKEINTERFACE. 435 * @param owner 436 * the internal name of the method's owner class (see 437 * {@link Type#getInternalName() getInternalName}). 438 * @param name 439 * the method's name. 440 * @param desc 441 * the method's descriptor (see {@link Type Type}). 442 */ 443 @Deprecated visitMethodInsn(int opcode, String owner, String name, String desc)444 public void visitMethodInsn(int opcode, String owner, String name, 445 String desc) { 446 if (api >= Opcodes.ASM5) { 447 boolean itf = opcode == Opcodes.INVOKEINTERFACE; 448 visitMethodInsn(opcode, owner, name, desc, itf); 449 return; 450 } 451 if (mv != null) { 452 mv.visitMethodInsn(opcode, owner, name, desc); 453 } 454 } 455 456 /** 457 * Visits a method instruction. A method instruction is an instruction that 458 * invokes a method. 459 * 460 * @param opcode 461 * the opcode of the type instruction to be visited. This opcode 462 * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or 463 * INVOKEINTERFACE. 464 * @param owner 465 * the internal name of the method's owner class (see 466 * {@link Type#getInternalName() getInternalName}). 467 * @param name 468 * the method's name. 469 * @param desc 470 * the method's descriptor (see {@link Type Type}). 471 * @param itf 472 * if the method's owner class is an interface. 473 */ visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)474 public void visitMethodInsn(int opcode, String owner, String name, 475 String desc, boolean itf) { 476 if (api < Opcodes.ASM5) { 477 if (itf != (opcode == Opcodes.INVOKEINTERFACE)) { 478 throw new IllegalArgumentException( 479 "INVOKESPECIAL/STATIC on interfaces require ASM 5"); 480 } 481 visitMethodInsn(opcode, owner, name, desc); 482 return; 483 } 484 if (mv != null) { 485 mv.visitMethodInsn(opcode, owner, name, desc, itf); 486 } 487 } 488 489 /** 490 * Visits an invokedynamic instruction. 491 * 492 * @param name 493 * the method's name. 494 * @param desc 495 * the method's descriptor (see {@link Type Type}). 496 * @param bsm 497 * the bootstrap method. 498 * @param bsmArgs 499 * the bootstrap method constant arguments. Each argument must be 500 * an {@link Integer}, {@link Float}, {@link Long}, 501 * {@link Double}, {@link String}, {@link Type} or {@link Handle} 502 * value. This method is allowed to modify the content of the 503 * array so a caller should expect that this array may change. 504 */ visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs)505 public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, 506 Object... bsmArgs) { 507 if (mv != null) { 508 mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); 509 } 510 } 511 512 /** 513 * Visits a jump instruction. A jump instruction is an instruction that may 514 * jump to another instruction. 515 * 516 * @param opcode 517 * the opcode of the type instruction to be visited. This opcode 518 * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, 519 * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, 520 * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. 521 * @param label 522 * the operand of the instruction to be visited. This operand is 523 * a label that designates the instruction to which the jump 524 * instruction may jump. 525 */ visitJumpInsn(int opcode, Label label)526 public void visitJumpInsn(int opcode, Label label) { 527 if (mv != null) { 528 mv.visitJumpInsn(opcode, label); 529 } 530 } 531 532 /** 533 * Visits a label. A label designates the instruction that will be visited 534 * just after it. 535 * 536 * @param label 537 * a {@link Label Label} object. 538 */ visitLabel(Label label)539 public void visitLabel(Label label) { 540 if (mv != null) { 541 mv.visitLabel(label); 542 } 543 } 544 545 // ------------------------------------------------------------------------- 546 // Special instructions 547 // ------------------------------------------------------------------------- 548 549 /** 550 * Visits a LDC instruction. Note that new constant types may be added in 551 * future versions of the Java Virtual Machine. To easily detect new 552 * constant types, implementations of this method should check for 553 * unexpected constant types, like this: 554 * 555 * <pre> 556 * if (cst instanceof Integer) { 557 * // ... 558 * } else if (cst instanceof Float) { 559 * // ... 560 * } else if (cst instanceof Long) { 561 * // ... 562 * } else if (cst instanceof Double) { 563 * // ... 564 * } else if (cst instanceof String) { 565 * // ... 566 * } else if (cst instanceof Type) { 567 * int sort = ((Type) cst).getSort(); 568 * if (sort == Type.OBJECT) { 569 * // ... 570 * } else if (sort == Type.ARRAY) { 571 * // ... 572 * } else if (sort == Type.METHOD) { 573 * // ... 574 * } else { 575 * // throw an exception 576 * } 577 * } else if (cst instanceof Handle) { 578 * // ... 579 * } else { 580 * // throw an exception 581 * } 582 * </pre> 583 * 584 * @param cst 585 * the constant to be loaded on the stack. This parameter must be 586 * a non null {@link Integer}, a {@link Float}, a {@link Long}, a 587 * {@link Double}, a {@link String}, a {@link Type} of OBJECT or 588 * ARRAY sort for <tt>.class</tt> constants, for classes whose 589 * version is 49.0, a {@link Type} of METHOD sort or a 590 * {@link Handle} for MethodType and MethodHandle constants, for 591 * classes whose version is 51.0. 592 */ visitLdcInsn(Object cst)593 public void visitLdcInsn(Object cst) { 594 if (mv != null) { 595 mv.visitLdcInsn(cst); 596 } 597 } 598 599 /** 600 * Visits an IINC instruction. 601 * 602 * @param var 603 * index of the local variable to be incremented. 604 * @param increment 605 * amount to increment the local variable by. 606 */ visitIincInsn(int var, int increment)607 public void visitIincInsn(int var, int increment) { 608 if (mv != null) { 609 mv.visitIincInsn(var, increment); 610 } 611 } 612 613 /** 614 * Visits a TABLESWITCH instruction. 615 * 616 * @param min 617 * the minimum key value. 618 * @param max 619 * the maximum key value. 620 * @param dflt 621 * beginning of the default handler block. 622 * @param labels 623 * beginnings of the handler blocks. <tt>labels[i]</tt> is the 624 * beginning of the handler block for the <tt>min + i</tt> key. 625 */ visitTableSwitchInsn(int min, int max, Label dflt, Label... labels)626 public void visitTableSwitchInsn(int min, int max, Label dflt, 627 Label... labels) { 628 if (mv != null) { 629 mv.visitTableSwitchInsn(min, max, dflt, labels); 630 } 631 } 632 633 /** 634 * Visits a LOOKUPSWITCH instruction. 635 * 636 * @param dflt 637 * beginning of the default handler block. 638 * @param keys 639 * the values of the keys. 640 * @param labels 641 * beginnings of the handler blocks. <tt>labels[i]</tt> is the 642 * beginning of the handler block for the <tt>keys[i]</tt> key. 643 */ visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)644 public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 645 if (mv != null) { 646 mv.visitLookupSwitchInsn(dflt, keys, labels); 647 } 648 } 649 650 /** 651 * Visits a MULTIANEWARRAY instruction. 652 * 653 * @param desc 654 * an array type descriptor (see {@link Type Type}). 655 * @param dims 656 * number of dimensions of the array to allocate. 657 */ visitMultiANewArrayInsn(String desc, int dims)658 public void visitMultiANewArrayInsn(String desc, int dims) { 659 if (mv != null) { 660 mv.visitMultiANewArrayInsn(desc, dims); 661 } 662 } 663 664 /** 665 * Visits an annotation on an instruction. This method must be called just 666 * <i>after</i> the annotated instruction. It can be called several times 667 * for the same instruction. 668 * 669 * @param typeRef 670 * a reference to the annotated type. The sort of this type 671 * reference must be {@link TypeReference#INSTANCEOF INSTANCEOF}, 672 * {@link TypeReference#NEW NEW}, 673 * {@link TypeReference#CONSTRUCTOR_REFERENCE 674 * CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE 675 * METHOD_REFERENCE}, {@link TypeReference#CAST CAST}, 676 * {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT 677 * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, 678 * {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT 679 * METHOD_INVOCATION_TYPE_ARGUMENT}, 680 * {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT 681 * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or 682 * {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT 683 * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}. 684 * @param typePath 685 * the path to the annotated type argument, wildcard bound, array 686 * element type, or static inner type within 'typeRef'. May be 687 * <tt>null</tt> if the annotation targets 'typeRef' as a whole. 688 * @param desc 689 * the class descriptor of the annotation class. 690 * @param visible 691 * <tt>true</tt> if the annotation is visible at runtime. 692 * @return a visitor to visit the annotation values, or <tt>null</tt> if 693 * this visitor is not interested in visiting this annotation. 694 */ visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible)695 public AnnotationVisitor visitInsnAnnotation(int typeRef, 696 TypePath typePath, String desc, boolean visible) { 697 if (api < Opcodes.ASM5) { 698 throw new RuntimeException(); 699 } 700 if (mv != null) { 701 return mv.visitInsnAnnotation(typeRef, typePath, desc, visible); 702 } 703 return null; 704 } 705 706 // ------------------------------------------------------------------------- 707 // Exceptions table entries, debug information, max stack and max locals 708 // ------------------------------------------------------------------------- 709 710 /** 711 * Visits a try catch block. 712 * 713 * @param start 714 * beginning of the exception handler's scope (inclusive). 715 * @param end 716 * end of the exception handler's scope (exclusive). 717 * @param handler 718 * beginning of the exception handler's code. 719 * @param type 720 * internal name of the type of exceptions handled by the 721 * handler, or <tt>null</tt> to catch any exceptions (for 722 * "finally" blocks). 723 * @throws IllegalArgumentException 724 * if one of the labels has already been visited by this visitor 725 * (by the {@link #visitLabel visitLabel} method). 726 */ visitTryCatchBlock(Label start, Label end, Label handler, String type)727 public void visitTryCatchBlock(Label start, Label end, Label handler, 728 String type) { 729 if (mv != null) { 730 mv.visitTryCatchBlock(start, end, handler, type); 731 } 732 } 733 734 /** 735 * Visits an annotation on an exception handler type. This method must be 736 * called <i>after</i> the {@link #visitTryCatchBlock} for the annotated 737 * exception handler. It can be called several times for the same exception 738 * handler. 739 * 740 * @param typeRef 741 * a reference to the annotated type. The sort of this type 742 * reference must be {@link TypeReference#EXCEPTION_PARAMETER 743 * EXCEPTION_PARAMETER}. See {@link TypeReference}. 744 * @param typePath 745 * the path to the annotated type argument, wildcard bound, array 746 * element type, or static inner type within 'typeRef'. May be 747 * <tt>null</tt> if the annotation targets 'typeRef' as a whole. 748 * @param desc 749 * the class descriptor of the annotation class. 750 * @param visible 751 * <tt>true</tt> if the annotation is visible at runtime. 752 * @return a visitor to visit the annotation values, or <tt>null</tt> if 753 * this visitor is not interested in visiting this annotation. 754 */ visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible)755 public AnnotationVisitor visitTryCatchAnnotation(int typeRef, 756 TypePath typePath, String desc, boolean visible) { 757 if (api < Opcodes.ASM5) { 758 throw new RuntimeException(); 759 } 760 if (mv != null) { 761 return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible); 762 } 763 return null; 764 } 765 766 /** 767 * Visits a local variable declaration. 768 * 769 * @param name 770 * the name of a local variable. 771 * @param desc 772 * the type descriptor of this local variable. 773 * @param signature 774 * the type signature of this local variable. May be 775 * <tt>null</tt> if the local variable type does not use generic 776 * types. 777 * @param start 778 * the first instruction corresponding to the scope of this local 779 * variable (inclusive). 780 * @param end 781 * the last instruction corresponding to the scope of this local 782 * variable (exclusive). 783 * @param index 784 * the local variable's index. 785 * @throws IllegalArgumentException 786 * if one of the labels has not already been visited by this 787 * visitor (by the {@link #visitLabel visitLabel} method). 788 */ visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index)789 public void visitLocalVariable(String name, String desc, String signature, 790 Label start, Label end, int index) { 791 if (mv != null) { 792 mv.visitLocalVariable(name, desc, signature, start, end, index); 793 } 794 } 795 796 /** 797 * Visits an annotation on a local variable type. 798 * 799 * @param typeRef 800 * a reference to the annotated type. The sort of this type 801 * reference must be {@link TypeReference#LOCAL_VARIABLE 802 * LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE 803 * RESOURCE_VARIABLE}. See {@link TypeReference}. 804 * @param typePath 805 * the path to the annotated type argument, wildcard bound, array 806 * element type, or static inner type within 'typeRef'. May be 807 * <tt>null</tt> if the annotation targets 'typeRef' as a whole. 808 * @param start 809 * the fist instructions corresponding to the continuous ranges 810 * that make the scope of this local variable (inclusive). 811 * @param end 812 * the last instructions corresponding to the continuous ranges 813 * that make the scope of this local variable (exclusive). This 814 * array must have the same size as the 'start' array. 815 * @param index 816 * the local variable's index in each range. This array must have 817 * the same size as the 'start' array. 818 * @param desc 819 * the class descriptor of the annotation class. 820 * @param visible 821 * <tt>true</tt> if the annotation is visible at runtime. 822 * @return a visitor to visit the annotation values, or <tt>null</tt> if 823 * this visitor is not interested in visiting this annotation. 824 */ visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc, boolean visible)825 public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, 826 TypePath typePath, Label[] start, Label[] end, int[] index, 827 String desc, boolean visible) { 828 if (api < Opcodes.ASM5) { 829 throw new RuntimeException(); 830 } 831 if (mv != null) { 832 return mv.visitLocalVariableAnnotation(typeRef, typePath, start, 833 end, index, desc, visible); 834 } 835 return null; 836 } 837 838 /** 839 * Visits a line number declaration. 840 * 841 * @param line 842 * a line number. This number refers to the source file from 843 * which the class was compiled. 844 * @param start 845 * the first instruction corresponding to this line number. 846 * @throws IllegalArgumentException 847 * if <tt>start</tt> has not already been visited by this 848 * visitor (by the {@link #visitLabel visitLabel} method). 849 */ visitLineNumber(int line, Label start)850 public void visitLineNumber(int line, Label start) { 851 if (mv != null) { 852 mv.visitLineNumber(line, start); 853 } 854 } 855 856 /** 857 * Visits the maximum stack size and the maximum number of local variables 858 * of the method. 859 * 860 * @param maxStack 861 * maximum stack size of the method. 862 * @param maxLocals 863 * maximum number of local variables for the method. 864 */ visitMaxs(int maxStack, int maxLocals)865 public void visitMaxs(int maxStack, int maxLocals) { 866 if (mv != null) { 867 mv.visitMaxs(maxStack, maxLocals); 868 } 869 } 870 871 /** 872 * Visits the end of the method. This method, which is the last one to be 873 * called, is used to inform the visitor that all the annotations and 874 * attributes of the method have been visited. 875 */ visitEnd()876 public void visitEnd() { 877 if (mv != null) { 878 mv.visitEnd(); 879 } 880 } 881 } 882