1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * ASM: a very small and fast Java bytecode manipulation framework 32 * Copyright (c) 2000-2011 INRIA, France Telecom 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. Neither the name of the copyright holders nor the names of its 44 * contributors may be used to endorse or promote products derived from 45 * this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 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.ModuleVisitor; 71 import jdk.internal.org.objectweb.asm.Opcodes; 72 import jdk.internal.org.objectweb.asm.TypePath; 73 74 /** 75 * A node that represents a class. 76 * 77 * @author Eric Bruneton 78 */ 79 public class ClassNode extends ClassVisitor { 80 81 /** 82 * The class version. 83 */ 84 public int version; 85 86 /** 87 * The class's access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}). This 88 * field also indicates if the class is deprecated. 89 */ 90 public int access; 91 92 /** 93 * The internal name of the class (see 94 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). 95 */ 96 public String name; 97 98 /** 99 * The signature of the class. May be <tt>null</tt>. 100 */ 101 public String signature; 102 103 /** 104 * The internal of name of the super class (see 105 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). For 106 * interfaces, the super class is {@link Object}. May be <tt>null</tt>, but 107 * only for the {@link Object} class. 108 */ 109 public String superName; 110 111 /** 112 * The internal names of the class's interfaces (see 113 * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). This 114 * list is a list of {@link String} objects. 115 */ 116 public List<String> interfaces; 117 118 /** 119 * The name of the source file from which this class was compiled. May be 120 * <tt>null</tt>. 121 */ 122 public String sourceFile; 123 124 /** 125 * Debug information to compute the correspondence between source and 126 * compiled elements of the class. May be <tt>null</tt>. 127 */ 128 public String sourceDebug; 129 130 /** 131 * Module information. May be <tt>null</tt>. 132 */ 133 public ModuleNode module; 134 135 /** 136 * The internal name of the enclosing class of the class. May be 137 * <tt>null</tt>. 138 */ 139 public String outerClass; 140 141 /** 142 * The name of the method that contains the class, or <tt>null</tt> if the 143 * class is not enclosed in a method. 144 */ 145 public String outerMethod; 146 147 /** 148 * The descriptor of the method that contains the class, or <tt>null</tt> if 149 * the class is not enclosed in a method. 150 */ 151 public String outerMethodDesc; 152 153 /** 154 * The runtime visible annotations of this class. This list is a list of 155 * {@link AnnotationNode} objects. May be <tt>null</tt>. 156 * 157 * @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode 158 * @label visible 159 */ 160 public List<AnnotationNode> visibleAnnotations; 161 162 /** 163 * The runtime invisible annotations of this class. This list is a list of 164 * {@link AnnotationNode} objects. May be <tt>null</tt>. 165 * 166 * @associates jdk.internal.org.objectweb.asm.tree.AnnotationNode 167 * @label invisible 168 */ 169 public List<AnnotationNode> invisibleAnnotations; 170 171 /** 172 * The runtime visible type annotations of this class. This list is a list 173 * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>. 174 * 175 * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode 176 * @label visible 177 */ 178 public List<TypeAnnotationNode> visibleTypeAnnotations; 179 180 /** 181 * The runtime invisible type annotations of this class. This list is a list 182 * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>. 183 * 184 * @associates jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode 185 * @label invisible 186 */ 187 public List<TypeAnnotationNode> invisibleTypeAnnotations; 188 189 /** 190 * The non standard attributes of this class. This list is a list of 191 * {@link Attribute} objects. May be <tt>null</tt>. 192 * 193 * @associates jdk.internal.org.objectweb.asm.Attribute 194 */ 195 public List<Attribute> attrs; 196 197 /** 198 * Informations about the inner classes of this class. This list is a list 199 * of {@link InnerClassNode} objects. 200 * 201 * @associates jdk.internal.org.objectweb.asm.tree.InnerClassNode 202 */ 203 public List<InnerClassNode> innerClasses; 204 205 /** 206 * The fields of this class. This list is a list of {@link FieldNode} 207 * objects. 208 * 209 * @associates jdk.internal.org.objectweb.asm.tree.FieldNode 210 */ 211 public List<FieldNode> fields; 212 213 /** 214 * The methods of this class. This list is a list of {@link MethodNode} 215 * objects. 216 * 217 * @associates jdk.internal.org.objectweb.asm.tree.MethodNode 218 */ 219 public List<MethodNode> methods; 220 221 /** 222 * Constructs a new {@link ClassNode}. <i>Subclasses must not use this 223 * constructor</i>. Instead, they must use the {@link #ClassNode(int)} 224 * version. 225 * 226 * @throws IllegalStateException 227 * If a subclass calls this constructor. 228 */ 229 public ClassNode() { 230 this(Opcodes.ASM6); 231 if (getClass() != ClassNode.class) { 232 throw new IllegalStateException(); 233 } 234 } 235 236 /** 237 * Constructs a new {@link ClassNode}. 238 * 239 * @param api 240 * the ASM API version implemented by this visitor. Must be one 241 * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. 242 */ 243 public ClassNode(final int api) { 244 super(api); 245 this.interfaces = new ArrayList<String>(); 246 this.innerClasses = new ArrayList<InnerClassNode>(); 247 this.fields = new ArrayList<FieldNode>(); 248 this.methods = new ArrayList<MethodNode>(); 249 } 250 251 // ------------------------------------------------------------------------ 252 // Implementation of the ClassVisitor abstract class 253 // ------------------------------------------------------------------------ 254 255 @Override 256 public void visit(final int version, final int access, final String name, 257 final String signature, final String superName, 258 final String[] interfaces) { 259 this.version = version; 260 this.access = access; 261 this.name = name; 262 this.signature = signature; 263 this.superName = superName; 264 if (interfaces != null) { 265 this.interfaces.addAll(Arrays.asList(interfaces)); 266 } 267 } 268 269 @Override 270 public void visitSource(final String file, final String debug) { 271 sourceFile = file; 272 sourceDebug = debug; 273 } 274 275 @Override 276 public ModuleVisitor visitModule(final String name, final int access, 277 final String version) { 278 return module = new ModuleNode(name, access, version); 279 } 280 281 @Override 282 public void visitOuterClass(final String owner, final String name, 283 final String desc) { 284 outerClass = owner; 285 outerMethod = name; 286 outerMethodDesc = desc; 287 } 288 289 @Override 290 public AnnotationVisitor visitAnnotation(final String desc, 291 final boolean visible) { 292 AnnotationNode an = new AnnotationNode(desc); 293 if (visible) { 294 if (visibleAnnotations == null) { 295 visibleAnnotations = new ArrayList<AnnotationNode>(1); 296 } 297 visibleAnnotations.add(an); 298 } else { 299 if (invisibleAnnotations == null) { 300 invisibleAnnotations = new ArrayList<AnnotationNode>(1); 301 } 302 invisibleAnnotations.add(an); 303 } 304 return an; 305 } 306 307 @Override 308 public AnnotationVisitor visitTypeAnnotation(int typeRef, 309 TypePath typePath, String desc, boolean visible) { 310 TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); 311 if (visible) { 312 if (visibleTypeAnnotations == null) { 313 visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); 314 } 315 visibleTypeAnnotations.add(an); 316 } else { 317 if (invisibleTypeAnnotations == null) { 318 invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); 319 } 320 invisibleTypeAnnotations.add(an); 321 } 322 return an; 323 } 324 325 @Override 326 public void visitAttribute(final Attribute attr) { 327 if (attrs == null) { 328 attrs = new ArrayList<Attribute>(1); 329 } 330 attrs.add(attr); 331 } 332 333 @Override 334 public void visitInnerClass(final String name, final String outerName, 335 final String innerName, final int access) { 336 InnerClassNode icn = new InnerClassNode(name, outerName, innerName, 337 access); 338 innerClasses.add(icn); 339 } 340 341 @Override 342 public FieldVisitor visitField(final int access, final String name, 343 final String desc, final String signature, final Object value) { 344 FieldNode fn = new FieldNode(access, name, desc, signature, value); 345 fields.add(fn); 346 return fn; 347 } 348 349 @Override 350 public MethodVisitor visitMethod(final int access, final String name, 351 final String desc, final String signature, final String[] exceptions) { 352 MethodNode mn = new MethodNode(access, name, desc, signature, 353 exceptions); 354 methods.add(mn); 355 return mn; 356 } 357 358 @Override 359 public void visitEnd() { 360 } 361 362 // ------------------------------------------------------------------------ 363 // Accept method 364 // ------------------------------------------------------------------------ 365 366 /** 367 * Checks that this class node is compatible with the given ASM API version. 368 * This methods checks that this node, and all its nodes recursively, do not 369 * contain elements that were introduced in more recent versions of the ASM 370 * API than the given version. 371 * 372 * @param api 373 * an ASM API version. Must be one of {@link Opcodes#ASM4}, 374 * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. 375 */ 376 public void check(final int api) { 377 if (api < Opcodes.ASM6) { 378 if (module != null) { 379 throw new RuntimeException(); 380 } 381 } 382 if (api < Opcodes.ASM5) { 383 if (visibleTypeAnnotations != null 384 && visibleTypeAnnotations.size() > 0) { 385 throw new RuntimeException(); 386 } 387 if (invisibleTypeAnnotations != null 388 && invisibleTypeAnnotations.size() > 0) { 389 throw new RuntimeException(); 390 } 391 } 392 // checks attributes 393 int i, n; 394 n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); 395 for (i = 0; i < n; ++i) { 396 visibleAnnotations.get(i).check(api); 397 } 398 n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); 399 for (i = 0; i < n; ++i) { 400 invisibleAnnotations.get(i).check(api); 401 } 402 n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); 403 for (i = 0; i < n; ++i) { 404 visibleTypeAnnotations.get(i).check(api); 405 } 406 n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations 407 .size(); 408 for (i = 0; i < n; ++i) { 409 invisibleTypeAnnotations.get(i).check(api); 410 } 411 for (FieldNode f : fields) { 412 f.check(api); 413 } 414 for (MethodNode m : methods) { 415 m.check(api); 416 } 417 } 418 419 /** 420 * Makes the given class visitor visit this class. 421 * 422 * @param cv 423 * a class visitor. 424 */ 425 public void accept(final ClassVisitor cv) { 426 // visits header 427 String[] interfaces = new String[this.interfaces.size()]; 428 this.interfaces.toArray(interfaces); 429 cv.visit(version, access, name, signature, superName, interfaces); 430 // visits source 431 if (sourceFile != null || sourceDebug != null) { 432 cv.visitSource(sourceFile, sourceDebug); 433 } 434 // visits module 435 if (module != null) { 436 module.accept(cv); 437 } 438 // visits outer class 439 if (outerClass != null) { 440 cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); 441 } 442 // visits attributes 443 int i, n; 444 n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); 445 for (i = 0; i < n; ++i) { 446 AnnotationNode an = visibleAnnotations.get(i); 447 an.accept(cv.visitAnnotation(an.desc, true)); 448 } 449 n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); 450 for (i = 0; i < n; ++i) { 451 AnnotationNode an = invisibleAnnotations.get(i); 452 an.accept(cv.visitAnnotation(an.desc, false)); 453 } 454 n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); 455 for (i = 0; i < n; ++i) { 456 TypeAnnotationNode an = visibleTypeAnnotations.get(i); 457 an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, 458 true)); 459 } 460 n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations 461 .size(); 462 for (i = 0; i < n; ++i) { 463 TypeAnnotationNode an = invisibleTypeAnnotations.get(i); 464 an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, 465 false)); 466 } 467 n = attrs == null ? 0 : attrs.size(); 468 for (i = 0; i < n; ++i) { 469 cv.visitAttribute(attrs.get(i)); 470 } 471 // visits inner classes 472 for (i = 0; i < innerClasses.size(); ++i) { 473 innerClasses.get(i).accept(cv); 474 } 475 // visits fields 476 for (i = 0; i < fields.size(); ++i) { 477 fields.get(i).accept(cv); 478 } 479 // visits methods 480 for (i = 0; i < methods.size(); ++i) { 481 methods.get(i).accept(cv); 482 } 483 // visits end 484 cv.visitEnd(); 485 } 486 }