2 * ASM: a very small and fast Java bytecode manipulation framework
3 * Copyright (c) 2000-2005 INRIA, France Telecom
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
30 package org.objectweb.asm.util;
32 import org.objectweb.asm.AnnotationVisitor;
33 import org.objectweb.asm.MethodVisitor;
34 import org.objectweb.asm.Label;
35 import org.objectweb.asm.Opcodes;
37 import java.util.HashMap;
40 * A {@link MethodVisitor} that prints the ASM code that generates the methods
43 * @author Eric Bruneton
44 * @author Eugene Kuleshov
46 public class ASMifierMethodVisitor extends ASMifierAbstractVisitor implements
51 * Constructs a new {@link ASMifierMethodVisitor} object.
53 public ASMifierMethodVisitor() {
55 this.labelNames = new HashMap();
58 public AnnotationVisitor visitAnnotationDefault() {
60 buf.append("{\n").append("av0 = mv.visitAnnotationDefault();\n");
61 text.add(buf.toString());
62 ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
63 text.add(av.getText());
68 public AnnotationVisitor visitParameterAnnotation(
71 final boolean visible)
75 .append("av0 = mv.visitParameterAnnotation(")
79 buf.append(", ").append(visible).append(");\n");
80 text.add(buf.toString());
81 ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
82 text.add(av.getText());
87 public void visitCode() {
88 text.add("mv.visitCode();\n");
91 public void visitInsn(final int opcode) {
93 buf.append("mv.visitInsn(").append(OPCODES[opcode]).append(");\n");
94 text.add(buf.toString());
97 public void visitIntInsn(final int opcode, final int operand) {
99 buf.append("mv.visitIntInsn(")
100 .append(OPCODES[opcode])
102 .append(opcode == Opcodes.NEWARRAY
104 : Integer.toString(operand))
106 text.add(buf.toString());
109 public void visitVarInsn(final int opcode, final int var) {
111 buf.append("mv.visitVarInsn(")
112 .append(OPCODES[opcode])
116 text.add(buf.toString());
119 public void visitTypeInsn(final int opcode, final String desc) {
121 buf.append("mv.visitTypeInsn(").append(OPCODES[opcode]).append(", ");
122 appendConstant(desc);
124 text.add(buf.toString());
127 public void visitFieldInsn(
134 buf.append("mv.visitFieldInsn(").append(OPCODES[opcode]).append(", ");
135 appendConstant(owner);
137 appendConstant(name);
139 appendConstant(desc);
141 text.add(buf.toString());
144 public void visitMethodInsn(
151 buf.append("mv.visitMethodInsn(").append(OPCODES[opcode]).append(", ");
152 appendConstant(owner);
154 appendConstant(name);
156 appendConstant(desc);
158 text.add(buf.toString());
161 public void visitJumpInsn(final int opcode, final Label label) {
164 buf.append("mv.visitJumpInsn(").append(OPCODES[opcode]).append(", ");
167 text.add(buf.toString());
170 public void visitLabel(final Label label) {
173 buf.append("mv.visitLabel(");
176 text.add(buf.toString());
179 public void visitLdcInsn(final Object cst) {
181 buf.append("mv.visitLdcInsn(");
184 text.add(buf.toString());
187 public void visitIincInsn(final int var, final int increment) {
189 buf.append("mv.visitIincInsn(")
194 text.add(buf.toString());
197 public void visitTableSwitchInsn(
201 final Label labels[])
204 for (int i = 0; i < labels.length; ++i) {
205 declareLabel(labels[i]);
209 buf.append("mv.visitTableSwitchInsn(")
215 buf.append(", new Label[] {");
216 for (int i = 0; i < labels.length; ++i) {
217 buf.append(i == 0 ? " " : ", ");
218 appendLabel(labels[i]);
220 buf.append(" });\n");
221 text.add(buf.toString());
224 public void visitLookupSwitchInsn(
227 final Label labels[])
230 for (int i = 0; i < labels.length; ++i) {
231 declareLabel(labels[i]);
235 buf.append("mv.visitLookupSwitchInsn(");
237 buf.append(", new int[] {");
238 for (int i = 0; i < keys.length; ++i) {
239 buf.append(i == 0 ? " " : ", ").append(keys[i]);
241 buf.append(" }, new Label[] {");
242 for (int i = 0; i < labels.length; ++i) {
243 buf.append(i == 0 ? " " : ", ");
244 appendLabel(labels[i]);
246 buf.append(" });\n");
247 text.add(buf.toString());
250 public void visitMultiANewArrayInsn(final String desc, final int dims) {
252 buf.append("mv.visitMultiANewArrayInsn(");
253 appendConstant(desc);
254 buf.append(", ").append(dims).append(");\n");
255 text.add(buf.toString());
258 public void visitTryCatchBlock(
267 declareLabel(handler);
268 buf.append("mv.visitTryCatchBlock(");
273 appendLabel(handler);
275 appendConstant(type);
277 text.add(buf.toString());
280 public void visitLocalVariable(
283 final String signature,
289 buf.append("mv.visitLocalVariable(");
290 appendConstant(name);
292 appendConstant(desc);
294 appendConstant(signature);
299 buf.append(", ").append(index).append(");\n");
300 text.add(buf.toString());
303 public void visitLineNumber(final int line, final Label start) {
305 buf.append("mv.visitLineNumber(").append(line).append(", ");
308 text.add(buf.toString());
311 public void visitMaxs(final int maxStack, final int maxLocals) {
313 buf.append("mv.visitMaxs(")
318 text.add(buf.toString());
322 * Appends a declaration of the given label to {@link #buf buf}. This
323 * declaration is of the form "Label lXXX = new Label();". Does nothing if
324 * the given label has already been declared.
328 private void declareLabel(final Label l) {
329 String name = (String) labelNames.get(l);
331 name = "l" + labelNames.size();
332 labelNames.put(l, name);
333 buf.append("Label ").append(name).append(" = new Label();\n");
338 * Appends the name of the given label to {@link #buf buf}. The given label
339 * <i>must</i> already have a name. One way to ensure this is to always
340 * call {@link #declareLabel declared} before calling this method.
344 private void appendLabel(final Label l) {
345 buf.append((String) labelNames.get(l));