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