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