001/*** 002 * ASM: a very small and fast Java bytecode manipulation framework 003 * Copyright (c) 2000-2011 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 */ 030package org.springframework.asm; 031 032/** 033 * A visitor to visit a Java class. The methods of this class must be called in 034 * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [ 035 * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> | 036 * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* ( 037 * <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )* 038 * <tt>visitEnd</tt>. 039 * 040 * @author Eric Bruneton 041 */ 042public abstract class ClassVisitor { 043 044 /** 045 * The ASM API version implemented by this visitor. The value of this field 046 * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. 047 */ 048 protected final int api; 049 050 /** 051 * The class visitor to which this visitor must delegate method calls. May 052 * be null. 053 */ 054 protected ClassVisitor cv; 055 056 /** 057 * Constructs a new {@link ClassVisitor}. 058 * 059 * @param api 060 * the ASM API version implemented by this visitor. Must be one 061 * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. 062 */ 063 public ClassVisitor(final int api) { 064 this(api, null); 065 } 066 067 /** 068 * Constructs a new {@link ClassVisitor}. 069 * 070 * @param api 071 * the ASM API version implemented by this visitor. Must be one 072 * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. 073 * @param cv 074 * the class visitor to which this visitor must delegate method 075 * calls. May be null. 076 */ 077 public ClassVisitor(final int api, final ClassVisitor cv) { 078 if (api < Opcodes.ASM4 || api > Opcodes.ASM6) { 079 throw new IllegalArgumentException(); 080 } 081 this.api = api; 082 this.cv = cv; 083 } 084 085 /** 086 * Visits the header of the class. 087 * 088 * @param version 089 * the class version. 090 * @param access 091 * the class's access flags (see {@link Opcodes}). This parameter 092 * also indicates if the class is deprecated. 093 * @param name 094 * the internal name of the class (see 095 * {@link Type#getInternalName() getInternalName}). 096 * @param signature 097 * the signature of this class. May be <tt>null</tt> if the class 098 * is not a generic one, and does not extend or implement generic 099 * classes or interfaces. 100 * @param superName 101 * the internal of name of the super class (see 102 * {@link Type#getInternalName() getInternalName}). For 103 * interfaces, the super class is {@link Object}. May be 104 * <tt>null</tt>, but only for the {@link Object} class. 105 * @param interfaces 106 * the internal names of the class's interfaces (see 107 * {@link Type#getInternalName() getInternalName}). May be 108 * <tt>null</tt>. 109 */ 110 public void visit(int version, int access, String name, String signature, 111 String superName, String[] interfaces) { 112 if (cv != null) { 113 cv.visit(version, access, name, signature, superName, interfaces); 114 } 115 } 116 117 /** 118 * Visits the source of the class. 119 * 120 * @param source 121 * the name of the source file from which the class was compiled. 122 * May be <tt>null</tt>. 123 * @param debug 124 * additional debug information to compute the correspondance 125 * between source and compiled elements of the class. May be 126 * <tt>null</tt>. 127 */ 128 public void visitSource(String source, String debug) { 129 if (cv != null) { 130 cv.visitSource(source, debug); 131 } 132 } 133 134 /** 135 * Visit the module corresponding to the class. 136 * @param name 137 * module name 138 * @param access 139 * module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} 140 * and {@code ACC_MANDATED}. 141 * @param version 142 * module version or null. 143 * @return a visitor to visit the module values, or <tt>null</tt> if 144 * this visitor is not interested in visiting this module. 145 */ 146 public ModuleVisitor visitModule(String name, int access, String version) { 147 if (api < Opcodes.ASM6) { 148 throw new RuntimeException(); 149 } 150 if (cv != null) { 151 return cv.visitModule(name, access, version); 152 } 153 return null; 154 } 155 156 /** 157 * Visits the enclosing class of the class. This method must be called only 158 * if the class has an enclosing class. 159 * 160 * @param owner 161 * internal name of the enclosing class of the class. 162 * @param name 163 * the name of the method that contains the class, or 164 * <tt>null</tt> if the class is not enclosed in a method of its 165 * enclosing class. 166 * @param desc 167 * the descriptor of the method that contains the class, or 168 * <tt>null</tt> if the class is not enclosed in a method of its 169 * enclosing class. 170 */ 171 public void visitOuterClass(String owner, String name, String desc) { 172 if (cv != null) { 173 cv.visitOuterClass(owner, name, desc); 174 } 175 } 176 177 /** 178 * Visits an annotation of the class. 179 * 180 * @param desc 181 * the class descriptor of the annotation class. 182 * @param visible 183 * <tt>true</tt> if the annotation is visible at runtime. 184 * @return a visitor to visit the annotation values, or <tt>null</tt> if 185 * this visitor is not interested in visiting this annotation. 186 */ 187 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 188 if (cv != null) { 189 return cv.visitAnnotation(desc, visible); 190 } 191 return null; 192 } 193 194 /** 195 * Visits an annotation on a type in the class signature. 196 * 197 * @param typeRef 198 * a reference to the annotated type. The sort of this type 199 * reference must be {@link TypeReference#CLASS_TYPE_PARAMETER 200 * CLASS_TYPE_PARAMETER}, 201 * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND 202 * CLASS_TYPE_PARAMETER_BOUND} or 203 * {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See 204 * {@link TypeReference}. 205 * @param typePath 206 * the path to the annotated type argument, wildcard bound, array 207 * element type, or static inner type within 'typeRef'. May be 208 * <tt>null</tt> if the annotation targets 'typeRef' as a whole. 209 * @param desc 210 * the class descriptor of the annotation class. 211 * @param visible 212 * <tt>true</tt> if the annotation is visible at runtime. 213 * @return a visitor to visit the annotation values, or <tt>null</tt> if 214 * this visitor is not interested in visiting this annotation. 215 */ 216 public AnnotationVisitor visitTypeAnnotation(int typeRef, 217 TypePath typePath, String desc, boolean visible) { 218 /* SPRING PATCH: REMOVED FOR COMPATIBILITY WITH CGLIB 3.1 219 if (api < Opcodes.ASM5) { 220 throw new RuntimeException(); 221 } 222 */ 223 if (cv != null) { 224 return cv.visitTypeAnnotation(typeRef, typePath, desc, visible); 225 } 226 return null; 227 } 228 229 /** 230 * Visits a non standard attribute of the class. 231 * 232 * @param attr 233 * an attribute. 234 */ 235 public void visitAttribute(Attribute attr) { 236 if (cv != null) { 237 cv.visitAttribute(attr); 238 } 239 } 240 241 /** 242 * Visits information about an inner class. This inner class is not 243 * necessarily a member of the class being visited. 244 * 245 * @param name 246 * the internal name of an inner class (see 247 * {@link Type#getInternalName() getInternalName}). 248 * @param outerName 249 * the internal name of the class to which the inner class 250 * belongs (see {@link Type#getInternalName() getInternalName}). 251 * May be <tt>null</tt> for not member classes. 252 * @param innerName 253 * the (simple) name of the inner class inside its enclosing 254 * class. May be <tt>null</tt> for anonymous inner classes. 255 * @param access 256 * the access flags of the inner class as originally declared in 257 * the enclosing class. 258 */ 259 public void visitInnerClass(String name, String outerName, 260 String innerName, int access) { 261 if (cv != null) { 262 cv.visitInnerClass(name, outerName, innerName, access); 263 } 264 } 265 266 /** 267 * Visits a field of the class. 268 * 269 * @param access 270 * the field's access flags (see {@link Opcodes}). This parameter 271 * also indicates if the field is synthetic and/or deprecated. 272 * @param name 273 * the field's name. 274 * @param desc 275 * the field's descriptor (see {@link Type Type}). 276 * @param signature 277 * the field's signature. May be <tt>null</tt> if the field's 278 * type does not use generic types. 279 * @param value 280 * the field's initial value. This parameter, which may be 281 * <tt>null</tt> if the field does not have an initial value, 282 * must be an {@link Integer}, a {@link Float}, a {@link Long}, a 283 * {@link Double} or a {@link String} (for <tt>int</tt>, 284 * <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields 285 * respectively). <i>This parameter is only used for static 286 * fields</i>. Its value is ignored for non static fields, which 287 * must be initialized through bytecode instructions in 288 * constructors or methods. 289 * @return a visitor to visit field annotations and attributes, or 290 * <tt>null</tt> if this class visitor is not interested in visiting 291 * these annotations and attributes. 292 */ 293 public FieldVisitor visitField(int access, String name, String desc, 294 String signature, Object value) { 295 if (cv != null) { 296 return cv.visitField(access, name, desc, signature, value); 297 } 298 return null; 299 } 300 301 /** 302 * Visits a method of the class. This method <i>must</i> return a new 303 * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called, 304 * i.e., it should not return a previously returned visitor. 305 * 306 * @param access 307 * the method's access flags (see {@link Opcodes}). This 308 * parameter also indicates if the method is synthetic and/or 309 * deprecated. 310 * @param name 311 * the method's name. 312 * @param desc 313 * the method's descriptor (see {@link Type Type}). 314 * @param signature 315 * the method's signature. May be <tt>null</tt> if the method 316 * parameters, return type and exceptions do not use generic 317 * types. 318 * @param exceptions 319 * the internal names of the method's exception classes (see 320 * {@link Type#getInternalName() getInternalName}). May be 321 * <tt>null</tt>. 322 * @return an object to visit the byte code of the method, or <tt>null</tt> 323 * if this class visitor is not interested in visiting the code of 324 * this method. 325 */ 326 public MethodVisitor visitMethod(int access, String name, String desc, 327 String signature, String[] exceptions) { 328 if (cv != null) { 329 return cv.visitMethod(access, name, desc, signature, exceptions); 330 } 331 return null; 332 } 333 334 /** 335 * Visits the end of the class. This method, which is the last one to be 336 * called, is used to inform the visitor that all the fields and methods of 337 * the class have been visited. 338 */ 339 public void visitEnd() { 340 if (cv != null) { 341 cv.visitEnd(); 342 } 343 } 344}