• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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