KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > asm > tree > MethodNode


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.tree;
31
32 import com.tc.asm.AnnotationVisitor;
33 import com.tc.asm.Attribute;
34 import com.tc.asm.ClassVisitor;
35 import com.tc.asm.MethodVisitor;
36 import com.tc.asm.Label;
37 import com.tc.asm.Opcodes;
38 import com.tc.asm.Type;
39
40 import java.util.List JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.Arrays JavaDoc;
43
44 /**
45  * A node that represents a method.
46  *
47  * @author Eric Bruneton
48  */

49 public class MethodNode extends MemberNode implements MethodVisitor {
50
51     /**
52      * The method's access flags (see {@link Opcodes}). This field also
53      * indicates if the method is synthetic and/or deprecated.
54      */

55     public int access;
56
57     /**
58      * The method's name.
59      */

60     public String JavaDoc name;
61
62     /**
63      * The method's descriptor (see {@link Type}).
64      */

65     public String JavaDoc desc;
66
67     /**
68      * The method's signature. May be <tt>null</tt>.
69      */

70     public String JavaDoc signature;
71
72     /**
73      * The internal names of the method's exception classes (see
74      * {@link Type#getInternalName() getInternalName}). This list is a list of
75      * {@link String} objects.
76      */

77     public List JavaDoc exceptions;
78
79     /**
80      * The default value of this annotation interface method. This field must be
81      * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},
82      * {@link Integer}, {@link Long}, {@link Float}, {@link Double},
83      * {@link String} or {@link Type}, or an two elements String array (for
84      * enumeration values), a {@link AnnotationNode}, or a {@link List} of
85      * values of one of the preceding types. May be <tt>null</tt>.
86      */

87     public Object JavaDoc annotationDefault;
88
89     /**
90      * The runtime visible parameter annotations of this method. These lists are
91      * lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
92      *
93      * @associates org.objectweb.asm.tree.AnnotationNode
94      * @label invisible parameters
95      */

96     public List JavaDoc[] visibleParameterAnnotations;
97
98     /**
99      * The runtime invisible parameter annotations of this method. These lists
100      * are lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
101      *
102      * @associates org.objectweb.asm.tree.AnnotationNode
103      * @label visible parameters
104      */

105     public List JavaDoc[] invisibleParameterAnnotations;
106
107     /**
108      * The instructions of this method. This list is a list of
109      * {@link AbstractInsnNode} objects.
110      *
111      * @associates org.objectweb.asm.tree.AbstractInsnNode
112      * @label instructions
113      */

114     public List JavaDoc instructions;
115
116     /**
117      * The try catch blocks of this method. This list is a list of
118      * {@link TryCatchBlockNode} objects.
119      *
120      * @associates org.objectweb.asm.tree.TryCatchBlockNode
121      */

122     public List JavaDoc tryCatchBlocks;
123
124     /**
125      * The maximum stack size of this method.
126      */

127     public int maxStack;
128
129     /**
130      * The maximum number of local variables of this method.
131      */

132     public int maxLocals;
133
134     /**
135      * The local variables of this method. This list is a list of
136      * {@link LocalVariableNode} objects. May be <tt>null</tt>
137      *
138      * @associates org.objectweb.asm.tree.LocalVariableNode
139      */

140     public List JavaDoc localVariables;
141
142     /**
143      * The line numbers of this method. This list is a list of
144      * {@link LineNumberNode} objects. May be <tt>null</tt>
145      *
146      * @associates org.objectweb.asm.tree.LineNumberNode
147      */

148     public List JavaDoc lineNumbers;
149
150     /**
151      * Constructs a new {@link MethodNode}.
152      *
153      * @param access the method's access flags (see {@link Opcodes}). This
154      * parameter also indicates if the method is synthetic and/or
155      * deprecated.
156      * @param name the method's name.
157      * @param desc the method's descriptor (see {@link Type}).
158      * @param signature the method's signature. May be <tt>null</tt>.
159      * @param exceptions the internal names of the method's exception classes
160      * (see {@link Type#getInternalName() getInternalName}). May be
161      * <tt>null</tt>.
162      */

163     public MethodNode(
164         final int access,
165         final String JavaDoc name,
166         final String JavaDoc desc,
167         final String JavaDoc signature,
168         final String JavaDoc[] exceptions)
169     {
170         this.access = access;
171         this.name = name;
172         this.desc = desc;
173         this.signature = signature;
174         this.exceptions = new ArrayList JavaDoc(exceptions == null
175                 ? 0
176                 : exceptions.length);
177         boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
178         this.instructions = new ArrayList JavaDoc(isAbstract ? 0 : 24);
179         if (!isAbstract) {
180             this.localVariables = new ArrayList JavaDoc(5);
181             this.lineNumbers = new ArrayList JavaDoc(5);
182         }
183         this.tryCatchBlocks = new ArrayList JavaDoc();
184         if (exceptions != null) {
185             this.exceptions.addAll(Arrays.asList(exceptions));
186         }
187     }
188
189     // ------------------------------------------------------------------------
190
// Implementation of the MethodVisitor interface
191
// ------------------------------------------------------------------------
192

193     public AnnotationVisitor visitAnnotationDefault() {
194         return new AnnotationNode(new ArrayList JavaDoc(0) {
195             public boolean add(Object JavaDoc o) {
196                 annotationDefault = o;
197                 return super.add(o);
198             }
199         });
200     }
201
202     public AnnotationVisitor visitParameterAnnotation(
203         final int parameter,
204         final String JavaDoc desc,
205         final boolean visible)
206     {
207         AnnotationNode an = new AnnotationNode(desc);
208         if (visible) {
209             if (visibleParameterAnnotations == null) {
210                 int params = Type.getArgumentTypes(this.desc).length;
211                 visibleParameterAnnotations = new List JavaDoc[params];
212             }
213             if (visibleParameterAnnotations[parameter] == null) {
214                 visibleParameterAnnotations[parameter] = new ArrayList JavaDoc(1);
215             }
216             visibleParameterAnnotations[parameter].add(an);
217         } else {
218             if (invisibleParameterAnnotations == null) {
219                 int params = Type.getArgumentTypes(this.desc).length;
220                 invisibleParameterAnnotations = new List JavaDoc[params];
221             }
222             if (invisibleParameterAnnotations[parameter] == null) {
223                 invisibleParameterAnnotations[parameter] = new ArrayList JavaDoc(1);
224             }
225             invisibleParameterAnnotations[parameter].add(an);
226         }
227         return an;
228     }
229
230     public void visitCode() {
231     }
232
233     public void visitInsn(final int opcode) {
234         instructions.add(new InsnNode(opcode));
235     }
236
237     public void visitIntInsn(final int opcode, final int operand) {
238         instructions.add(new IntInsnNode(opcode, operand));
239     }
240
241     public void visitVarInsn(final int opcode, final int var) {
242         instructions.add(new VarInsnNode(opcode, var));
243     }
244
245     public void visitTypeInsn(final int opcode, final String JavaDoc desc) {
246         instructions.add(new TypeInsnNode(opcode, desc));
247     }
248
249     public void visitFieldInsn(
250         final int opcode,
251         final String JavaDoc owner,
252         final String JavaDoc name,
253         final String JavaDoc desc)
254     {
255         instructions.add(new FieldInsnNode(opcode, owner, name, desc));
256     }
257
258     public void visitMethodInsn(
259         final int opcode,
260         final String JavaDoc owner,
261         final String JavaDoc name,
262         final String JavaDoc desc)
263     {
264         instructions.add(new MethodInsnNode(opcode, owner, name, desc));
265     }
266
267     public void visitJumpInsn(final int opcode, final Label label) {
268         instructions.add(new JumpInsnNode(opcode, label));
269     }
270
271     public void visitLabel(final Label label) {
272         instructions.add(new LabelNode(label));
273     }
274
275     public void visitLdcInsn(final Object JavaDoc cst) {
276         instructions.add(new LdcInsnNode(cst));
277     }
278
279     public void visitIincInsn(final int var, final int increment) {
280         instructions.add(new IincInsnNode(var, increment));
281     }
282
283     public void visitTableSwitchInsn(
284         final int min,
285         final int max,
286         final Label dflt,
287         final Label[] labels)
288     {
289         instructions.add(new TableSwitchInsnNode(min, max, dflt, labels));
290     }
291
292     public void visitLookupSwitchInsn(
293         final Label dflt,
294         final int[] keys,
295         final Label[] labels)
296     {
297         instructions.add(new LookupSwitchInsnNode(dflt, keys, labels));
298     }
299
300     public void visitMultiANewArrayInsn(final String JavaDoc desc, final int dims) {
301         instructions.add(new MultiANewArrayInsnNode(desc, dims));
302     }
303
304     public void visitTryCatchBlock(
305         final Label start,
306         final Label end,
307         final Label handler,
308         final String JavaDoc type)
309     {
310         tryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, type));
311     }
312
313     public void visitLocalVariable(
314         final String JavaDoc name,
315         final String JavaDoc desc,
316         final String JavaDoc signature,
317         final Label start,
318         final Label end,
319         final int index)
320     {
321         localVariables.add(new LocalVariableNode(name,
322                 desc,
323                 signature,
324                 start,
325                 end,
326                 index));
327     }
328
329     public void visitLineNumber(final int line, final Label start) {
330         lineNumbers.add(new LineNumberNode(line, start));
331     }
332
333     public void visitMaxs(final int maxStack, final int maxLocals) {
334         this.maxStack = maxStack;
335         this.maxLocals = maxLocals;
336     }
337
338     // ------------------------------------------------------------------------
339
// Accept method
340
// ------------------------------------------------------------------------
341

342     /**
343      * Makes the given class visitor visit this method.
344      *
345      * @param cv a class visitor.
346      */

347     public void accept(final ClassVisitor cv) {
348         String JavaDoc[] exceptions = new String JavaDoc[this.exceptions.size()];
349         this.exceptions.toArray(exceptions);
350         MethodVisitor mv = cv.visitMethod(access,
351                 name,
352                 desc,
353                 signature,
354                 exceptions);
355         if (mv != null) {
356             accept(mv);
357         }
358     }
359     
360     /**
361      * Makes the given method visitor visit this method.
362      *
363      * @param mv a method visitor.
364      */

365     public void accept(final MethodVisitor mv) {
366         // visits the method attributes
367
int i, j, n;
368         if (annotationDefault != null) {
369             AnnotationVisitor av = mv.visitAnnotationDefault();
370             AnnotationNode.accept(av, null, annotationDefault);
371             av.visitEnd();
372         }
373         n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
374         for (i = 0; i < n; ++i) {
375             AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i);
376             an.accept(mv.visitAnnotation(an.desc, true));
377         }
378         n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
379         for (i = 0; i < n; ++i) {
380             AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i);
381             an.accept(mv.visitAnnotation(an.desc, false));
382         }
383         n = visibleParameterAnnotations == null
384                 ? 0
385                 : visibleParameterAnnotations.length;
386         for (i = 0; i < n; ++i) {
387             List JavaDoc l = visibleParameterAnnotations[i];
388             if (l == null) {
389                 continue;
390             }
391             for (j = 0; j < l.size(); ++j) {
392                 AnnotationNode an = (AnnotationNode) l.get(j);
393                 an.accept(mv.visitParameterAnnotation(i, an.desc, true));
394             }
395         }
396         n = invisibleParameterAnnotations == null
397                 ? 0
398                 : invisibleParameterAnnotations.length;
399         for (i = 0; i < n; ++i) {
400             List JavaDoc l = invisibleParameterAnnotations[i];
401             if (l == null) {
402                 continue;
403             }
404             for (j = 0; j < l.size(); ++j) {
405                 AnnotationNode an = (AnnotationNode) l.get(j);
406                 an.accept(mv.visitParameterAnnotation(i, an.desc, false));
407             }
408         }
409         n = attrs == null ? 0 : attrs.size();
410         for (i = 0; i < n; ++i) {
411             mv.visitAttribute((Attribute) attrs.get(i));
412         }
413         // visits the method's code
414
if (instructions.size() > 0) {
415             mv.visitCode();
416             // visits try catch blocks
417
for (i = 0; i < tryCatchBlocks.size(); ++i) {
418                 ((TryCatchBlockNode) tryCatchBlocks.get(i)).accept(mv);
419             }
420             // visits instructions
421
for (i = 0; i < instructions.size(); ++i) {
422                 ((AbstractInsnNode) instructions.get(i)).accept(mv);
423             }
424             // visits local variables
425
n = localVariables == null ? 0 : localVariables.size();
426             for (i = 0; i < n; ++i) {
427                 ((LocalVariableNode) localVariables.get(i)).accept(mv);
428             }
429             // visits line numbers
430
n = lineNumbers == null ? 0 : lineNumbers.size();
431             for (i = 0; i < n; ++i) {
432                 ((LineNumberNode) lineNumbers.get(i)).accept(mv);
433             }
434             // visits maxs
435
mv.visitMaxs(maxStack, maxLocals);
436         }
437         mv.visitEnd();
438     }
439 }
440
Popular Tags