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