001: /*
002: * ASM: a very small and fast Java bytecode manipulation framework
003: * Copyright (c) 2000-2005 INRIA, France Telecom
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.objectweb.asm.tree;
031:
032: import org.objectweb.asm.Attribute;
033: import org.objectweb.asm.ClassVisitor;
034: import org.objectweb.asm.MethodVisitor;
035: import org.objectweb.asm.FieldVisitor;
036:
037: import java.util.List;
038: import java.util.ArrayList;
039: import java.util.Arrays;
040:
041: /**
042: * A node that represents a class.
043: *
044: * @author Eric Bruneton
045: */
046: @SuppressWarnings("unchecked")
047: public class ClassNode extends MemberNode implements ClassVisitor {
048:
049: /**
050: * The class version.
051: */
052: public int version;
053:
054: /**
055: * The class's access flags (see {@link org.objectweb.asm.Opcodes}). This
056: * field also indicates if the class is deprecated.
057: */
058: public int access;
059:
060: /**
061: * The internal name of the class (see
062: * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
063: */
064: public String name;
065:
066: /**
067: * The signature of the class. Mayt be <tt>null</tt>.
068: */
069: public String signature;
070:
071: /**
072: * The internal of name of the super class (see
073: * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). For
074: * interfaces, the super class is {@link Object}. May be <tt>null</tt>,
075: * but only for the {@link Object} class.
076: */
077: public String super Name;
078:
079: /**
080: * The internal names of the class's interfaces (see
081: * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This
082: * list is a list of {@link String} objects.
083: */
084: public List interfaces;
085:
086: /**
087: * The name of the source file from which this class was compiled. May be
088: * <tt>null</tt>.
089: */
090: public String sourceFile;
091:
092: /**
093: * Debug information to compute the correspondance between source and
094: * compiled elements of the class. May be <tt>null</tt>.
095: */
096: public String sourceDebug;
097:
098: /**
099: * The internal name of the enclosing class of the class. May be
100: * <tt>null</tt>.
101: */
102: public String outerClass;
103:
104: /**
105: * The name of the method that contains the class, or <tt>null</tt> if the
106: * class is not enclosed in a method.
107: */
108: public String outerMethod;
109:
110: /**
111: * The descriptor of the method that contains the class, or <tt>null</tt>
112: * if the class is not enclosed in a method.
113: */
114: public String outerMethodDesc;
115:
116: /**
117: * Informations about the inner classes of this class. This list is a list
118: * of {@link InnerClassNode} objects.
119: *
120: * @associates org.objectweb.asm.tree.InnerClassNode
121: */
122: public List innerClasses;
123:
124: /**
125: * The fields of this class. This list is a list of {@link FieldNode}
126: * objects.
127: *
128: * @associates org.objectweb.asm.tree.FieldNode
129: */
130: public List fields;
131:
132: /**
133: * The methods of this class. This list is a list of {@link MethodNode}
134: * objects.
135: *
136: * @associates org.objectweb.asm.tree.MethodNode
137: */
138: public List methods;
139:
140: /**
141: * Constructs a new {@link ClassNode}.
142: */
143: public ClassNode() {
144: this .interfaces = new ArrayList();
145: this .innerClasses = new ArrayList();
146: this .fields = new ArrayList();
147: this .methods = new ArrayList();
148: }
149:
150: // ------------------------------------------------------------------------
151: // Implementation of the ClassVisitor interface
152: // ------------------------------------------------------------------------
153:
154: public void visit(final int version, final int access,
155: final String name, final String signature,
156: final String super Name, final String[] interfaces) {
157: this .version = version;
158: this .access = access;
159: this .name = name;
160: this .signature = signature;
161: this .super Name = super Name;
162: if (interfaces != null) {
163: this .interfaces.addAll(Arrays.asList(interfaces));
164: }
165: }
166:
167: public void visitSource(final String file, final String debug) {
168: sourceFile = file;
169: sourceDebug = debug;
170: }
171:
172: public void visitOuterClass(final String owner, final String name,
173: final String desc) {
174: outerClass = owner;
175: outerMethod = name;
176: outerMethodDesc = desc;
177: }
178:
179: public void visitInnerClass(final String name,
180: final String outerName, final String innerName,
181: final int access) {
182: InnerClassNode icn = new InnerClassNode(name, outerName,
183: innerName, access);
184: innerClasses.add(icn);
185: }
186:
187: public FieldVisitor visitField(final int access, final String name,
188: final String desc, final String signature,
189: final Object value) {
190: FieldNode fn = new FieldNode(access, name, desc, signature,
191: value);
192: fields.add(fn);
193: return fn;
194: }
195:
196: public MethodVisitor visitMethod(final int access,
197: final String name, final String desc,
198: final String signature, final String[] exceptions) {
199: MethodNode mn = new MethodNode(access, name, desc, signature,
200: exceptions);
201: methods.add(mn);
202: return mn;
203: }
204:
205: public void visitEnd() {
206: }
207:
208: // ------------------------------------------------------------------------
209: // Accept method
210: // ------------------------------------------------------------------------
211:
212: /**
213: * Makes the given class visitor visit this class.
214: *
215: * @param cv a class visitor.
216: */
217: public void accept(final ClassVisitor cv) {
218: // visits header
219: String[] interfaces = new String[this .interfaces.size()];
220: this .interfaces.toArray(interfaces);
221: cv.visit(version, access, name, signature, super Name,
222: interfaces);
223: // visits source
224: if (sourceFile != null || sourceDebug != null) {
225: cv.visitSource(sourceFile, sourceDebug);
226: }
227: // visits outer class
228: if (outerClass != null) {
229: cv
230: .visitOuterClass(outerClass, outerMethod,
231: outerMethodDesc);
232: }
233: // visits attributes
234: int i, n;
235: n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
236: for (i = 0; i < n; ++i) {
237: AnnotationNode an = (AnnotationNode) visibleAnnotations
238: .get(i);
239: an.accept(cv.visitAnnotation(an.desc, true));
240: }
241: n = invisibleAnnotations == null ? 0 : invisibleAnnotations
242: .size();
243: for (i = 0; i < n; ++i) {
244: AnnotationNode an = (AnnotationNode) invisibleAnnotations
245: .get(i);
246: an.accept(cv.visitAnnotation(an.desc, false));
247: }
248: n = attrs == null ? 0 : attrs.size();
249: for (i = 0; i < n; ++i) {
250: cv.visitAttribute((Attribute) attrs.get(i));
251: }
252: // visits inner classes
253: for (i = 0; i < innerClasses.size(); ++i) {
254: ((InnerClassNode) innerClasses.get(i)).accept(cv);
255: }
256: // visits fields
257: for (i = 0; i < fields.size(); ++i) {
258: ((FieldNode) fields.get(i)).accept(cv);
259: }
260: // visits methods
261: for (i = 0; i < methods.size(); ++i) {
262: ((MethodNode) methods.get(i)).accept(cv);
263: }
264: // visits end
265: cv.visitEnd();
266: }
267: }
|