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 org.objectweb.asm.Attribute;
33 import org.objectweb.asm.ClassVisitor;
34 import org.objectweb.asm.MethodVisitor;
35 import org.objectweb.asm.FieldVisitor;
36 
37 import java.util.List;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 
41 /**
42  * A node that represents a class.
43  *
44  * @author Eric Bruneton
45  */
46 public class ClassNode extends MemberNode implements ClassVisitor {
47 
48     /**
49      * The class version.
50      */
51     public int version;
52 
53     /**
54      * The class's access flags (see {@link org.objectweb.asm.Opcodes}). This
55      * field also indicates if the class is deprecated.
56      */
57     public int access;
58 
59     /**
60      * The internal name of the class (see
61      * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
62      */
63     public String name;
64 
65     /**
66      * The signature of the class. Mayt be <tt>null</tt>.
67      */
68     public String signature;
69 
70     /**
71      * The internal of name of the super class (see
72      * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). For
73      * interfaces, the super class is {@link Object}. May be <tt>null</tt>,
74      * but only for the {@link Object} class.
75      */
76     public String superName;
77 
78     /**
79      * The internal names of the class's interfaces (see
80      * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This
81      * list is a list of {@link String} objects.
82      */
83     public List interfaces;
84 
85     /**
86      * The name of the source file from which this class was compiled. May be
87      * <tt>null</tt>.
88      */
89     public String sourceFile;
90 
91     /**
92      * Debug information to compute the correspondance between source and
93      * compiled elements of the class. May be <tt>null</tt>.
94      */
95     public String sourceDebug;
96 
97     /**
98      * The internal name of the enclosing class of the class. May be
99      * <tt>null</tt>.
100      */
101     public String outerClass;
102 
103     /**
104      * The name of the method that contains the class, or <tt>null</tt> if the
105      * class is not enclosed in a method.
106      */
107     public String outerMethod;
108 
109     /**
110      * The descriptor of the method that contains the class, or <tt>null</tt>
111      * if the class is not enclosed in a method.
112      */
113     public String outerMethodDesc;
114 
115     /**
116      * Informations about the inner classes of this class. This list is a list
117      * of {@link InnerClassNode} objects.
118      *
119      * @associates org.objectweb.asm.tree.InnerClassNode
120      */
121     public List innerClasses;
122 
123     /**
124      * The fields of this class. This list is a list of {@link FieldNode}
125      * objects.
126      *
127      * @associates org.objectweb.asm.tree.FieldNode
128      */
129     public List fields;
130 
131     /**
132      * The methods of this class. This list is a list of {@link MethodNode}
133      * objects.
134      *
135      * @associates org.objectweb.asm.tree.MethodNode
136      */
137     public List methods;
138 
139     /**
140      * Constructs a new {@link ClassNode}.
141      */
ClassNode()142     public ClassNode() {
143         this.interfaces = new ArrayList();
144         this.innerClasses = new ArrayList();
145         this.fields = new ArrayList();
146         this.methods = new ArrayList();
147     }
148 
149     // ------------------------------------------------------------------------
150     // Implementation of the ClassVisitor interface
151     // ------------------------------------------------------------------------
152 
visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)153     public void visit(
154         final int version,
155         final int access,
156         final String name,
157         final String signature,
158         final String superName,
159         final String[] interfaces)
160     {
161         this.version = version;
162         this.access = access;
163         this.name = name;
164         this.signature = signature;
165         this.superName = superName;
166         if (interfaces != null) {
167             this.interfaces.addAll(Arrays.asList(interfaces));
168         }
169     }
170 
visitSource(final String file, final String debug)171     public void visitSource(final String file, final String debug) {
172         sourceFile = file;
173         sourceDebug = debug;
174     }
175 
visitOuterClass( final String owner, final String name, final String desc)176     public void visitOuterClass(
177         final String owner,
178         final String name,
179         final String desc)
180     {
181         outerClass = owner;
182         outerMethod = name;
183         outerMethodDesc = desc;
184     }
185 
visitInnerClass( final String name, final String outerName, final String innerName, final int access)186     public void visitInnerClass(
187         final String name,
188         final String outerName,
189         final String innerName,
190         final int access)
191     {
192         InnerClassNode icn = new InnerClassNode(name,
193                 outerName,
194                 innerName,
195                 access);
196         innerClasses.add(icn);
197     }
198 
visitField( final int access, final String name, final String desc, final String signature, final Object value)199     public FieldVisitor visitField(
200         final int access,
201         final String name,
202         final String desc,
203         final String signature,
204         final Object value)
205     {
206         FieldNode fn = new FieldNode(access, name, desc, signature, value);
207         fields.add(fn);
208         return fn;
209     }
210 
visitMethod( final int access, final String name, final String desc, final String signature, final String[] exceptions)211     public MethodVisitor visitMethod(
212         final int access,
213         final String name,
214         final String desc,
215         final String signature,
216         final String[] exceptions)
217     {
218         MethodNode mn = new MethodNode(access,
219                 name,
220                 desc,
221                 signature,
222                 exceptions);
223         methods.add(mn);
224         return mn;
225     }
226 
visitEnd()227     public void visitEnd() {
228     }
229 
230     // ------------------------------------------------------------------------
231     // Accept method
232     // ------------------------------------------------------------------------
233 
234     /**
235      * Makes the given class visitor visit this class.
236      *
237      * @param cv a class visitor.
238      */
accept(final ClassVisitor cv)239     public void accept(final ClassVisitor cv) {
240         // visits header
241         String[] interfaces = new String[this.interfaces.size()];
242         this.interfaces.toArray(interfaces);
243         cv.visit(version, access, name, signature, superName, interfaces);
244         // visits source
245         if (sourceFile != null || sourceDebug != null) {
246             cv.visitSource(sourceFile, sourceDebug);
247         }
248         // visits outer class
249         if (outerClass != null) {
250             cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
251         }
252         // visits attributes
253         int i, n;
254         n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
255         for (i = 0; i < n; ++i) {
256             AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i);
257             an.accept(cv.visitAnnotation(an.desc, true));
258         }
259         n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
260         for (i = 0; i < n; ++i) {
261             AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i);
262             an.accept(cv.visitAnnotation(an.desc, false));
263         }
264         n = attrs == null ? 0 : attrs.size();
265         for (i = 0; i < n; ++i) {
266             cv.visitAttribute((Attribute) attrs.get(i));
267         }
268         // visits inner classes
269         for (i = 0; i < innerClasses.size(); ++i) {
270             ((InnerClassNode) innerClasses.get(i)).accept(cv);
271         }
272         // visits fields
273         for (i = 0; i < fields.size(); ++i) {
274             ((FieldNode) fields.get(i)).accept(cv);
275         }
276         // visits methods
277         for (i = 0; i < methods.size(); ++i) {
278             ((MethodNode) methods.get(i)).accept(cv);
279         }
280         // visits end
281         cv.visitEnd();
282     }
283 }
284