/***
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000-2007 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.google.gwt.dev.asm;

/**
 * A visitor to visit a Java method. The methods of this interface must be
 * called in the following order: [ <tt>visitAnnotationDefault</tt> ] (
 * <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
 * <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
 * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | <tt>visitTryCatchBlock</tt> |
 * <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt>)* <tt>visitMaxs</tt> ]
 * <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt>
 * and <tt>visitLabel</tt> methods must be called in the sequential order of
 * the bytecode instructions of the visited code, <tt>visitTryCatchBlock</tt>
 * must be called <i>before</i> the labels passed as arguments have been
 * visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt>
 * methods must be called <i>after</i> the labels passed as arguments have been
 * visited.
 * 
 * @author Eric Bruneton
 */
public interface MethodVisitor {

    // -------------------------------------------------------------------------
    // Annotations and non standard attributes
    // -------------------------------------------------------------------------

    /**
     * Visits the default value of this annotation interface method.
     * 
     * @return a visitor to the visit the actual default value of this
     *         annotation interface method, or <tt>null</tt> if this visitor
     *         is not interested in visiting this default value. The 'name'
     *         parameters passed to the methods of this annotation visitor are
     *         ignored. Moreover, exacly one visit method must be called on this
     *         annotation visitor, followed by visitEnd.
     */
    AnnotationVisitor visitAnnotationDefault();

    /**
     * Visits an annotation of this method.
     * 
     * @param desc the class descriptor of the annotation class.
     * @param visible <tt>true</tt> if the annotation is visible at runtime.
     * @return a visitor to visit the annotation values, or <tt>null</tt> if
     *         this visitor is not interested in visiting this annotation.
     */
    AnnotationVisitor visitAnnotation(String desc, boolean visible);

    /**
     * Visits an annotation of a parameter this method.
     * 
     * @param parameter the parameter index.
     * @param desc the class descriptor of the annotation class.
     * @param visible <tt>true</tt> if the annotation is visible at runtime.
     * @return a visitor to visit the annotation values, or <tt>null</tt> if
     *         this visitor is not interested in visiting this annotation.
     */
    AnnotationVisitor visitParameterAnnotation(
        int parameter,
        String desc,
        boolean visible);

    /**
     * Visits a non standard attribute of this method.
     * 
     * @param attr an attribute.
     */
    void visitAttribute(Attribute attr);

    /**
     * Starts the visit of the method's code, if any (i.e. non abstract method).
     */
    void visitCode();

    /**
     * Visits the current state of the local variables and operand stack
     * elements. This method must(*) be called <i>just before</i> any
     * instruction <b>i</b> that follows an unconditionnal branch instruction
     * such as GOTO or THROW, that is the target of a jump instruction, or that
     * starts an exception handler block. The visited types must describe the
     * values of the local variables and of the operand stack elements <i>just
     * before</i> <b>i</b> is executed. <br> <br> (*) this is mandatory only
     * for classes whose version is greater than or equal to
     * {@link Opcodes#V1_6 V1_6}. <br> <br> Packed frames are basically
     * "deltas" from the state of the previous frame (very first frame is
     * implicitly defined by the method's parameters and access flags): <ul>
     * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
     * locals as the previous frame and with the empty stack.</li> <li>{@link Opcodes#F_SAME1}
     * representing frame with exactly the same locals as the previous frame and
     * with single value on the stack (<code>nStack</code> is 1 and
     * <code>stack[0]</code> contains value for the type of the stack item).</li>
     * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
     * the same as the locals in the previous frame, except that additional
     * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
     * <code>local</code> elements contains values representing added types).</li>
     * <li>{@link Opcodes#F_CHOP} representing frame with current locals are
     * the same as the locals in the previous frame, except that the last 1-3
     * locals are absent and with the empty stack (<code>nLocals</code> is 1,
     * 2 or 3). </li> <li>{@link Opcodes#F_FULL} representing complete frame
     * data.</li> </li> </ul>
     * 
     * @param type the type of this stack map frame. Must be
     *        {@link Opcodes#F_NEW} for expanded frames, or
     *        {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
     *        {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
     *        {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed
     *        frames.
     * @param nLocal the number of local variables in the visited frame.
     * @param local the local variable types in this frame. This array must not
     *        be modified. Primitive types are represented by
     *        {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
     *        {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
     *        {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
     *        {@link Opcodes#UNINITIALIZED_THIS} (long and double are
     *        represented by a single element). Reference types are represented
     *        by String objects (representing internal names), and uninitialized 
     *        types by Label objects (this label designates the NEW instruction 
     *        that created this uninitialized value).
     * @param nStack the number of operand stack elements in the visited frame.
     * @param stack the operand stack types in this frame. This array must not
     *        be modified. Its content has the same format as the "local" array.
     */
    void visitFrame(
        int type,
        int nLocal,
        Object[] local,
        int nStack,
        Object[] stack);

    // -------------------------------------------------------------------------
    // Normal instructions
    // -------------------------------------------------------------------------

    /**
     * Visits a zero operand instruction.
     * 
     * @param opcode the opcode of the instruction to be visited. This opcode is
     *        either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
     *        ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
     *        FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD,
     *        DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE,
     *        DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP,
     *        DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD,
     *        DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
     *        FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL,
     *        LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR,
     *        I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
     *        I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
     *        FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
     *        MONITORENTER, or MONITOREXIT.
     */
    void visitInsn(int opcode);

    /**
     * Visits an instruction with a single int operand.
     * 
     * @param opcode the opcode of the instruction to be visited. This opcode is
     *        either BIPUSH, SIPUSH or NEWARRAY.
     * @param operand the operand of the instruction to be visited.<br> When
     *        opcode is BIPUSH, operand value should be between Byte.MIN_VALUE
     *        and Byte.MAX_VALUE.<br> When opcode is SIPUSH, operand value
     *        should be between Short.MIN_VALUE and Short.MAX_VALUE.<br> When
     *        opcode is NEWARRAY, operand value should be one of
     *        {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
     *        {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
     *        {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
     *        {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
     */
    void visitIntInsn(int opcode, int operand);

    /**
     * Visits a local variable instruction. A local variable instruction is an
     * instruction that loads or stores the value of a local variable.
     * 
     * @param opcode the opcode of the local variable instruction to be visited.
     *        This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
     *        LSTORE, FSTORE, DSTORE, ASTORE or RET.
     * @param var the operand of the instruction to be visited. This operand is
     *        the index of a local variable.
     */
    void visitVarInsn(int opcode, int var);

    /**
     * Visits a type instruction. A type instruction is an instruction that
     * takes the internal name of a class as parameter.
     * 
     * @param opcode the opcode of the type instruction to be visited. This
     *        opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
     * @param type the operand of the instruction to be visited. This operand
     *        must be the internal name of an object or array class (see {@link 
     *        Type#getInternalName() getInternalName}).
     */
    void visitTypeInsn(int opcode, String type);

    /**
     * Visits a field instruction. A field instruction is an instruction that
     * loads or stores the value of a field of an object.
     * 
     * @param opcode the opcode of the type instruction to be visited. This
     *        opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
     * @param owner the internal name of the field's owner class (see {@link
     *        Type#getInternalName() getInternalName}).
     * @param name the field's name.
     * @param desc the field's descriptor (see {@link Type Type}).
     */
    void visitFieldInsn(int opcode, String owner, String name, String desc);

    /**
     * Visits a method instruction. A method instruction is an instruction that
     * invokes a method.
     * 
     * @param opcode the opcode of the type instruction to be visited. This
     *        opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
     *        INVOKEINTERFACE.
     * @param owner the internal name of the method's owner class (see {@link
     *        Type#getInternalName() getInternalName}).
     * @param name the method's name.
     * @param desc the method's descriptor (see {@link Type Type}).
     */
    void visitMethodInsn(int opcode, String owner, String name, String desc);

    /**
     * Visits a jump instruction. A jump instruction is an instruction that may
     * jump to another instruction.
     * 
     * @param opcode the opcode of the type instruction to be visited. This
     *        opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
     *        IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
     *        IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
     * @param label the operand of the instruction to be visited. This operand
     *        is a label that designates the instruction to which the jump
     *        instruction may jump.
     */
    void visitJumpInsn(int opcode, Label label);

    /**
     * Visits a label. A label designates the instruction that will be visited
     * just after it.
     * 
     * @param label a {@link Label Label} object.
     */
    void visitLabel(Label label);

    // -------------------------------------------------------------------------
    // Special instructions
    // -------------------------------------------------------------------------

    /**
     * Visits a LDC instruction.
     * 
     * @param cst the constant to be loaded on the stack. This parameter must be
     *        a non null {@link Integer}, a {@link Float}, a {@link Long}, a
     *        {@link Double} a {@link String} (or a {@link Type} for
     *        <tt>.class</tt> constants, for classes whose version is 49.0 or
     *        more).
     */
    void visitLdcInsn(Object cst);

    /**
     * Visits an IINC instruction.
     * 
     * @param var index of the local variable to be incremented.
     * @param increment amount to increment the local variable by.
     */
    void visitIincInsn(int var, int increment);

    /**
     * Visits a TABLESWITCH instruction.
     * 
     * @param min the minimum key value.
     * @param max the maximum key value.
     * @param dflt beginning of the default handler block.
     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
     *        the beginning of the handler block for the <tt>min + i</tt> key.
     */
    void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels);

    /**
     * Visits a LOOKUPSWITCH instruction.
     * 
     * @param dflt beginning of the default handler block.
     * @param keys the values of the keys.
     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
     *        the beginning of the handler block for the <tt>keys[i]</tt> key.
     */
    void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels);

    /**
     * Visits a MULTIANEWARRAY instruction.
     * 
     * @param desc an array type descriptor (see {@link Type Type}).
     * @param dims number of dimensions of the array to allocate.
     */
    void visitMultiANewArrayInsn(String desc, int dims);

    // -------------------------------------------------------------------------
    // Exceptions table entries, debug information, max stack and max locals
    // -------------------------------------------------------------------------

    /**
     * Visits a try catch block.
     * 
     * @param start beginning of the exception handler's scope (inclusive).
     * @param end end of the exception handler's scope (exclusive).
     * @param handler beginning of the exception handler's code.
     * @param type internal name of the type of exceptions handled by the
     *        handler, or <tt>null</tt> to catch any exceptions (for "finally"
     *        blocks).
     * @throws IllegalArgumentException if one of the labels has already been
     *         visited by this visitor (by the {@link #visitLabel visitLabel}
     *         method).
     */
    void visitTryCatchBlock(Label start, Label end, Label handler, String type);

    /**
     * Visits a local variable declaration.
     * 
     * @param name the name of a local variable.
     * @param desc the type descriptor of this local variable.
     * @param signature the type signature of this local variable. May be
     *        <tt>null</tt> if the local variable type does not use generic
     *        types.
     * @param start the first instruction corresponding to the scope of this
     *        local variable (inclusive).
     * @param end the last instruction corresponding to the scope of this local
     *        variable (exclusive).
     * @param index the local variable's index.
     * @throws IllegalArgumentException if one of the labels has not already
     *         been visited by this visitor (by the
     *         {@link #visitLabel visitLabel} method).
     */
    void visitLocalVariable(
        String name,
        String desc,
        String signature,
        Label start,
        Label end,
        int index);

    /**
     * Visits a line number declaration.
     * 
     * @param line a line number. This number refers to the source file from
     *        which the class was compiled.
     * @param start the first instruction corresponding to this line number.
     * @throws IllegalArgumentException if <tt>start</tt> has not already been
     *         visited by this visitor (by the {@link #visitLabel visitLabel}
     *         method).
     */
    void visitLineNumber(int line, Label start);

    /**
     * Visits the maximum stack size and the maximum number of local variables
     * of the method.
     * 
     * @param maxStack maximum stack size of the method.
     * @param maxLocals maximum number of local variables for the method.
     */
    void visitMaxs(int maxStack, int maxLocals);

    /**
     * Visits the end of the method. This method, which is the last one to be
     * called, is used to inform the visitor that all the annotations and
     * attributes of the method have been visited.
     */
    void visitEnd();
}
