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