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;
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>.
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 }
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,
|
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;
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>.
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 }
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,
|