1/***
2 * ASM: a very small and fast Java bytecode manipulation framework
3 * Copyright (c) 2000-2007 INRIA, France Telecom
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the copyright holders nor the names of its
15 *    contributors may be used to endorse or promote products derived from
16 *    this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30package org.mockito.asm.tree;
31
32import java.util.List;
33import java.util.Map;
34
35import org.mockito.asm.MethodVisitor;
36
37/**
38 * A node that represents a bytecode instruction. <i>An instruction can appear
39 * at most once in at most one {@link InsnList} at a time</i>.
40 *
41 * @author Eric Bruneton
42 */
43public abstract class AbstractInsnNode {
44
45    /**
46     * The type of {@link InsnNode} instructions.
47     */
48    public static final int INSN = 0;
49
50    /**
51     * The type of {@link IntInsnNode} instructions.
52     */
53    public static final int INT_INSN = 1;
54
55    /**
56     * The type of {@link VarInsnNode} instructions.
57     */
58    public static final int VAR_INSN = 2;
59
60    /**
61     * The type of {@link TypeInsnNode} instructions.
62     */
63    public static final int TYPE_INSN = 3;
64
65    /**
66     * The type of {@link FieldInsnNode} instructions.
67     */
68    public static final int FIELD_INSN = 4;
69
70    /**
71     * The type of {@link MethodInsnNode} instructions.
72     */
73    public static final int METHOD_INSN = 5;
74
75    /**
76     * The type of {@link JumpInsnNode} instructions.
77     */
78    public static final int JUMP_INSN = 6;
79
80    /**
81     * The type of {@link LabelNode} "instructions".
82     */
83    public static final int LABEL = 7;
84
85    /**
86     * The type of {@link LdcInsnNode} instructions.
87     */
88    public static final int LDC_INSN = 8;
89
90    /**
91     * The type of {@link IincInsnNode} instructions.
92     */
93    public static final int IINC_INSN = 9;
94
95    /**
96     * The type of {@link TableSwitchInsnNode} instructions.
97     */
98    public static final int TABLESWITCH_INSN = 10;
99
100    /**
101     * The type of {@link LookupSwitchInsnNode} instructions.
102     */
103    public static final int LOOKUPSWITCH_INSN = 11;
104
105    /**
106     * The type of {@link MultiANewArrayInsnNode} instructions.
107     */
108    public static final int MULTIANEWARRAY_INSN = 12;
109
110    /**
111     * The type of {@link FrameNode} "instructions".
112     */
113    public static final int FRAME = 13;
114
115    /**
116     * The type of {@link LineNumberNode} "instructions".
117     */
118    public static final int LINE = 14;
119
120    /**
121     * The opcode of this instruction.
122     */
123    protected int opcode;
124
125    /**
126     * Previous instruction in the list to which this instruction belongs.
127     */
128    AbstractInsnNode prev;
129
130    /**
131     * Next instruction in the list to which this instruction belongs.
132     */
133    AbstractInsnNode next;
134
135    /**
136     * Index of this instruction in the list to which it belongs. The value of
137     * this field is correct only when {@link InsnList#cache} is not null. A
138     * value of -1 indicates that this instruction does not belong to any
139     * {@link InsnList}.
140     */
141    int index;
142
143    /**
144     * Constructs a new {@link AbstractInsnNode}.
145     *
146     * @param opcode the opcode of the instruction to be constructed.
147     */
148    protected AbstractInsnNode(final int opcode) {
149        this.opcode = opcode;
150        this.index = -1;
151    }
152
153    /**
154     * Returns the opcode of this instruction.
155     *
156     * @return the opcode of this instruction.
157     */
158    public int getOpcode() {
159        return opcode;
160    }
161
162    /**
163     * Returns the type of this instruction.
164     *
165     * @return the type of this instruction, i.e. one the constants defined in
166     *         this class.
167     */
168    public abstract int getType();
169
170    /**
171     * Returns the previous instruction in the list to which this instruction
172     * belongs, if any.
173     *
174     * @return the previous instruction in the list to which this instruction
175     *         belongs, if any. May be <tt>null</tt>.
176     */
177    public AbstractInsnNode getPrevious() {
178        return prev;
179    }
180
181    /**
182     * Returns the next instruction in the list to which this instruction
183     * belongs, if any.
184     *
185     * @return the next instruction in the list to which this instruction
186     *         belongs, if any. May be <tt>null</tt>.
187     */
188    public AbstractInsnNode getNext() {
189        return next;
190    }
191
192    /**
193     * Makes the given code visitor visit this instruction.
194     *
195     * @param cv a code visitor.
196     */
197    public abstract void accept(final MethodVisitor cv);
198
199    /**
200     * Returns a copy of this instruction.
201     *
202     * @param labels a map from LabelNodes to cloned LabelNodes.
203     * @return a copy of this instruction. The returned instruction does not
204     *         belong to any {@link InsnList}.
205     */
206    public abstract AbstractInsnNode clone(final Map labels);
207
208    /**
209     * Returns the clone of the given label.
210     *
211     * @param label a label.
212     * @param map a map from LabelNodes to cloned LabelNodes.
213     * @return the clone of the given label.
214     */
215    static LabelNode clone(final LabelNode label, final Map map) {
216        return (LabelNode) map.get(label);
217    }
218
219    /**
220     * Returns the clones of the given labels.
221     *
222     * @param labels a list of labels.
223     * @param map a map from LabelNodes to cloned LabelNodes.
224     * @return the clones of the given labels.
225     */
226    static LabelNode[] clone(final List labels, final Map map) {
227        LabelNode[] clones = new LabelNode[labels.size()];
228        for (int i = 0; i < clones.length; ++i) {
229            clones[i] = (LabelNode) map.get(labels.get(i));
230        }
231        return clones;
232    }
233}
234