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.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 * @throws IllegalStateException 221 * If a subclass calls this constructor. 222 */ 223 public ClassNode() { 224 this(Opcodes.ASM5); 225 if (getClass() != ClassNode.class) { 226 throw new IllegalStateException(); 227 } 228 } 229 230 /** 231 * Constructs a new {@link ClassNode}. 232 * 233 * @param api 234 * the ASM API version implemented by this visitor. Must be one 235 * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. 236 */ 237 public ClassNode(final int api) { 238 super(api); 239 this.interfaces = new ArrayList<String>(); 240 this.innerClasses = new ArrayList<InnerClassNode>(); 241 this.fields = new ArrayList<FieldNode>(); 242 this.methods = new ArrayList<MethodNode>(); 243 } 244 245 // ------------------------------------------------------------------------ 246 // Implementation of the ClassVisitor abstract class 247 // ------------------------------------------------------------------------ 248 249 @Override 250 public void visit(final int version, final int access, final String name, 251 final String signature, final String superName, 252 final String[] interfaces) { 253 this.version = version; 254 this.access = access; 255 this.name = name; 256 this.signature = signature; 257 this.superName = superName; 258 if (interfaces != null) { 259 this.interfaces.addAll(Arrays.asList(interfaces)); 260 } 261 } 262 263 @Override 264 public void visitSource(final String file, final String debug) { 265 sourceFile = file; 266 sourceDebug = debug; 267 } 268 269 @Override 270 public void visitOuterClass(final String owner, final String name, 271 final String desc) { 272 outerClass = owner; 273 outerMethod = name; 274 outerMethodDesc = desc; 275 } 276 277 @Override 278 public AnnotationVisitor visitAnnotation(final String desc, 279 final boolean visible) { 280 AnnotationNode an = new AnnotationNode(desc); 281 if (visible) { 282 if (visibleAnnotations == null) { 283 visibleAnnotations = new ArrayList<AnnotationNode>(1); 284 } 285 visibleAnnotations.add(an); 286 } else { 287 if (invisibleAnnotations == null) { 288 invisibleAnnotations = new ArrayList<AnnotationNode>(1); 289 } 290 invisibleAnnotations.add(an); 291 } 292 return an; 293 } 294 295 @Override 296 public AnnotationVisitor visitTypeAnnotation(int typeRef, 297 TypePath typePath, String desc, boolean visible) { 298 TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); 299 if (visible) { 300 if (visibleTypeAnnotations == null) { 301 visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); 302 } 303 visibleTypeAnnotations.add(an); 304 } else { 305 if (invisibleTypeAnnotations == null) { 306 invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); 307 } 308 invisibleTypeAnnotations.add(an); 309 } 310 return an; 311 } 312 313 @Override 314 public void visitAttribute(final Attribute attr) { 315 if (attrs == null) { 316 attrs = new ArrayList<Attribute>(1); 317 } 318 attrs.add(attr); 319 } 320 321 @Override 322 public void visitInnerClass(final String name, final String outerName, 323 final String innerName, final int access) { 324 InnerClassNode icn = new InnerClassNode(name, outerName, innerName, 325 access); 326 innerClasses.add(icn); 327 } 328 329 @Override 330 public FieldVisitor visitField(final int access, final String name, 331 final String desc, final String signature, final Object value) { 332 FieldNode fn = new FieldNode(access, name, desc, signature, value); 333 fields.add(fn); 334 return fn; 335 } 336 337 @Override 338 public MethodVisitor visitMethod(final int access, final String name, 339 final String desc, final String signature, final String[] exceptions) { 340 MethodNode mn = new MethodNode(access, name, desc, signature, 341 exceptions); 342 methods.add(mn); 343 return mn; 344 } 345 346 @Override 347 public void visitEnd() { 348 } 349 350 // ------------------------------------------------------------------------ 351 // Accept method 352 // ------------------------------------------------------------------------ 353 354 /** 355 * Checks that this class node is compatible with the given ASM API version. 356 * This methods checks that this node, and all its nodes recursively, do not 357 * contain elements that were introduced in more recent versions of the ASM 358 * API than the given version. 359 * 360 * @param api 361 * an ASM API version. Must be one of {@link Opcodes#ASM4} or 362 * {@link Opcodes#ASM5}. 363 */ 364 public void check(final int api) { 365 if (api == Opcodes.ASM4) { 366 if (visibleTypeAnnotations != null 367 && visibleTypeAnnotations.size() > 0) { 368 throw new RuntimeException(); 369 } 370 if (invisibleTypeAnnotations != null 371 && invisibleTypeAnnotations.size() > 0) { 372 throw new RuntimeException(); 373 } 374 for (FieldNode f : fields) { 375 f.check(api); 376 } 377 for (MethodNode m : methods) { 378 m.check(api); 379 } 380 } 381 } 382 383 /** 384 * Makes the given class visitor visit this class. 385 * 386 * @param cv 387 * a class visitor. 388 */ 389 public void accept(final ClassVisitor cv) { 390 // visits header 391 String[] interfaces = new String[this.interfaces.size()]; 392 this.interfaces.toArray(interfaces); 393 cv.visit(version, access, name, signature, superName, interfaces); 394 // visits source 395 if (sourceFile != null || sourceDebug != null) { 396 cv.visitSource(sourceFile, sourceDebug); 397 } 398 // visits outer class 399 if (outerClass != null) { 400 cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); 401 } 402 // visits attributes 403 int i, n; 404 n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); 405 for (i = 0; i < n; ++i) { 406 AnnotationNode an = visibleAnnotations.get(i); 407 an.accept(cv.visitAnnotation(an.desc, true)); 408 } 409 n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); 410 for (i = 0; i < n; ++i) { 411 AnnotationNode an = invisibleAnnotations.get(i); 412 an.accept(cv.visitAnnotation(an.desc, false)); 413 } 414 n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); 415 for (i = 0; i < n; ++i) { 416 TypeAnnotationNode an = visibleTypeAnnotations.get(i); 417 an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, 418 true)); 419 } 420 n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations 421 .size(); 422 for (i = 0; i < n; ++i) { 423 TypeAnnotationNode an = invisibleTypeAnnotations.get(i); 424 an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, 425 false)); 426 } 427 n = attrs == null ? 0 : attrs.size(); 428 for (i = 0; i < n; ++i) { 429 cv.visitAttribute(attrs.get(i)); 430 } 431 // visits inner classes 432 for (i = 0; i < innerClasses.size(); ++i) { 433 innerClasses.get(i).accept(cv); 434 } 435 // visits fields 436 for (i = 0; i < fields.size(); ++i) { 437 fields.get(i).accept(cv); 438 } 439 // visits methods 440 for (i = 0; i < methods.size(); ++i) { 441 methods.get(i).accept(cv); 442 } 443 // visits end 444 cv.visitEnd(); 445 } 446 }