KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > asm > util > ASMifierMethodVisitor


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 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  */

30 package com.tc.asm.util;
31
32 import com.tc.asm.AnnotationVisitor;
33 import com.tc.asm.MethodVisitor;
34 import com.tc.asm.Label;
35 import com.tc.asm.Opcodes;
36
37 import java.util.HashMap JavaDoc;
38
39 /**
40  * A {@link MethodVisitor} that prints the ASM code that generates the methods
41  * it visits.
42  *
43  * @author Eric Bruneton
44  * @author Eugene Kuleshov
45  */

46 public class ASMifierMethodVisitor extends ASMifierAbstractVisitor implements
47         MethodVisitor
48 {
49
50     /**
51      * Constructs a new {@link ASMifierMethodVisitor} object.
52      */

53     public ASMifierMethodVisitor() {
54         super("mv");
55         this.labelNames = new HashMap JavaDoc();
56     }
57
58     public AnnotationVisitor visitAnnotationDefault() {
59         buf.setLength(0);
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());
64         text.add("}\n");
65         return av;
66     }
67
68     public AnnotationVisitor visitParameterAnnotation(
69         final int parameter,
70         final String JavaDoc desc,
71         final boolean visible)
72     {
73         buf.setLength(0);
74         buf.append("{\n")
75                 .append("av0 = mv.visitParameterAnnotation(")
76                 .append(parameter)
77                 .append(", ");
78         appendConstant(desc);
79         buf.append(", ").append(visible).append(");\n");
80         text.add(buf.toString());
81         ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
82         text.add(av.getText());
83         text.add("}\n");
84         return av;
85     }
86
87     public void visitCode() {
88         text.add("mv.visitCode();\n");
89     }
90
91     public void visitInsn(final int opcode) {
92         buf.setLength(0);
93         buf.append("mv.visitInsn(").append(OPCODES[opcode]).append(");\n");
94         text.add(buf.toString());
95     }
96
97     public void visitIntInsn(final int opcode, final int operand) {
98         buf.setLength(0);
99         buf.append("mv.visitIntInsn(")
100                 .append(OPCODES[opcode])
101                 .append(", ")
102                 .append(opcode == Opcodes.NEWARRAY
103                         ? TYPES[operand]
104                         : Integer.toString(operand))
105                 .append(");\n");
106         text.add(buf.toString());
107     }
108
109     public void visitVarInsn(final int opcode, final int var) {
110         buf.setLength(0);
111         buf.append("mv.visitVarInsn(")
112                 .append(OPCODES[opcode])
113                 .append(", ")
114                 .append(var)
115                 .append(");\n");
116         text.add(buf.toString());
117     }
118
119     public void visitTypeInsn(final int opcode, final String JavaDoc desc) {
120         buf.setLength(0);
121         buf.append("mv.visitTypeInsn(").append(OPCODES[opcode]).append(", ");
122         appendConstant(desc);
123         buf.append(");\n");
124         text.add(buf.toString());
125     }
126
127     public void visitFieldInsn(
128         final int opcode,
129         final String JavaDoc owner,
130         final String JavaDoc name,
131         final String JavaDoc desc)
132     {
133         buf.setLength(0);
134         buf.append("mv.visitFieldInsn(").append(OPCODES[opcode]).append(", ");
135         appendConstant(owner);
136         buf.append(", ");
137         appendConstant(name);
138         buf.append(", ");
139         appendConstant(desc);
140         buf.append(");\n");
141         text.add(buf.toString());
142     }
143
144     public void visitMethodInsn(
145         final int opcode,
146         final String JavaDoc owner,
147         final String JavaDoc name,
148         final String JavaDoc desc)
149     {
150         buf.setLength(0);
151         buf.append("mv.visitMethodInsn(").append(OPCODES[opcode]).append(", ");
152         appendConstant(owner);
153         buf.append(", ");
154         appendConstant(name);
155         buf.append(", ");
156         appendConstant(desc);
157         buf.append(");\n");
158         text.add(buf.toString());
159     }
160
161     public void visitJumpInsn(final int opcode, final Label label) {
162         buf.setLength(0);
163         declareLabel(label);
164         buf.append("mv.visitJumpInsn(").append(OPCODES[opcode]).append(", ");
165         appendLabel(label);
166         buf.append(");\n");
167         text.add(buf.toString());
168     }
169
170     public void visitLabel(final Label label) {
171         buf.setLength(0);
172         declareLabel(label);
173         buf.append("mv.visitLabel(");
174         appendLabel(label);
175         buf.append(");\n");
176         text.add(buf.toString());
177     }
178
179     public void visitLdcInsn(final Object JavaDoc cst) {
180         buf.setLength(0);
181         buf.append("mv.visitLdcInsn(");
182         appendConstant(cst);
183         buf.append(");\n");
184         text.add(buf.toString());
185     }
186
187     public void visitIincInsn(final int var, final int increment) {
188         buf.setLength(0);
189         buf.append("mv.visitIincInsn(")
190                 .append(var)
191                 .append(", ")
192                 .append(increment)
193                 .append(");\n");
194         text.add(buf.toString());
195     }
196
197     public void visitTableSwitchInsn(
198         final int min,
199         final int max,
200         final Label dflt,
201         final Label labels[])
202     {
203         buf.setLength(0);
204         for (int i = 0; i < labels.length; ++i) {
205             declareLabel(labels[i]);
206         }
207         declareLabel(dflt);
208
209         buf.append("mv.visitTableSwitchInsn(")
210                 .append(min)
211                 .append(", ")
212                 .append(max)
213                 .append(", ");
214         appendLabel(dflt);
215         buf.append(", new Label[] {");
216         for (int i = 0; i < labels.length; ++i) {
217             buf.append(i == 0 ? " " : ", ");
218             appendLabel(labels[i]);
219         }
220         buf.append(" });\n");
221         text.add(buf.toString());
222     }
223
224     public void visitLookupSwitchInsn(
225         final Label dflt,
226         final int keys[],
227         final Label labels[])
228     {
229         buf.setLength(0);
230         for (int i = 0; i < labels.length; ++i) {
231             declareLabel(labels[i]);
232         }
233         declareLabel(dflt);
234
235         buf.append("mv.visitLookupSwitchInsn(");
236         appendLabel(dflt);
237         buf.append(", new int[] {");
238         for (int i = 0; i < keys.length; ++i) {
239             buf.append(i == 0 ? " " : ", ").append(keys[i]);
240         }
241         buf.append(" }, new Label[] {");
242         for (int i = 0; i < labels.length; ++i) {
243             buf.append(i == 0 ? " " : ", ");
244             appendLabel(labels[i]);
245         }
246         buf.append(" });\n");
247         text.add(buf.toString());
248     }
249
250     public void visitMultiANewArrayInsn(final String JavaDoc desc, final int dims) {
251         buf.setLength(0);
252         buf.append("mv.visitMultiANewArrayInsn(");
253         appendConstant(desc);
254         buf.append(", ").append(dims).append(");\n");
255         text.add(buf.toString());
256     }
257
258     public void visitTryCatchBlock(
259         final Label start,
260         final Label end,
261         final Label handler,
262         final String JavaDoc type)
263     {
264         buf.setLength(0);
265         declareLabel(start);
266         declareLabel(end);
267         declareLabel(handler);
268         buf.append("mv.visitTryCatchBlock(");
269         appendLabel(start);
270         buf.append(", ");
271         appendLabel(end);
272         buf.append(", ");
273         appendLabel(handler);
274         buf.append(", ");
275         appendConstant(type);
276         buf.append(");\n");
277         text.add(buf.toString());
278     }
279
280     public void visitLocalVariable(
281         final String JavaDoc name,
282         final String JavaDoc desc,
283         final String JavaDoc signature,
284         final Label start,
285         final Label end,
286         final int index)
287     {
288         buf.setLength(0);
289         buf.append("mv.visitLocalVariable(");
290         appendConstant(name);
291         buf.append(", ");
292         appendConstant(desc);
293         buf.append(", ");
294         appendConstant(signature);
295         buf.append(", ");
296         appendLabel(start);
297         buf.append(", ");
298         appendLabel(end);
299         buf.append(", ").append(index).append(");\n");
300         text.add(buf.toString());
301     }
302
303     public void visitLineNumber(final int line, final Label start) {
304         buf.setLength(0);
305         buf.append("mv.visitLineNumber(").append(line).append(", ");
306         appendLabel(start);
307         buf.append(");\n");
308         text.add(buf.toString());
309     }
310
311     public void visitMaxs(final int maxStack, final int maxLocals) {
312         buf.setLength(0);
313         buf.append("mv.visitMaxs(")
314                 .append(maxStack)
315                 .append(", ")
316                 .append(maxLocals)
317                 .append(");\n");
318         text.add(buf.toString());
319     }
320
321     /**
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.
325      *
326      * @param l a label.
327      */

328     private void declareLabel(final Label l) {
329         String JavaDoc name = (String JavaDoc) labelNames.get(l);
330         if (name == null) {
331             name = "l" + labelNames.size();
332             labelNames.put(l, name);
333             buf.append("Label ").append(name).append(" = new Label();\n");
334         }
335     }
336
337     /**
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.
341      *
342      * @param l a label.
343      */

344     private void appendLabel(final Label l) {
345         buf.append((String JavaDoc) labelNames.get(l));
346     }
347 }
348
Popular Tags