51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59 package jdk.internal.org.objectweb.asm.tree; 60 61 import java.util.ArrayList; 62 import java.util.Arrays; 63 import java.util.List; 64 65 import jdk.internal.org.objectweb.asm.AnnotationVisitor; 66 import jdk.internal.org.objectweb.asm.Attribute; 67 import jdk.internal.org.objectweb.asm.ClassVisitor; 68 import jdk.internal.org.objectweb.asm.FieldVisitor; 69 import jdk.internal.org.objectweb.asm.MethodVisitor; 70 import jdk.internal.org.objectweb.asm.Opcodes; 71 72 /** 73 * A node that represents a class. 74 * 75 * @author Eric Bruneton 76 */ 77 public class ClassNode extends ClassVisitor { 78 79 /** 80 * The class version. 81 */ 82 public int version; 83 84 /** 85 * The class's access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}). This 86 * field also indicates if the class is deprecated. 87 */ 88 public int access; 89 90 /** 91 * The internal name of the class (see 92 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). 93 */ 94 public String name; 95 96 /** 97 * The signature of the class. Mayt be <tt>null</tt>. 98 */ 99 public String signature; 100 101 /** 102 * The internal of name of the super class (see 103 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). For 104 * interfaces, the super class is {@link Object}. May be <tt>null</tt>, 105 * but only for the {@link Object} class. 106 */ 107 public String superName; 108 109 /** 110 * The internal names of the class's interfaces (see 111 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). This 112 * list is a list of {@link String} objects. 113 */ 114 public List<String> interfaces; 115 116 /** 117 * The name of the source file from which this class was compiled. May be 118 * <tt>null</tt>. 119 */ 120 public String sourceFile; 121 122 /** 123 * Debug information to compute the correspondance between source and 124 * compiled elements of the class. May be <tt>null</tt>. 125 */ 126 public String sourceDebug; 127 128 /** 129 * The internal name of the enclosing class of the class. May be 130 * <tt>null</tt>. 131 */ 132 public String outerClass; 133 134 /** 135 * The name of the method that contains the class, or <tt>null</tt> if the 136 * class is not enclosed in a method. 137 */ 138 public String outerMethod; 139 140 /** 141 * The descriptor of the method that contains the class, or <tt>null</tt> 142 * if the class is not enclosed in a method. 143 */ 144 public String outerMethodDesc; 145 146 /** 147 * The runtime visible annotations of this class. This list is a list of 148 * {@link AnnotationNode} objects. May be <tt>null</tt>. 149 * 150 * @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode 151 * @label visible 152 */ 153 public List<AnnotationNode> visibleAnnotations; 154 155 /** 156 * The runtime invisible annotations of this class. This list is a list of 157 * {@link AnnotationNode} objects. May be <tt>null</tt>. 158 * 159 * @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode 160 * @label invisible 161 */ 162 public List<AnnotationNode> invisibleAnnotations; 163 164 /** 165 * The non standard attributes of this class. This list is a list of 166 * {@link Attribute} objects. May be <tt>null</tt>. 167 * 168 * @associates jdk.internal.org.objectweb.asm.Attribute 169 */ 170 public List<Attribute> attrs; 171 172 /** 173 * Informations about the inner classes of this class. This list is a list 174 * of {@link InnerClassNode} objects. 175 * 176 * @associates jdk.internal.org.objectweb.asm.tree.InnerClassNode 177 */ 178 public List<InnerClassNode> innerClasses; 179 180 /** 181 * The fields of this class. This list is a list of {@link FieldNode} 182 * objects. 183 * 184 * @associates jdk.internal.org.objectweb.asm.tree.FieldNode 185 */ 186 public List<FieldNode> fields; 187 188 /** 189 * The methods of this class. This list is a list of {@link MethodNode} 190 * objects. 191 * 192 * @associates jdk.internal.org.objectweb.asm.tree.MethodNode 193 */ 194 public List<MethodNode> methods; 195 196 /** 197 * Constructs a new {@link ClassNode}. <i>Subclasses must not use this 198 * constructor</i>. Instead, they must use the {@link #ClassNode(int)} 199 * version. 200 */ 201 public ClassNode() { 202 this(Opcodes.ASM4); 203 } 204 205 /** 206 * Constructs a new {@link ClassNode}. 207 * 208 * @param api the ASM API version implemented by this visitor. Must be one 209 * of {@link Opcodes#ASM4}. 210 */ 211 public ClassNode(final int api) { 212 super(api); 213 this.interfaces = new ArrayList<String>(); 214 this.innerClasses = new ArrayList<InnerClassNode>(); 215 this.fields = new ArrayList<FieldNode>(); 216 this.methods = new ArrayList<MethodNode>(); 217 } 218 219 // ------------------------------------------------------------------------ 220 // Implementation of the ClassVisitor abstract class 221 // ------------------------------------------------------------------------ 222 223 @Override 224 public void visit( 225 final int version, 226 final int access, 227 final String name, 228 final String signature, 229 final String superName, 230 final String[] interfaces) 231 { 232 this.version = version; 233 this.access = access; 234 this.name = name; 235 this.signature = signature; 236 this.superName = superName; 237 if (interfaces != null) { 238 this.interfaces.addAll(Arrays.asList(interfaces)); 239 } 240 } 241 242 @Override 243 public void visitSource(final String file, final String debug) { 244 sourceFile = file; 245 sourceDebug = debug; 246 } 247 248 @Override 249 public void visitOuterClass( 250 final String owner, 251 final String name, 252 final String desc) 253 { 254 outerClass = owner; 255 outerMethod = name; 256 outerMethodDesc = desc; 257 } 258 259 @Override 260 public AnnotationVisitor visitAnnotation( 261 final String desc, 262 final boolean visible) 263 { 264 AnnotationNode an = new AnnotationNode(desc); 265 if (visible) { 266 if (visibleAnnotations == null) { 267 visibleAnnotations = new ArrayList<AnnotationNode>(1); 268 } 269 visibleAnnotations.add(an); 270 } else { 271 if (invisibleAnnotations == null) { 272 invisibleAnnotations = new ArrayList<AnnotationNode>(1); 273 } 274 invisibleAnnotations.add(an); 275 } 276 return an; 277 } 278 279 @Override 280 public void visitAttribute(final Attribute attr) { 281 if (attrs == null) { 282 attrs = new ArrayList<Attribute>(1); 283 } 284 attrs.add(attr); 285 } 286 287 @Override 288 public void visitInnerClass( 289 final String name, 290 final String outerName, 291 final String innerName, 292 final int access) 293 { 294 InnerClassNode icn = new InnerClassNode(name, 295 outerName, 296 innerName, 297 access); 298 innerClasses.add(icn); 299 } 300 301 @Override 302 public FieldVisitor visitField( 303 final int access, 304 final String name, 305 final String desc, 306 final String signature, 307 final Object value) 308 { 309 FieldNode fn = new FieldNode(access, name, desc, signature, value); 310 fields.add(fn); 311 return fn; 312 } 313 314 @Override 315 public MethodVisitor visitMethod( 316 final int access, 317 final String name, 318 final String desc, 319 final String signature, 320 final String[] exceptions) 321 { 322 MethodNode mn = new MethodNode(access, 323 name, 324 desc, 325 signature, 326 exceptions); 327 methods.add(mn); 328 return mn; 329 } 330 331 @Override 332 public void visitEnd() { 333 } 334 335 // ------------------------------------------------------------------------ 336 // Accept method 337 // ------------------------------------------------------------------------ 338 339 /** 340 * Checks that this class node is compatible with the given ASM API version. 341 * This methods checks that this node, and all its nodes recursively, do not 342 * contain elements that were introduced in more recent versions of the ASM 343 * API than the given version. 344 * 345 * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}. 346 */ 347 public void check(final int api) { 348 // nothing to do 349 } 350 351 /** 352 * Makes the given class visitor visit this class. 353 * 354 * @param cv a class visitor. 355 */ 356 public void accept(final ClassVisitor cv) { 357 // visits header 358 String[] interfaces = new String[this.interfaces.size()]; 359 this.interfaces.toArray(interfaces); 360 cv.visit(version, access, name, signature, superName, interfaces); 361 // visits source 362 if (sourceFile != null || sourceDebug != null) { 363 cv.visitSource(sourceFile, sourceDebug); 364 } 365 // visits outer class 366 if (outerClass != null) { 367 cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); 368 } 369 // visits attributes 370 int i, n; 371 n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); 372 for (i = 0; i < n; ++i) { 373 AnnotationNode an = visibleAnnotations.get(i); 374 an.accept(cv.visitAnnotation(an.desc, true)); 375 } 376 n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); 377 for (i = 0; i < n; ++i) { 378 AnnotationNode an = invisibleAnnotations.get(i); 379 an.accept(cv.visitAnnotation(an.desc, false)); 380 } 381 n = attrs == null ? 0 : attrs.size(); 382 for (i = 0; i < n; ++i) { 383 cv.visitAttribute(attrs.get(i)); 384 } 385 // visits inner classes 386 for (i = 0; i < innerClasses.size(); ++i) { 387 innerClasses.get(i).accept(cv); 388 } 389 // visits fields 390 for (i = 0; i < fields.size(); ++i) { 391 fields.get(i).accept(cv); 392 } 393 // visits methods 394 for (i = 0; i < methods.size(); ++i) { 395 methods.get(i).accept(cv); 396 } 397 // visits end 398 cv.visitEnd(); 399 } 400 } | 51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59 package jdk.internal.org.objectweb.asm.tree; 60 61 import java.util.ArrayList; 62 import java.util.Arrays; 63 import java.util.List; 64 65 import jdk.internal.org.objectweb.asm.AnnotationVisitor; 66 import jdk.internal.org.objectweb.asm.Attribute; 67 import jdk.internal.org.objectweb.asm.ClassVisitor; 68 import jdk.internal.org.objectweb.asm.FieldVisitor; 69 import jdk.internal.org.objectweb.asm.MethodVisitor; 70 import jdk.internal.org.objectweb.asm.Opcodes; 71 import jdk.internal.org.objectweb.asm.TypePath; 72 73 /** 74 * A node that represents a class. 75 * 76 * @author Eric Bruneton 77 */ 78 public class ClassNode extends ClassVisitor { 79 80 /** 81 * The class version. 82 */ 83 public int version; 84 85 /** 86 * The class's access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}). This 87 * field also indicates if the class is deprecated. 88 */ 89 public int access; 90 91 /** 92 * The internal name of the class (see 93 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). 94 */ 95 public String name; 96 97 /** 98 * The signature of the class. May be <tt>null</tt>. 99 */ 100 public String signature; 101 102 /** 103 * The internal of name of the super class (see 104 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). For 105 * interfaces, the super class is {@link Object}. May be <tt>null</tt>, but 106 * only for the {@link Object} class. 107 */ 108 public String superName; 109 110 /** 111 * The internal names of the class's interfaces (see 112 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). This 113 * list is a list of {@link String} objects. 114 */ 115 public List<String> interfaces; 116 117 /** 118 * The name of the source file from which this class was compiled. May be 119 * <tt>null</tt>. 120 */ 121 public String sourceFile; 122 123 /** 124 * Debug information to compute the correspondence between source and 125 * compiled elements of the class. May be <tt>null</tt>. 126 */ 127 public String sourceDebug; 128 129 /** 130 * The internal name of the enclosing class of the class. May be 131 * <tt>null</tt>. 132 */ 133 public String outerClass; 134 135 /** 136 * The name of the method that contains the class, or <tt>null</tt> if the 137 * class is not enclosed in a method. 138 */ 139 public String outerMethod; 140 141 /** 142 * The descriptor of the method that contains the class, or <tt>null</tt> if 143 * the class is not enclosed in a method. 144 */ 145 public String outerMethodDesc; 146 147 /** 148 * The runtime visible annotations of this class. This list is a list of 149 * {@link AnnotationNode} objects. May be <tt>null</tt>. 150 * 151 * @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode 152 * @label visible 153 */ 154 public List<AnnotationNode> visibleAnnotations; 155 156 /** 157 * The runtime invisible annotations of this class. This list is a list of 158 * {@link AnnotationNode} objects. May be <tt>null</tt>. 159 * 160 * @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode 161 * @label invisible 162 */ 163 public List<AnnotationNode> invisibleAnnotations; 164 165 /** 166 * The runtime visible type annotations of this class. This list is a list 167 * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>. 168 * 169 * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode 170 * @label visible 171 */ 172 public List<TypeAnnotationNode> visibleTypeAnnotations; 173 174 /** 175 * The runtime invisible type annotations of this class. This list is a list 176 * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>. 177 * 178 * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode 179 * @label invisible 180 */ 181 public List<TypeAnnotationNode> invisibleTypeAnnotations; 182 183 /** 184 * The non standard attributes of this class. This list is a list of 185 * {@link Attribute} objects. May be <tt>null</tt>. 186 * 187 * @associates jdk.internal.org.objectweb.asm.Attribute 188 */ 189 public List<Attribute> attrs; 190 191 /** 192 * Informations about the inner classes of this class. This list is a list 193 * of {@link InnerClassNode} objects. 194 * 195 * @associates jdk.internal.org.objectweb.asm.tree.InnerClassNode 196 */ 197 public List<InnerClassNode> innerClasses; 198 199 /** 200 * The fields of this class. This list is a list of {@link FieldNode} 201 * objects. 202 * 203 * @associates jdk.internal.org.objectweb.asm.tree.FieldNode 204 */ 205 public List<FieldNode> fields; 206 207 /** 208 * The methods of this class. This list is a list of {@link MethodNode} 209 * objects. 210 * 211 * @associates jdk.internal.org.objectweb.asm.tree.MethodNode 212 */ 213 public List<MethodNode> methods; 214 215 /** 216 * Constructs a new {@link ClassNode}. <i>Subclasses must not use this 217 * constructor</i>. Instead, they must use the {@link #ClassNode(int)} 218 * version. 219 */ 220 public ClassNode() { 221 this(Opcodes.ASM5); 222 } 223 224 /** 225 * Constructs a new {@link ClassNode}. 226 * 227 * @param api 228 * the ASM API version implemented by this visitor. Must be one 229 * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. 230 */ 231 public ClassNode(final int api) { 232 super(api); 233 this.interfaces = new ArrayList<String>(); 234 this.innerClasses = new ArrayList<InnerClassNode>(); 235 this.fields = new ArrayList<FieldNode>(); 236 this.methods = new ArrayList<MethodNode>(); 237 } 238 239 // ------------------------------------------------------------------------ 240 // Implementation of the ClassVisitor abstract class 241 // ------------------------------------------------------------------------ 242 243 @Override 244 public void visit(final int version, final int access, final String name, 245 final String signature, final String superName, 246 final String[] interfaces) { 247 this.version = version; 248 this.access = access; 249 this.name = name; 250 this.signature = signature; 251 this.superName = superName; 252 if (interfaces != null) { 253 this.interfaces.addAll(Arrays.asList(interfaces)); 254 } 255 } 256 257 @Override 258 public void visitSource(final String file, final String debug) { 259 sourceFile = file; 260 sourceDebug = debug; 261 } 262 263 @Override 264 public void visitOuterClass(final String owner, final String name, 265 final String desc) { 266 outerClass = owner; 267 outerMethod = name; 268 outerMethodDesc = desc; 269 } 270 271 @Override 272 public AnnotationVisitor visitAnnotation(final String desc, 273 final boolean visible) { 274 AnnotationNode an = new AnnotationNode(desc); 275 if (visible) { 276 if (visibleAnnotations == null) { 277 visibleAnnotations = new ArrayList<AnnotationNode>(1); 278 } 279 visibleAnnotations.add(an); 280 } else { 281 if (invisibleAnnotations == null) { 282 invisibleAnnotations = new ArrayList<AnnotationNode>(1); 283 } 284 invisibleAnnotations.add(an); 285 } 286 return an; 287 } 288 289 @Override 290 public AnnotationVisitor visitTypeAnnotation(int typeRef, 291 TypePath typePath, String desc, boolean visible) { 292 TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); 293 if (visible) { 294 if (visibleTypeAnnotations == null) { 295 visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); 296 } 297 visibleTypeAnnotations.add(an); 298 } else { 299 if (invisibleTypeAnnotations == null) { 300 invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); 301 } 302 invisibleTypeAnnotations.add(an); 303 } 304 return an; 305 } 306 307 @Override 308 public void visitAttribute(final Attribute attr) { 309 if (attrs == null) { 310 attrs = new ArrayList<Attribute>(1); 311 } 312 attrs.add(attr); 313 } 314 315 @Override 316 public void visitInnerClass(final String name, final String outerName, 317 final String innerName, final int access) { 318 InnerClassNode icn = new InnerClassNode(name, outerName, innerName, 319 access); 320 innerClasses.add(icn); 321 } 322 323 @Override 324 public FieldVisitor visitField(final int access, final String name, 325 final String desc, final String signature, final Object value) { 326 FieldNode fn = new FieldNode(access, name, desc, signature, value); 327 fields.add(fn); 328 return fn; 329 } 330 331 @Override 332 public MethodVisitor visitMethod(final int access, final String name, 333 final String desc, final String signature, final String[] exceptions) { 334 MethodNode mn = new MethodNode(access, name, desc, signature, 335 exceptions); 336 methods.add(mn); 337 return mn; 338 } 339 340 @Override 341 public void visitEnd() { 342 } 343 344 // ------------------------------------------------------------------------ 345 // Accept method 346 // ------------------------------------------------------------------------ 347 348 /** 349 * Checks that this class node is compatible with the given ASM API version. 350 * This methods checks that this node, and all its nodes recursively, do not 351 * contain elements that were introduced in more recent versions of the ASM 352 * API than the given version. 353 * 354 * @param api 355 * an ASM API version. Must be one of {@link Opcodes#ASM4} or 356 * {@link Opcodes#ASM5}. 357 */ 358 public void check(final int api) { 359 if (api == Opcodes.ASM4) { 360 if (visibleTypeAnnotations != null 361 && visibleTypeAnnotations.size() > 0) { 362 throw new RuntimeException(); 363 } 364 if (invisibleTypeAnnotations != null 365 && invisibleTypeAnnotations.size() > 0) { 366 throw new RuntimeException(); 367 } 368 for (FieldNode f : fields) { 369 f.check(api); 370 } 371 for (MethodNode m : methods) { 372 m.check(api); 373 } 374 } 375 } 376 377 /** 378 * Makes the given class visitor visit this class. 379 * 380 * @param cv 381 * a class visitor. 382 */ 383 public void accept(final ClassVisitor cv) { 384 // visits header 385 String[] interfaces = new String[this.interfaces.size()]; 386 this.interfaces.toArray(interfaces); 387 cv.visit(version, access, name, signature, superName, interfaces); 388 // visits source 389 if (sourceFile != null || sourceDebug != null) { 390 cv.visitSource(sourceFile, sourceDebug); 391 } 392 // visits outer class 393 if (outerClass != null) { 394 cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); 395 } 396 // visits attributes 397 int i, n; 398 n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); 399 for (i = 0; i < n; ++i) { 400 AnnotationNode an = visibleAnnotations.get(i); 401 an.accept(cv.visitAnnotation(an.desc, true)); 402 } 403 n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); 404 for (i = 0; i < n; ++i) { 405 AnnotationNode an = invisibleAnnotations.get(i); 406 an.accept(cv.visitAnnotation(an.desc, false)); 407 } 408 n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); 409 for (i = 0; i < n; ++i) { 410 TypeAnnotationNode an = visibleTypeAnnotations.get(i); 411 an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, 412 true)); 413 } 414 n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations 415 .size(); 416 for (i = 0; i < n; ++i) { 417 TypeAnnotationNode an = invisibleTypeAnnotations.get(i); 418 an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, 419 false)); 420 } 421 n = attrs == null ? 0 : attrs.size(); 422 for (i = 0; i < n; ++i) { 423 cv.visitAttribute(attrs.get(i)); 424 } 425 // visits inner classes 426 for (i = 0; i < innerClasses.size(); ++i) { 427 innerClasses.get(i).accept(cv); 428 } 429 // visits fields 430 for (i = 0; i < fields.size(); ++i) { 431 fields.get(i).accept(cv); 432 } 433 // visits methods 434 for (i = 0; i < methods.size(); ++i) { 435 methods.get(i).accept(cv); 436 } 437 // visits end 438 cv.visitEnd(); 439 } 440 } |