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