1/*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2007 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 */ 30package org.mockito.asm.tree; 31 32import org.mockito.asm.Attribute; 33import org.mockito.asm.ClassVisitor; 34import org.mockito.asm.FieldVisitor; 35import org.mockito.asm.MethodVisitor; 36 37import java.util.List; 38import java.util.ArrayList; 39import java.util.Arrays; 40 41/** 42 * A node that represents a class. 43 * 44 * @author Eric Bruneton 45 */ 46public 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.mockito.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.mockito.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.mockito.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.mockito.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.mockito.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.mockito.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.mockito.asm.tree.MethodNode 136 */ 137 public List methods; 138 139 /** 140 * Constructs a new {@link ClassNode}. 141 */ 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 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 171 public void visitSource(final String file, final String debug) { 172 sourceFile = file; 173 sourceDebug = debug; 174 } 175 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 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 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 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 227 // ------------------------------------------------------------------------ 228 // Accept method 229 // ------------------------------------------------------------------------ 230 231 /** 232 * Makes the given class visitor visit this class. 233 * 234 * @param cv a class visitor. 235 */ 236 public void accept(final ClassVisitor cv) { 237 // visits header 238 String[] interfaces = new String[this.interfaces.size()]; 239 this.interfaces.toArray(interfaces); 240 cv.visit(version, access, name, signature, superName, interfaces); 241 // visits source 242 if (sourceFile != null || sourceDebug != null) { 243 cv.visitSource(sourceFile, sourceDebug); 244 } 245 // visits outer class 246 if (outerClass != null) { 247 cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); 248 } 249 // visits attributes 250 int i, n; 251 n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); 252 for (i = 0; i < n; ++i) { 253 AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i); 254 an.accept(cv.visitAnnotation(an.desc, true)); 255 } 256 n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); 257 for (i = 0; i < n; ++i) { 258 AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i); 259 an.accept(cv.visitAnnotation(an.desc, false)); 260 } 261 n = attrs == null ? 0 : attrs.size(); 262 for (i = 0; i < n; ++i) { 263 cv.visitAttribute((Attribute) attrs.get(i)); 264 } 265 // visits inner classes 266 for (i = 0; i < innerClasses.size(); ++i) { 267 ((InnerClassNode) innerClasses.get(i)).accept(cv); 268 } 269 // visits fields 270 for (i = 0; i < fields.size(); ++i) { 271 ((FieldNode) fields.get(i)).accept(cv); 272 } 273 // visits methods 274 for (i = 0; i < methods.size(); ++i) { 275 ((MethodNode) methods.get(i)).accept(cv); 276 } 277 // visits end 278 cv.visitEnd(); 279 } 280} 281