• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 org.objectweb.asm.tree;
31 
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 
36 import org.objectweb.asm.AnnotationVisitor;
37 import org.objectweb.asm.Attribute;
38 import org.objectweb.asm.ClassVisitor;
39 import org.objectweb.asm.Handle;
40 import org.objectweb.asm.TypeAnnotationVisitor;
41 import org.objectweb.asm.Label;
42 import org.objectweb.asm.MethodVisitor;
43 import org.objectweb.asm.Opcodes;
44 import org.objectweb.asm.Type;
45 import org.objectweb.asm.TypePath;
46 
47 /**
48  * A node that represents a method.
49  *
50  * @author Eric Bruneton
51  */
52 public class MethodNode extends MemberNode implements MethodVisitor {
53 
54     // jaime
visitTypeAnnotation(String desc, boolean visible, boolean inCode)55     public TypeAnnotationVisitor visitTypeAnnotation(String desc,
56         boolean visible,
57         boolean inCode)
58     {
59         return null;
60     }
61     //end jaime
62 
63     /**
64      * The method's access flags (see {@link Opcodes}). This field also
65      * indicates if the method is synthetic and/or deprecated.
66      */
67     public int access;
68 
69     /**
70      * The method's name.
71      */
72     public String name;
73 
74     /**
75      * The method's descriptor (see {@link Type}).
76      */
77     public String desc;
78 
79     /**
80      * The method's signature. May be <tt>null</tt>.
81      */
82     public String signature;
83 
84     /**
85      * The internal names of the method's exception classes (see
86      * {@link Type#getInternalName() getInternalName}). This list is a list of
87      * {@link String} objects.
88      */
89     public List exceptions;
90 
91     /**
92      * The default value of this annotation interface method. This field must be
93      * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},
94      * {@link Integer}, {@link Long}, {@link Float}, {@link Double},
95      * {@link String} or {@link Type}, or an two elements String array (for
96      * enumeration values), a {@link AnnotationNode}, or a {@link List} of
97      * values of one of the preceding types. May be <tt>null</tt>.
98      */
99     public Object annotationDefault;
100 
101     /**
102      * The runtime visible parameter annotations of this method. These lists are
103      * lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
104      *
105      * @associates org.objectweb.asm.tree.AnnotationNode
106      * @label invisible parameters
107      */
108     public List[] visibleParameterAnnotations;
109 
110     /**
111      * The runtime invisible parameter annotations of this method. These lists
112      * are lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
113      *
114      * @associates org.objectweb.asm.tree.AnnotationNode
115      * @label visible parameters
116      */
117     public List[] invisibleParameterAnnotations;
118 
119     /**
120      * The instructions of this method. This list is a list of
121      * {@link AbstractInsnNode} objects.
122      *
123      * @associates org.objectweb.asm.tree.AbstractInsnNode
124      * @label instructions
125      */
126     public List instructions;
127 
128     /**
129      * The try catch blocks of this method. This list is a list of
130      * {@link TryCatchBlockNode} objects.
131      *
132      * @associates org.objectweb.asm.tree.TryCatchBlockNode
133      */
134     public List tryCatchBlocks;
135 
136     /**
137      * The maximum stack size of this method.
138      */
139     public int maxStack;
140 
141     /**
142      * The maximum number of local variables of this method.
143      */
144     public int maxLocals;
145 
146     /**
147      * The local variables of this method. This list is a list of
148      * {@link LocalVariableNode} objects. May be <tt>null</tt>
149      *
150      * @associates org.objectweb.asm.tree.LocalVariableNode
151      */
152     public List localVariables;
153 
154     /**
155      * The line numbers of this method. This list is a list of
156      * {@link LineNumberNode} objects. May be <tt>null</tt>
157      *
158      * @associates org.objectweb.asm.tree.LineNumberNode
159      */
160     public List lineNumbers;
161 
162     /**
163      * Constructs a new {@link MethodNode}.
164      *
165      * @param access the method's access flags (see {@link Opcodes}). This
166      *        parameter also indicates if the method is synthetic and/or
167      *        deprecated.
168      * @param name the method's name.
169      * @param desc the method's descriptor (see {@link Type}).
170      * @param signature the method's signature. May be <tt>null</tt>.
171      * @param exceptions the internal names of the method's exception classes
172      *        (see {@link Type#getInternalName() getInternalName}). May be
173      *        <tt>null</tt>.
174      */
MethodNode( final int access, final String name, final String desc, final String signature, final String[] exceptions)175     public MethodNode(
176         final int access,
177         final String name,
178         final String desc,
179         final String signature,
180         final String[] exceptions)
181     {
182         this.access = access;
183         this.name = name;
184         this.desc = desc;
185         this.signature = signature;
186         this.exceptions = new ArrayList(exceptions == null
187                 ? 0
188                 : exceptions.length);
189         boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
190         this.instructions = new ArrayList(isAbstract ? 0 : 24);
191         if (!isAbstract) {
192             this.localVariables = new ArrayList(5);
193             this.lineNumbers = new ArrayList(5);
194         }
195         this.tryCatchBlocks = new ArrayList();
196         if (exceptions != null) {
197             this.exceptions.addAll(Arrays.asList(exceptions));
198         }
199     }
200 
201     // ------------------------------------------------------------------------
202     // Implementation of the MethodVisitor interface
203     // ------------------------------------------------------------------------
204 
visitAnnotationDefault()205     public AnnotationVisitor visitAnnotationDefault() {
206         return new AnnotationNode(new ArrayList(0) {
207             public boolean add(Object o) {
208                 annotationDefault = o;
209                 return super.add(o);
210             }
211         });
212     }
213 
214     public AnnotationVisitor visitParameterAnnotation(
215         final int parameter,
216         final String desc,
217         final boolean visible)
218     {
219         AnnotationNode an = new AnnotationNode(desc);
220         if (visible) {
221             if (visibleParameterAnnotations == null) {
222                 int params = Type.getArgumentTypes(this.desc).length;
223                 visibleParameterAnnotations = new List[params];
224             }
225             if (visibleParameterAnnotations[parameter] == null) {
226                 visibleParameterAnnotations[parameter] = new ArrayList(1);
227             }
228             visibleParameterAnnotations[parameter].add(an);
229         } else {
230             if (invisibleParameterAnnotations == null) {
231                 int params = Type.getArgumentTypes(this.desc).length;
232                 invisibleParameterAnnotations = new List[params];
233             }
234             if (invisibleParameterAnnotations[parameter] == null) {
235                 invisibleParameterAnnotations[parameter] = new ArrayList(1);
236             }
237             invisibleParameterAnnotations[parameter].add(an);
238         }
239         return an;
240     }
241 
242     public void visitCode() {
243     }
244 
245     public void visitInsn(final int opcode) {
246         instructions.add(new InsnNode(opcode));
247     }
248 
249     public void visitIntInsn(final int opcode, final int operand) {
250         instructions.add(new IntInsnNode(opcode, operand));
251     }
252 
253     public void visitVarInsn(final int opcode, final int var) {
254         instructions.add(new VarInsnNode(opcode, var));
255     }
256 
257     public void visitTypeInsn(final int opcode, final String desc) {
258         instructions.add(new TypeInsnNode(opcode, desc));
259     }
260 
261     public void visitFieldInsn(
262         final int opcode,
263         final String owner,
264         final String name,
265         final String desc)
266     {
267         instructions.add(new FieldInsnNode(opcode, owner, name, desc));
268     }
269 
270     public void visitMethodInsn(
271         final int opcode,
272         final String owner,
273         final String name,
274         final String desc)
275     {
276         instructions.add(new MethodInsnNode(opcode, owner, name, desc));
277     }
278 
279     @Override
280     public void visitInvokeDynamicInsn(
281         String name,
282         String desc,
283         Handle bsm,
284         Object... bsmArgs)
285     {
286         instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs));
287     }
288 
289     public void visitJumpInsn(final int opcode, final Label label) {
290         instructions.add(new JumpInsnNode(opcode, label));
291     }
292 
293     public void visitLabel(final Label label) {
294         instructions.add(new LabelNode(label));
295     }
296 
297     public void visitLdcInsn(final Object cst) {
298         instructions.add(new LdcInsnNode(cst));
299     }
300 
301     public void visitIincInsn(final int var, final int increment) {
302         instructions.add(new IincInsnNode(var, increment));
303     }
304 
305     public void visitTableSwitchInsn(
306         final int min,
307         final int max,
308         final Label dflt,
309         final Label[] labels)
310     {
311         instructions.add(new TableSwitchInsnNode(min, max, dflt, labels));
312     }
313 
314     public void visitLookupSwitchInsn(
315         final Label dflt,
316         final int[] keys,
317         final Label[] labels)
318     {
319         instructions.add(new LookupSwitchInsnNode(dflt, keys, labels));
320     }
321 
322     public void visitMultiANewArrayInsn(final String desc, final int dims) {
323         instructions.add(new MultiANewArrayInsnNode(desc, dims));
324     }
325 
326     public void visitTryCatchBlock(
327         final Label start,
328         final Label end,
329         final Label handler,
330         final String type)
331     {
332         tryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, type));
333     }
334 
335     public void visitLocalVariable(
336         final String name,
337         final String desc,
338         final String signature,
339         final Label start,
340         final Label end,
341         final int index)
342     {
343         localVariables.add(new LocalVariableNode(name,
344                 desc,
345                 signature,
346                 start,
347                 end,
348                 index));
349     }
350 
351     public void visitLineNumber(final int line, final Label start) {
352         lineNumbers.add(new LineNumberNode(line, start));
353     }
354 
355     public void visitMaxs(final int maxStack, final int maxLocals) {
356         this.maxStack = maxStack;
357         this.maxLocals = maxLocals;
358     }
359 
360     // ------------------------------------------------------------------------
361     // Accept method
362     // ------------------------------------------------------------------------
363 
364     /**
365      * Makes the given class visitor visit this method.
366      *
367      * @param cv a class visitor.
368      */
369     public void accept(final ClassVisitor cv) {
370         String[] exceptions = new String[this.exceptions.size()];
371         this.exceptions.toArray(exceptions);
372         MethodVisitor mv = cv.visitMethod(access,
373                 name,
374                 desc,
375                 signature,
376                 exceptions);
377         if (mv != null) {
378             accept(mv);
379         }
380     }
381 
382     /**
383      * Makes the given method visitor visit this method.
384      *
385      * @param mv a method visitor.
386      */
387     public void accept(final MethodVisitor mv) {
388         // visits the method attributes
389         int i, j, n;
390         if (annotationDefault != null) {
391             AnnotationVisitor av = mv.visitAnnotationDefault();
392             AnnotationNode.accept(av, null, annotationDefault);
393             av.visitEnd();
394         }
395         n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
396         for (i = 0; i < n; ++i) {
397             AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i);
398             an.accept(mv.visitAnnotation(an.desc, true));
399         }
400         n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
401         for (i = 0; i < n; ++i) {
402             AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i);
403             an.accept(mv.visitAnnotation(an.desc, false));
404         }
405         n = visibleParameterAnnotations == null
406                 ? 0
407                 : visibleParameterAnnotations.length;
408         for (i = 0; i < n; ++i) {
409             List l = visibleParameterAnnotations[i];
410             if (l == null) {
411                 continue;
412             }
413             for (j = 0; j < l.size(); ++j) {
414                 AnnotationNode an = (AnnotationNode) l.get(j);
415                 an.accept(mv.visitParameterAnnotation(i, an.desc, true));
416             }
417         }
418         n = invisibleParameterAnnotations == null
419                 ? 0
420                 : invisibleParameterAnnotations.length;
421         for (i = 0; i < n; ++i) {
422             List l = invisibleParameterAnnotations[i];
423             if (l == null) {
424                 continue;
425             }
426             for (j = 0; j < l.size(); ++j) {
427                 AnnotationNode an = (AnnotationNode) l.get(j);
428                 an.accept(mv.visitParameterAnnotation(i, an.desc, false));
429             }
430         }
431         n = attrs == null ? 0 : attrs.size();
432         for (i = 0; i < n; ++i) {
433             mv.visitAttribute((Attribute) attrs.get(i));
434         }
435         // visits the method's code
436         if (instructions.size() > 0) {
437             mv.visitCode();
438             // visits try catch blocks
439             for (i = 0; i < tryCatchBlocks.size(); ++i) {
440                 ((TryCatchBlockNode) tryCatchBlocks.get(i)).accept(mv);
441             }
442             // visits instructions
443             for (i = 0; i < instructions.size(); ++i) {
444                 ((AbstractInsnNode) instructions.get(i)).accept(mv);
445             }
446             // visits local variables
447             n = localVariables == null ? 0 : localVariables.size();
448             for (i = 0; i < n; ++i) {
449                 ((LocalVariableNode) localVariables.get(i)).accept(mv);
450             }
451             // visits line numbers
452             n = lineNumbers == null ? 0 : lineNumbers.size();
453             for (i = 0; i < n; ++i) {
454                 ((LineNumberNode) lineNumbers.get(i)).accept(mv);
455             }
456             // visits maxs
457             mv.visitMaxs(maxStack, maxLocals);
458         }
459         mv.visitEnd();
460     }
461 
462     @Override
463     public AnnotationVisitor visitInsnAnnotation(int typeRef,
464         TypePath typePath, String desc, boolean visible) {
465       // TODO Auto-generated method stub
466       return null;
467     }
468 }
469