• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ASM: a very small and fast Java bytecode manipulation framework
2 // Copyright (c) 2000-2011 INRIA, France Telecom
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // 1. Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the distribution.
13 // 3. Neither the name of the copyright holders nor the names of its
14 //    contributors may be used to endorse or promote products derived from
15 //    this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 // THE POSSIBILITY OF SUCH DAMAGE.
28 package org.objectweb.asm.util;
29 
30 import java.io.FileInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.PrintWriter;
34 import java.util.ArrayList;
35 import java.util.List;
36 import org.objectweb.asm.Attribute;
37 import org.objectweb.asm.ClassReader;
38 import org.objectweb.asm.ConstantDynamic;
39 import org.objectweb.asm.Handle;
40 import org.objectweb.asm.Label;
41 import org.objectweb.asm.Opcodes;
42 import org.objectweb.asm.Type;
43 import org.objectweb.asm.TypePath;
44 import org.objectweb.asm.TypeReference;
45 
46 /**
47  * An abstract converter from visit events to text.
48  *
49  * @author Eric Bruneton
50  */
51 public abstract class Printer {
52 
53   /** The names of the Java Virtual Machine opcodes. */
54   public static final String[] OPCODES = {
55     "NOP", // 0 (0x0)
56     "ACONST_NULL", // 1 (0x1)
57     "ICONST_M1", // 2 (0x2)
58     "ICONST_0", // 3 (0x3)
59     "ICONST_1", // 4 (0x4)
60     "ICONST_2", // 5 (0x5)
61     "ICONST_3", // 6 (0x6)
62     "ICONST_4", // 7 (0x7)
63     "ICONST_5", // 8 (0x8)
64     "LCONST_0", // 9 (0x9)
65     "LCONST_1", // 10 (0xa)
66     "FCONST_0", // 11 (0xb)
67     "FCONST_1", // 12 (0xc)
68     "FCONST_2", // 13 (0xd)
69     "DCONST_0", // 14 (0xe)
70     "DCONST_1", // 15 (0xf)
71     "BIPUSH", // 16 (0x10)
72     "SIPUSH", // 17 (0x11)
73     "LDC", // 18 (0x12)
74     "LDC_W", // 19 (0x13)
75     "LDC2_W", // 20 (0x14)
76     "ILOAD", // 21 (0x15)
77     "LLOAD", // 22 (0x16)
78     "FLOAD", // 23 (0x17)
79     "DLOAD", // 24 (0x18)
80     "ALOAD", // 25 (0x19)
81     "ILOAD_0", // 26 (0x1a)
82     "ILOAD_1", // 27 (0x1b)
83     "ILOAD_2", // 28 (0x1c)
84     "ILOAD_3", // 29 (0x1d)
85     "LLOAD_0", // 30 (0x1e)
86     "LLOAD_1", // 31 (0x1f)
87     "LLOAD_2", // 32 (0x20)
88     "LLOAD_3", // 33 (0x21)
89     "FLOAD_0", // 34 (0x22)
90     "FLOAD_1", // 35 (0x23)
91     "FLOAD_2", // 36 (0x24)
92     "FLOAD_3", // 37 (0x25)
93     "DLOAD_0", // 38 (0x26)
94     "DLOAD_1", // 39 (0x27)
95     "DLOAD_2", // 40 (0x28)
96     "DLOAD_3", // 41 (0x29)
97     "ALOAD_0", // 42 (0x2a)
98     "ALOAD_1", // 43 (0x2b)
99     "ALOAD_2", // 44 (0x2c)
100     "ALOAD_3", // 45 (0x2d)
101     "IALOAD", // 46 (0x2e)
102     "LALOAD", // 47 (0x2f)
103     "FALOAD", // 48 (0x30)
104     "DALOAD", // 49 (0x31)
105     "AALOAD", // 50 (0x32)
106     "BALOAD", // 51 (0x33)
107     "CALOAD", // 52 (0x34)
108     "SALOAD", // 53 (0x35)
109     "ISTORE", // 54 (0x36)
110     "LSTORE", // 55 (0x37)
111     "FSTORE", // 56 (0x38)
112     "DSTORE", // 57 (0x39)
113     "ASTORE", // 58 (0x3a)
114     "ISTORE_0", // 59 (0x3b)
115     "ISTORE_1", // 60 (0x3c)
116     "ISTORE_2", // 61 (0x3d)
117     "ISTORE_3", // 62 (0x3e)
118     "LSTORE_0", // 63 (0x3f)
119     "LSTORE_1", // 64 (0x40)
120     "LSTORE_2", // 65 (0x41)
121     "LSTORE_3", // 66 (0x42)
122     "FSTORE_0", // 67 (0x43)
123     "FSTORE_1", // 68 (0x44)
124     "FSTORE_2", // 69 (0x45)
125     "FSTORE_3", // 70 (0x46)
126     "DSTORE_0", // 71 (0x47)
127     "DSTORE_1", // 72 (0x48)
128     "DSTORE_2", // 73 (0x49)
129     "DSTORE_3", // 74 (0x4a)
130     "ASTORE_0", // 75 (0x4b)
131     "ASTORE_1", // 76 (0x4c)
132     "ASTORE_2", // 77 (0x4d)
133     "ASTORE_3", // 78 (0x4e)
134     "IASTORE", // 79 (0x4f)
135     "LASTORE", // 80 (0x50)
136     "FASTORE", // 81 (0x51)
137     "DASTORE", // 82 (0x52)
138     "AASTORE", // 83 (0x53)
139     "BASTORE", // 84 (0x54)
140     "CASTORE", // 85 (0x55)
141     "SASTORE", // 86 (0x56)
142     "POP", // 87 (0x57)
143     "POP2", // 88 (0x58)
144     "DUP", // 89 (0x59)
145     "DUP_X1", // 90 (0x5a)
146     "DUP_X2", // 91 (0x5b)
147     "DUP2", // 92 (0x5c)
148     "DUP2_X1", // 93 (0x5d)
149     "DUP2_X2", // 94 (0x5e)
150     "SWAP", // 95 (0x5f)
151     "IADD", // 96 (0x60)
152     "LADD", // 97 (0x61)
153     "FADD", // 98 (0x62)
154     "DADD", // 99 (0x63)
155     "ISUB", // 100 (0x64)
156     "LSUB", // 101 (0x65)
157     "FSUB", // 102 (0x66)
158     "DSUB", // 103 (0x67)
159     "IMUL", // 104 (0x68)
160     "LMUL", // 105 (0x69)
161     "FMUL", // 106 (0x6a)
162     "DMUL", // 107 (0x6b)
163     "IDIV", // 108 (0x6c)
164     "LDIV", // 109 (0x6d)
165     "FDIV", // 110 (0x6e)
166     "DDIV", // 111 (0x6f)
167     "IREM", // 112 (0x70)
168     "LREM", // 113 (0x71)
169     "FREM", // 114 (0x72)
170     "DREM", // 115 (0x73)
171     "INEG", // 116 (0x74)
172     "LNEG", // 117 (0x75)
173     "FNEG", // 118 (0x76)
174     "DNEG", // 119 (0x77)
175     "ISHL", // 120 (0x78)
176     "LSHL", // 121 (0x79)
177     "ISHR", // 122 (0x7a)
178     "LSHR", // 123 (0x7b)
179     "IUSHR", // 124 (0x7c)
180     "LUSHR", // 125 (0x7d)
181     "IAND", // 126 (0x7e)
182     "LAND", // 127 (0x7f)
183     "IOR", // 128 (0x80)
184     "LOR", // 129 (0x81)
185     "IXOR", // 130 (0x82)
186     "LXOR", // 131 (0x83)
187     "IINC", // 132 (0x84)
188     "I2L", // 133 (0x85)
189     "I2F", // 134 (0x86)
190     "I2D", // 135 (0x87)
191     "L2I", // 136 (0x88)
192     "L2F", // 137 (0x89)
193     "L2D", // 138 (0x8a)
194     "F2I", // 139 (0x8b)
195     "F2L", // 140 (0x8c)
196     "F2D", // 141 (0x8d)
197     "D2I", // 142 (0x8e)
198     "D2L", // 143 (0x8f)
199     "D2F", // 144 (0x90)
200     "I2B", // 145 (0x91)
201     "I2C", // 146 (0x92)
202     "I2S", // 147 (0x93)
203     "LCMP", // 148 (0x94)
204     "FCMPL", // 149 (0x95)
205     "FCMPG", // 150 (0x96)
206     "DCMPL", // 151 (0x97)
207     "DCMPG", // 152 (0x98)
208     "IFEQ", // 153 (0x99)
209     "IFNE", // 154 (0x9a)
210     "IFLT", // 155 (0x9b)
211     "IFGE", // 156 (0x9c)
212     "IFGT", // 157 (0x9d)
213     "IFLE", // 158 (0x9e)
214     "IF_ICMPEQ", // 159 (0x9f)
215     "IF_ICMPNE", // 160 (0xa0)
216     "IF_ICMPLT", // 161 (0xa1)
217     "IF_ICMPGE", // 162 (0xa2)
218     "IF_ICMPGT", // 163 (0xa3)
219     "IF_ICMPLE", // 164 (0xa4)
220     "IF_ACMPEQ", // 165 (0xa5)
221     "IF_ACMPNE", // 166 (0xa6)
222     "GOTO", // 167 (0xa7)
223     "JSR", // 168 (0xa8)
224     "RET", // 169 (0xa9)
225     "TABLESWITCH", // 170 (0xaa)
226     "LOOKUPSWITCH", // 171 (0xab)
227     "IRETURN", // 172 (0xac)
228     "LRETURN", // 173 (0xad)
229     "FRETURN", // 174 (0xae)
230     "DRETURN", // 175 (0xaf)
231     "ARETURN", // 176 (0xb0)
232     "RETURN", // 177 (0xb1)
233     "GETSTATIC", // 178 (0xb2)
234     "PUTSTATIC", // 179 (0xb3)
235     "GETFIELD", // 180 (0xb4)
236     "PUTFIELD", // 181 (0xb5)
237     "INVOKEVIRTUAL", // 182 (0xb6)
238     "INVOKESPECIAL", // 183 (0xb7)
239     "INVOKESTATIC", // 184 (0xb8)
240     "INVOKEINTERFACE", // 185 (0xb9)
241     "INVOKEDYNAMIC", // 186 (0xba)
242     "NEW", // 187 (0xbb)
243     "NEWARRAY", // 188 (0xbc)
244     "ANEWARRAY", // 189 (0xbd)
245     "ARRAYLENGTH", // 190 (0xbe)
246     "ATHROW", // 191 (0xbf)
247     "CHECKCAST", // 192 (0xc0)
248     "INSTANCEOF", // 193 (0xc1)
249     "MONITORENTER", // 194 (0xc2)
250     "MONITOREXIT", // 195 (0xc3)
251     "WIDE", // 196 (0xc4)
252     "MULTIANEWARRAY", // 197 (0xc5)
253     "IFNULL", // 198 (0xc6)
254     "IFNONNULL" // 199 (0xc7)
255   };
256 
257   /**
258    * The names of the {@code operand} values of the {@link
259    * org.objectweb.asm.MethodVisitor#visitIntInsn} method when {@code opcode} is {@code NEWARRAY}.
260    */
261   public static final String[] TYPES = {
262     "",
263     "",
264     "",
265     "",
266     "T_BOOLEAN",
267     "T_CHAR",
268     "T_FLOAT",
269     "T_DOUBLE",
270     "T_BYTE",
271     "T_SHORT",
272     "T_INT",
273     "T_LONG"
274   };
275 
276   /** The names of the {@code tag} field values for {@link org.objectweb.asm.Handle}. */
277   public static final String[] HANDLE_TAG = {
278     "",
279     "H_GETFIELD",
280     "H_GETSTATIC",
281     "H_PUTFIELD",
282     "H_PUTSTATIC",
283     "H_INVOKEVIRTUAL",
284     "H_INVOKESTATIC",
285     "H_INVOKESPECIAL",
286     "H_NEWINVOKESPECIAL",
287     "H_INVOKEINTERFACE"
288   };
289 
290   /** Message of the UnsupportedOperationException thrown by methods which must be overridden. */
291   private static final String UNSUPPORTED_OPERATION = "Must be overridden";
292 
293   /**
294    * The ASM API version implemented by this class. The value of this field must be one of the
295    * {@code ASM}<i>x</i> values in {@link Opcodes}.
296    */
297   protected final int api;
298 
299   /** The builder used to build strings in the various visit methods. */
300   protected final StringBuilder stringBuilder;
301 
302   /**
303    * The text to be printed. Since the code of methods is not necessarily visited in sequential
304    * order, one method after the other, but can be interlaced (some instructions from method one,
305    * then some instructions from method two, then some instructions from method one again...), it is
306    * not possible to print the visited instructions directly to a sequential stream. A class is
307    * therefore printed in a two steps process: a string tree is constructed during the visit, and
308    * printed to a sequential stream at the end of the visit. This string tree is stored in this
309    * field, as a string list that can contain other string lists, which can themselves contain other
310    * string lists, and so on.
311    */
312   public final List<Object> text;
313 
314   // -----------------------------------------------------------------------------------------------
315   // Constructor
316   // -----------------------------------------------------------------------------------------------
317 
318   /**
319    * Constructs a new {@link Printer}.
320    *
321    * @param api the ASM API version implemented by this printer. Must be one of the {@code
322    *     ASM}<i>x</i> values in {@link Opcodes}.
323    */
Printer(final int api)324   protected Printer(final int api) {
325     this.api = api;
326     this.stringBuilder = new StringBuilder();
327     this.text = new ArrayList<>();
328   }
329 
330   // -----------------------------------------------------------------------------------------------
331   // Classes
332   // -----------------------------------------------------------------------------------------------
333 
334   /**
335    * Class header. See {@link org.objectweb.asm.ClassVisitor#visit}.
336    *
337    * @param version the class version. The minor version is stored in the 16 most significant bits,
338    *     and the major version in the 16 least significant bits.
339    * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if
340    *     the class is deprecated.
341    * @param name the internal name of the class (see {@link Type#getInternalName()}).
342    * @param signature the signature of this class. May be {@literal null} if the class is not a
343    *     generic one, and does not extend or implement generic classes or interfaces.
344    * @param superName the internal of name of the super class (see {@link Type#getInternalName()}).
345    *     For interfaces, the super class is {@link Object}. May be {@literal null}, but only for the
346    *     {@link Object} class.
347    * @param interfaces the internal names of the class's interfaces (see {@link
348    *     Type#getInternalName()}). May be {@literal null}.
349    */
visit( int version, int access, String name, String signature, String superName, String[] interfaces)350   public abstract void visit(
351       int version,
352       int access,
353       String name,
354       String signature,
355       String superName,
356       String[] interfaces);
357 
358   /**
359    * Class source. See {@link org.objectweb.asm.ClassVisitor#visitSource}.
360    *
361    * @param source the name of the source file from which the class was compiled. May be {@literal
362    *     null}.
363    * @param debug additional debug information to compute the correspondence between source and
364    *     compiled elements of the class. May be {@literal null}.
365    */
visitSource(String source, String debug)366   public abstract void visitSource(String source, String debug);
367 
368   /**
369    * Module. See {@link org.objectweb.asm.ClassVisitor#visitModule}.
370    *
371    * @param name the fully qualified name (using dots) of the module.
372    * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
373    *     ACC_MANDATED}.
374    * @param version the module version, or {@literal null}.
375    * @return the printer.
376    */
visitModule(final String name, final int access, final String version)377   public Printer visitModule(final String name, final int access, final String version) {
378     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
379   }
380 
381   /**
382    * Visits the nest host class of the class. A nest is a set of classes of the same package that
383    * share access to their private members. One of these classes, called the host, lists the other
384    * members of the nest, which in turn should link to the host of their nest. This method must be
385    * called only once and only if the visited class is a non-host member of a nest. A class is
386    * implicitly its own nest, so it's invalid to call this method with the visited class name as
387    * argument.
388    *
389    * @param nestHost the internal name of the host class of the nest (see {@link
390    *     Type#getInternalName()}).
391    */
visitNestHost(final String nestHost)392   public void visitNestHost(final String nestHost) {
393     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
394   }
395 
396   /**
397    * Class outer class. See {@link org.objectweb.asm.ClassVisitor#visitOuterClass}.
398    *
399    * @param owner internal name of the enclosing class of the class (see {@link
400    *     Type#getInternalName()}).
401    * @param name the name of the method that contains the class, or {@literal null} if the class is
402    *     not enclosed in a method of its enclosing class.
403    * @param descriptor the descriptor of the method that contains the class, or {@literal null} if
404    *     the class is not enclosed in a method of its enclosing class.
405    */
visitOuterClass(String owner, String name, String descriptor)406   public abstract void visitOuterClass(String owner, String name, String descriptor);
407 
408   /**
409    * Class annotation. See {@link org.objectweb.asm.ClassVisitor#visitAnnotation}.
410    *
411    * @param descriptor the class descriptor of the annotation class.
412    * @param visible {@literal true} if the annotation is visible at runtime.
413    * @return the printer.
414    */
visitClassAnnotation(String descriptor, boolean visible)415   public abstract Printer visitClassAnnotation(String descriptor, boolean visible);
416 
417   /**
418    * Class type annotation. See {@link org.objectweb.asm.ClassVisitor#visitTypeAnnotation}.
419    *
420    * @param typeRef a reference to the annotated type. The sort of this type reference must be
421    *     {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
422    *     TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
423    *     {@link TypeReference}.
424    * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
425    *     static inner type within 'typeRef'. May be {@literal null} if the annotation targets
426    *     'typeRef' as a whole.
427    * @param descriptor the class descriptor of the annotation class.
428    * @param visible {@literal true} if the annotation is visible at runtime.
429    * @return the printer.
430    */
visitClassTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)431   public Printer visitClassTypeAnnotation(
432       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
433     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
434   }
435 
436   /**
437    * Class attribute. See {@link org.objectweb.asm.ClassVisitor#visitAttribute}.
438    *
439    * @param attribute an attribute.
440    */
visitClassAttribute(Attribute attribute)441   public abstract void visitClassAttribute(Attribute attribute);
442 
443   /**
444    * Visits a member of the nest. A nest is a set of classes of the same package that share access
445    * to their private members. One of these classes, called the host, lists the other members of the
446    * nest, which in turn should link to the host of their nest. This method must be called only if
447    * the visited class is the host of a nest. A nest host is implicitly a member of its own nest, so
448    * it's invalid to call this method with the visited class name as argument.
449    *
450    * @param nestMember the internal name of a nest member (see {@link Type#getInternalName()}).
451    */
visitNestMember(final String nestMember)452   public void visitNestMember(final String nestMember) {
453     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
454   }
455 
456   /**
457    * Visits a permitted subclasses. A permitted subclass is one of the allowed subclasses of the
458    * current class. See {@link org.objectweb.asm.ClassVisitor#visitPermittedSubclass(String)}.
459    *
460    * @param permittedSubclass the internal name of a permitted subclass (see {@link
461    *     Type#getInternalName()}).
462    */
visitPermittedSubclass(final String permittedSubclass)463   public void visitPermittedSubclass(final String permittedSubclass) {
464     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
465   }
466 
467   /**
468    * Class inner name. See {@link org.objectweb.asm.ClassVisitor#visitInnerClass}.
469    *
470    * @param name the internal name of an inner class (see {@link Type#getInternalName()}).
471    * @param outerName the internal name of the class to which the inner class belongs (see {@link
472    *     Type#getInternalName()}). May be {@literal null} for not member classes.
473    * @param innerName the (simple) name of the inner class inside its enclosing class. May be
474    *     {@literal null} for anonymous inner classes.
475    * @param access the access flags of the inner class as originally declared in the enclosing
476    *     class.
477    */
visitInnerClass(String name, String outerName, String innerName, int access)478   public abstract void visitInnerClass(String name, String outerName, String innerName, int access);
479 
480   /**
481    * Visits a record component of the class. See {@link
482    * org.objectweb.asm.ClassVisitor#visitRecordComponent(String, String, String)}.
483    *
484    * @param name the field's name.
485    * @param descriptor the record component descriptor (see {@link Type}).
486    * @param signature the record component signature. May be {@literal null} if the record component
487    *     type does not use generic types.
488    * @return a visitor to visit this record component annotations and attributes, or {@literal null}
489    *     if this class visitor is not interested in visiting these annotations and attributes.
490    */
visitRecordComponent( final String name, final String descriptor, final String signature)491   public Printer visitRecordComponent(
492       final String name, final String descriptor, final String signature) {
493     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
494   }
495 
496   /**
497    * Class field. See {@link org.objectweb.asm.ClassVisitor#visitField}.
498    *
499    * @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if
500    *     the field is synthetic and/or deprecated.
501    * @param name the field's name.
502    * @param descriptor the field's descriptor (see {@link Type}).
503    * @param signature the field's signature. May be {@literal null} if the field's type does not use
504    *     generic types.
505    * @param value the field's initial value. This parameter, which may be {@literal null} if the
506    *     field does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link
507    *     Long}, a {@link Double} or a {@link String} (for {@code int}, {@code float}, {@code long}
508    *     or {@code String} fields respectively). <i>This parameter is only used for static
509    *     fields</i>. Its value is ignored for non static fields, which must be initialized through
510    *     bytecode instructions in constructors or methods.
511    * @return the printer.
512    */
visitField( int access, String name, String descriptor, String signature, Object value)513   public abstract Printer visitField(
514       int access, String name, String descriptor, String signature, Object value);
515 
516   /**
517    * Class method. See {@link org.objectweb.asm.ClassVisitor#visitMethod}.
518    *
519    * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
520    *     the method is synthetic and/or deprecated.
521    * @param name the method's name.
522    * @param descriptor the method's descriptor (see {@link Type}).
523    * @param signature the method's signature. May be {@literal null} if the method parameters,
524    *     return type and exceptions do not use generic types.
525    * @param exceptions the internal names of the method's exception classes (see {@link
526    *     Type#getInternalName()}). May be {@literal null}.
527    * @return the printer.
528    */
visitMethod( int access, String name, String descriptor, String signature, String[] exceptions)529   public abstract Printer visitMethod(
530       int access, String name, String descriptor, String signature, String[] exceptions);
531 
532   /** Class end. See {@link org.objectweb.asm.ClassVisitor#visitEnd}. */
visitClassEnd()533   public abstract void visitClassEnd();
534 
535   // -----------------------------------------------------------------------------------------------
536   // Modules
537   // -----------------------------------------------------------------------------------------------
538 
539   /**
540    * Module main class. See {@link org.objectweb.asm.ModuleVisitor#visitMainClass}.
541    *
542    * @param mainClass the internal name of the main class of the current module (see {@link
543    *     Type#getInternalName()}).
544    */
visitMainClass(final String mainClass)545   public void visitMainClass(final String mainClass) {
546     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
547   }
548 
549   /**
550    * Module package. See {@link org.objectweb.asm.ModuleVisitor#visitPackage}.
551    *
552    * @param packaze the internal name of a package (see {@link Type#getInternalName()}).
553    */
visitPackage(final String packaze)554   public void visitPackage(final String packaze) {
555     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
556   }
557 
558   /**
559    * Module require. See {@link org.objectweb.asm.ModuleVisitor#visitRequire}.
560    *
561    * @param module the fully qualified name (using dots) of the dependence.
562    * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code
563    *     ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
564    * @param version the module version at compile time, or {@literal null}.
565    */
visitRequire(final String module, final int access, final String version)566   public void visitRequire(final String module, final int access, final String version) {
567     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
568   }
569 
570   /**
571    * Module export. See {@link org.objectweb.asm.ModuleVisitor#visitExport}.
572    *
573    * @param packaze the internal name of the exported package (see {@link Type#getInternalName()}).
574    * @param access the access flag of the exported package, valid values are among {@code
575    *     ACC_SYNTHETIC} and {@code ACC_MANDATED}.
576    * @param modules the fully qualified names (using dots) of the modules that can access the public
577    *     classes of the exported package, or {@literal null}.
578    */
visitExport(final String packaze, final int access, final String... modules)579   public void visitExport(final String packaze, final int access, final String... modules) {
580     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
581   }
582 
583   /**
584    * Module open. See {@link org.objectweb.asm.ModuleVisitor#visitOpen}.
585    *
586    * @param packaze the internal name of the opened package (see {@link Type#getInternalName()}).
587    * @param access the access flag of the opened package, valid values are among {@code
588    *     ACC_SYNTHETIC} and {@code ACC_MANDATED}.
589    * @param modules the fully qualified names (using dots) of the modules that can use deep
590    *     reflection to the classes of the open package, or {@literal null}.
591    */
visitOpen(final String packaze, final int access, final String... modules)592   public void visitOpen(final String packaze, final int access, final String... modules) {
593     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
594   }
595 
596   /**
597    * Module use. See {@link org.objectweb.asm.ModuleVisitor#visitUse}.
598    *
599    * @param service the internal name of the service (see {@link Type#getInternalName()}).
600    */
visitUse(final String service)601   public void visitUse(final String service) {
602     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
603   }
604 
605   /**
606    * Module provide. See {@link org.objectweb.asm.ModuleVisitor#visitProvide}.
607    *
608    * @param service the internal name of the service (see {@link Type#getInternalName()}).
609    * @param providers the internal names of the implementations of the service (there is at least
610    *     one provider).
611    */
visitProvide(final String service, final String... providers)612   public void visitProvide(final String service, final String... providers) {
613     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
614   }
615 
616   /** Module end. See {@link org.objectweb.asm.ModuleVisitor#visitEnd}. */
visitModuleEnd()617   public void visitModuleEnd() {
618     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
619   }
620 
621   // -----------------------------------------------------------------------------------------------
622   // Annotations
623   // -----------------------------------------------------------------------------------------------
624 
625   /**
626    * Annotation value. See {@link org.objectweb.asm.AnnotationVisitor#visit}.
627    *
628    * @param name the value name.
629    * @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link
630    *     Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float}, {@link Double},
631    *     {@link String} or {@link Type} of {@link Type#OBJECT} or {@link Type#ARRAY} sort. This
632    *     value can also be an array of byte, boolean, short, char, int, long, float or double values
633    *     (this is equivalent to using {@link #visitArray} and visiting each array element in turn,
634    *     but is more convenient).
635    */
636   // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different.
visit(String name, Object value)637   public abstract void visit(String name, Object value);
638 
639   /**
640    * Annotation enum value. See {@link org.objectweb.asm.AnnotationVisitor#visitEnum}.
641    *
642    * @param name the value name.
643    * @param descriptor the class descriptor of the enumeration class.
644    * @param value the actual enumeration value.
645    */
visitEnum(String name, String descriptor, String value)646   public abstract void visitEnum(String name, String descriptor, String value);
647 
648   /**
649    * Nested annotation value. See {@link org.objectweb.asm.AnnotationVisitor#visitAnnotation}.
650    *
651    * @param name the value name.
652    * @param descriptor the class descriptor of the nested annotation class.
653    * @return the printer.
654    */
visitAnnotation(String name, String descriptor)655   public abstract Printer visitAnnotation(String name, String descriptor);
656 
657   /**
658    * Annotation array value. See {@link org.objectweb.asm.AnnotationVisitor#visitArray}.
659    *
660    * @param name the value name.
661    * @return the printer.
662    */
visitArray(String name)663   public abstract Printer visitArray(String name);
664 
665   /** Annotation end. See {@link org.objectweb.asm.AnnotationVisitor#visitEnd}. */
visitAnnotationEnd()666   public abstract void visitAnnotationEnd();
667 
668   // -----------------------------------------------------------------------------------------------
669   // Record components
670   // -----------------------------------------------------------------------------------------------
671 
672   /**
673    * Visits an annotation of the record component. See {@link
674    * org.objectweb.asm.RecordComponentVisitor#visitAnnotation}.
675    *
676    * @param descriptor the class descriptor of the annotation class.
677    * @param visible {@literal true} if the annotation is visible at runtime.
678    * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
679    *     interested in visiting this annotation.
680    */
visitRecordComponentAnnotation(final String descriptor, final boolean visible)681   public Printer visitRecordComponentAnnotation(final String descriptor, final boolean visible) {
682     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
683   }
684 
685   /**
686    * Visits an annotation on a type in the record component signature. See {@link
687    * org.objectweb.asm.RecordComponentVisitor#visitTypeAnnotation}.
688    *
689    * @param typeRef a reference to the annotated type. The sort of this type reference must be
690    *     {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link
691    *     TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See
692    *     {@link TypeReference}.
693    * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
694    *     static inner type within 'typeRef'. May be {@literal null} if the annotation targets
695    *     'typeRef' as a whole.
696    * @param descriptor the class descriptor of the annotation class.
697    * @param visible {@literal true} if the annotation is visible at runtime.
698    * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
699    *     interested in visiting this annotation.
700    */
visitRecordComponentTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)701   public Printer visitRecordComponentTypeAnnotation(
702       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
703     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
704   }
705 
706   /**
707    * Visits a non standard attribute of the record component. See {@link
708    * org.objectweb.asm.RecordComponentVisitor#visitAttribute}.
709    *
710    * @param attribute an attribute.
711    */
visitRecordComponentAttribute(final Attribute attribute)712   public void visitRecordComponentAttribute(final Attribute attribute) {
713     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
714   }
715 
716   /**
717    * Visits the end of the record component. See {@link
718    * org.objectweb.asm.RecordComponentVisitor#visitEnd}. This method, which is the last one to be
719    * called, is used to inform the visitor that everything have been visited.
720    */
visitRecordComponentEnd()721   public void visitRecordComponentEnd() {
722     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
723   }
724 
725   // -----------------------------------------------------------------------------------------------
726   // Fields
727   // -----------------------------------------------------------------------------------------------
728 
729   /**
730    * Field annotation. See {@link org.objectweb.asm.FieldVisitor#visitAnnotation}.
731    *
732    * @param descriptor the class descriptor of the annotation class.
733    * @param visible {@literal true} if the annotation is visible at runtime.
734    * @return the printer.
735    */
visitFieldAnnotation(String descriptor, boolean visible)736   public abstract Printer visitFieldAnnotation(String descriptor, boolean visible);
737 
738   /**
739    * Field type annotation. See {@link org.objectweb.asm.FieldVisitor#visitTypeAnnotation}.
740    *
741    * @param typeRef a reference to the annotated type. The sort of this type reference must be
742    *     {@link TypeReference#FIELD}. See {@link TypeReference}.
743    * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
744    *     static inner type within 'typeRef'. May be {@literal null} if the annotation targets
745    *     'typeRef' as a whole.
746    * @param descriptor the class descriptor of the annotation class.
747    * @param visible {@literal true} if the annotation is visible at runtime.
748    * @return the printer.
749    */
visitFieldTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)750   public Printer visitFieldTypeAnnotation(
751       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
752     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
753   }
754 
755   /**
756    * Field attribute. See {@link org.objectweb.asm.FieldVisitor#visitAttribute}.
757    *
758    * @param attribute an attribute.
759    */
visitFieldAttribute(Attribute attribute)760   public abstract void visitFieldAttribute(Attribute attribute);
761 
762   /** Field end. See {@link org.objectweb.asm.FieldVisitor#visitEnd}. */
visitFieldEnd()763   public abstract void visitFieldEnd();
764 
765   // -----------------------------------------------------------------------------------------------
766   // Methods
767   // -----------------------------------------------------------------------------------------------
768 
769   /**
770    * Method parameter. See {@link org.objectweb.asm.MethodVisitor#visitParameter(String, int)}.
771    *
772    * @param name parameter name or {@literal null} if none is provided.
773    * @param access the parameter's access flags, only {@code ACC_FINAL}, {@code ACC_SYNTHETIC}
774    *     or/and {@code ACC_MANDATED} are allowed (see {@link Opcodes}).
775    */
visitParameter(final String name, final int access)776   public void visitParameter(final String name, final int access) {
777     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
778   }
779 
780   /**
781    * Method default annotation. See {@link org.objectweb.asm.MethodVisitor#visitAnnotationDefault}.
782    *
783    * @return the printer.
784    */
visitAnnotationDefault()785   public abstract Printer visitAnnotationDefault();
786 
787   /**
788    * Method annotation. See {@link org.objectweb.asm.MethodVisitor#visitAnnotation}.
789    *
790    * @param descriptor the class descriptor of the annotation class.
791    * @param visible {@literal true} if the annotation is visible at runtime.
792    * @return the printer.
793    */
visitMethodAnnotation(String descriptor, boolean visible)794   public abstract Printer visitMethodAnnotation(String descriptor, boolean visible);
795 
796   /**
797    * Method type annotation. See {@link org.objectweb.asm.MethodVisitor#visitTypeAnnotation}.
798    *
799    * @param typeRef a reference to the annotated type. The sort of this type reference must be
800    *     {@link TypeReference#METHOD_TYPE_PARAMETER}, {@link
801    *     TypeReference#METHOD_TYPE_PARAMETER_BOUND}, {@link TypeReference#METHOD_RETURN}, {@link
802    *     TypeReference#METHOD_RECEIVER}, {@link TypeReference#METHOD_FORMAL_PARAMETER} or {@link
803    *     TypeReference#THROWS}. See {@link TypeReference}.
804    * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
805    *     static inner type within 'typeRef'. May be {@literal null} if the annotation targets
806    *     'typeRef' as a whole.
807    * @param descriptor the class descriptor of the annotation class.
808    * @param visible {@literal true} if the annotation is visible at runtime.
809    * @return the printer.
810    */
visitMethodTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)811   public Printer visitMethodTypeAnnotation(
812       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
813     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
814   }
815 
816   /**
817    * Number of method parameters that can have annotations. See {@link
818    * org.objectweb.asm.MethodVisitor#visitAnnotableParameterCount}.
819    *
820    * @param parameterCount the number of method parameters than can have annotations. This number
821    *     must be less or equal than the number of parameter types in the method descriptor. It can
822    *     be strictly less when a method has synthetic parameters and when these parameters are
823    *     ignored when computing parameter indices for the purpose of parameter annotations (see
824    *     https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
825    * @param visible {@literal true} to define the number of method parameters that can have
826    *     annotations visible at runtime, {@literal false} to define the number of method parameters
827    *     that can have annotations invisible at runtime.
828    * @return the printer.
829    */
visitAnnotableParameterCount(final int parameterCount, final boolean visible)830   public Printer visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
831     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
832   }
833 
834   /**
835    * Method parameter annotation. See {@link
836    * org.objectweb.asm.MethodVisitor#visitParameterAnnotation}.
837    *
838    * @param parameter the parameter index. This index must be strictly smaller than the number of
839    *     parameters in the method descriptor, and strictly smaller than the parameter count
840    *     specified in {@link #visitAnnotableParameterCount}. Important note: <i>a parameter index i
841    *     is not required to correspond to the i'th parameter descriptor in the method
842    *     descriptor</i>, in particular in case of synthetic parameters (see
843    *     https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
844    * @param descriptor the class descriptor of the annotation class.
845    * @param visible {@literal true} if the annotation is visible at runtime.
846    * @return the printer.
847    */
visitParameterAnnotation( int parameter, String descriptor, boolean visible)848   public abstract Printer visitParameterAnnotation(
849       int parameter, String descriptor, boolean visible);
850 
851   /**
852    * Method attribute. See {@link org.objectweb.asm.MethodVisitor#visitAttribute}.
853    *
854    * @param attribute an attribute.
855    */
visitMethodAttribute(Attribute attribute)856   public abstract void visitMethodAttribute(Attribute attribute);
857 
858   /** Method start. See {@link org.objectweb.asm.MethodVisitor#visitCode}. */
visitCode()859   public abstract void visitCode();
860 
861   /**
862    * Method stack frame. See {@link org.objectweb.asm.MethodVisitor#visitFrame}.
863    *
864    * @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded
865    *     frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link
866    *     Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
867    * @param numLocal the number of local variables in the visited frame.
868    * @param local the local variable types in this frame. This array must not be modified. Primitive
869    *     types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
870    *     Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL} or
871    *     {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a single element).
872    *     Reference types are represented by String objects (representing internal names, see {@link
873    *     Type#getInternalName()}), and uninitialized types by Label objects (this label designates
874    *     the NEW instruction that created this uninitialized value).
875    * @param numStack the number of operand stack elements in the visited frame.
876    * @param stack the operand stack types in this frame. This array must not be modified. Its
877    *     content has the same format as the "local" array.
878    */
visitFrame( int type, int numLocal, Object[] local, int numStack, Object[] stack)879   public abstract void visitFrame(
880       int type, int numLocal, Object[] local, int numStack, Object[] stack);
881 
882   /**
883    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitInsn}
884    *
885    * @param opcode the opcode of the instruction to be visited. This opcode is either NOP,
886    *     ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
887    *     LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
888    *     FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
889    *     AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
890    *     SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
891    *     FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR,
892    *     LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I,
893    *     D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
894    *     DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT.
895    */
visitInsn(int opcode)896   public abstract void visitInsn(int opcode);
897 
898   /**
899    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitIntInsn}.
900    *
901    * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH
902    *     or NEWARRAY.
903    * @param operand the operand of the instruction to be visited.<br>
904    *     When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE.
905    *     <br>
906    *     When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE.
907    *     <br>
908    *     When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link
909    *     Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE},
910    *     {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
911    */
visitIntInsn(int opcode, int operand)912   public abstract void visitIntInsn(int opcode, int operand);
913 
914   /**
915    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitVarInsn}.
916    *
917    * @param opcode the opcode of the local variable instruction to be visited. This opcode is either
918    *     ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
919    * @param varIndex the operand of the instruction to be visited. This operand is the index of a
920    *     local variable.
921    */
visitVarInsn(int opcode, int varIndex)922   public abstract void visitVarInsn(int opcode, int varIndex);
923 
924   /**
925    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitTypeInsn}.
926    *
927    * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW,
928    *     ANEWARRAY, CHECKCAST or INSTANCEOF.
929    * @param type the operand of the instruction to be visited. This operand must be the internal
930    *     name of an object or array class (see {@link Type#getInternalName()}).
931    */
visitTypeInsn(int opcode, String type)932   public abstract void visitTypeInsn(int opcode, String type);
933 
934   /**
935    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitFieldInsn}.
936    *
937    * @param opcode the opcode of the type instruction to be visited. This opcode is either
938    *     GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
939    * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}).
940    * @param name the field's name.
941    * @param descriptor the field's descriptor (see {@link Type}).
942    */
visitFieldInsn(int opcode, String owner, String name, String descriptor)943   public abstract void visitFieldInsn(int opcode, String owner, String name, String descriptor);
944 
945   /**
946    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitMethodInsn}.
947    *
948    * @param opcode the opcode of the type instruction to be visited. This opcode is either
949    *     INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
950    * @param owner the internal name of the method's owner class (see {@link
951    *     Type#getInternalName()}).
952    * @param name the method's name.
953    * @param descriptor the method's descriptor (see {@link Type}).
954    * @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
955    */
956   @Deprecated
visitMethodInsn( final int opcode, final String owner, final String name, final String descriptor)957   public void visitMethodInsn(
958       final int opcode, final String owner, final String name, final String descriptor) {
959     // This method was abstract before ASM5, and was therefore always overridden (without any
960     // call to 'super'). Thus, at this point we necessarily have api >= ASM5, and we must then
961     // redirect the method call to the ASM5 visitMethodInsn() method.
962     visitMethodInsn(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
963   }
964 
965   /**
966    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitMethodInsn}.
967    *
968    * @param opcode the opcode of the type instruction to be visited. This opcode is either
969    *     INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
970    * @param owner the internal name of the method's owner class (see {@link
971    *     Type#getInternalName()}).
972    * @param name the method's name.
973    * @param descriptor the method's descriptor (see {@link Type}).
974    * @param isInterface if the method's owner class is an interface.
975    */
visitMethodInsn( final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface)976   public void visitMethodInsn(
977       final int opcode,
978       final String owner,
979       final String name,
980       final String descriptor,
981       final boolean isInterface) {
982     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
983   }
984 
985   /**
986    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}.
987    *
988    * @param name the method's name.
989    * @param descriptor the method's descriptor (see {@link Type}).
990    * @param bootstrapMethodHandle the bootstrap method.
991    * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be
992    *     an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link
993    *     Type} or {@link Handle} value. This method is allowed to modify the content of the array so
994    *     a caller should expect that this array may change.
995    */
visitInvokeDynamicInsn( String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments)996   public abstract void visitInvokeDynamicInsn(
997       String name,
998       String descriptor,
999       Handle bootstrapMethodHandle,
1000       Object... bootstrapMethodArguments);
1001 
1002   /**
1003    * Method jump instruction. See {@link org.objectweb.asm.MethodVisitor#visitJumpInsn}.
1004    *
1005    * @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ,
1006    *     IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
1007    *     IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
1008    * @param label the operand of the instruction to be visited. This operand is a label that
1009    *     designates the instruction to which the jump instruction may jump.
1010    */
visitJumpInsn(int opcode, Label label)1011   public abstract void visitJumpInsn(int opcode, Label label);
1012 
1013   /**
1014    * Method label. See {@link org.objectweb.asm.MethodVisitor#visitLabel}.
1015    *
1016    * @param label a {@link Label} object.
1017    */
visitLabel(Label label)1018   public abstract void visitLabel(Label label);
1019 
1020   /**
1021    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitLdcInsn}.
1022    *
1023    * @param value the constant to be loaded on the stack. This parameter must be a non null {@link
1024    *     Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link
1025    *     Type} of OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is
1026    *     49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle
1027    *     constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant
1028    *     dynamic for classes whose version is 55.
1029    */
visitLdcInsn(Object value)1030   public abstract void visitLdcInsn(Object value);
1031 
1032   /**
1033    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitIincInsn}.
1034    *
1035    * @param varIndex index of the local variable to be incremented.
1036    * @param increment amount to increment the local variable by.
1037    */
visitIincInsn(int varIndex, int increment)1038   public abstract void visitIincInsn(int varIndex, int increment);
1039 
1040   /**
1041    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitTableSwitchInsn}.
1042    *
1043    * @param min the minimum key value.
1044    * @param max the maximum key value.
1045    * @param dflt beginning of the default handler block.
1046    * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
1047    *     handler block for the {@code min + i} key.
1048    */
visitTableSwitchInsn(int min, int max, Label dflt, Label... labels)1049   public abstract void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels);
1050 
1051   /**
1052    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn}.
1053    *
1054    * @param dflt beginning of the default handler block.
1055    * @param keys the values of the keys.
1056    * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
1057    *     handler block for the {@code keys[i]} key.
1058    */
visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)1059   public abstract void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels);
1060 
1061   /**
1062    * Method instruction. See {@link org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}.
1063    *
1064    * @param descriptor an array type descriptor (see {@link Type}).
1065    * @param numDimensions the number of dimensions of the array to allocate.
1066    */
visitMultiANewArrayInsn(String descriptor, int numDimensions)1067   public abstract void visitMultiANewArrayInsn(String descriptor, int numDimensions);
1068 
1069   /**
1070    * Instruction type annotation. See {@link org.objectweb.asm.MethodVisitor#visitInsnAnnotation}.
1071    *
1072    * @param typeRef a reference to the annotated type. The sort of this type reference must be
1073    *     {@link TypeReference#INSTANCEOF}, {@link TypeReference#NEW}, {@link
1074    *     TypeReference#CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE}, {@link
1075    *     TypeReference#CAST}, {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link
1076    *     TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
1077    *     TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link
1078    *     TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
1079    * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
1080    *     static inner type within 'typeRef'. May be {@literal null} if the annotation targets
1081    *     'typeRef' as a whole.
1082    * @param descriptor the class descriptor of the annotation class.
1083    * @param visible {@literal true} if the annotation is visible at runtime.
1084    * @return the printer.
1085    */
visitInsnAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)1086   public Printer visitInsnAnnotation(
1087       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
1088     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
1089   }
1090 
1091   /**
1092    * Method exception handler. See {@link org.objectweb.asm.MethodVisitor#visitTryCatchBlock}.
1093    *
1094    * @param start the beginning of the exception handler's scope (inclusive).
1095    * @param end the end of the exception handler's scope (exclusive).
1096    * @param handler the beginning of the exception handler's code.
1097    * @param type the internal name of the type of exceptions handled by the handler (see {@link
1098    *     Type#getInternalName()}), or {@literal null} to catch any exceptions (for "finally"
1099    *     blocks).
1100    */
visitTryCatchBlock(Label start, Label end, Label handler, String type)1101   public abstract void visitTryCatchBlock(Label start, Label end, Label handler, String type);
1102 
1103   /**
1104    * Try catch block type annotation. See {@link
1105    * org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
1106    *
1107    * @param typeRef a reference to the annotated type. The sort of this type reference must be
1108    *     {@link TypeReference#EXCEPTION_PARAMETER}. See {@link TypeReference}.
1109    * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
1110    *     static inner type within 'typeRef'. May be {@literal null} if the annotation targets
1111    *     'typeRef' as a whole.
1112    * @param descriptor the class descriptor of the annotation class.
1113    * @param visible {@literal true} if the annotation is visible at runtime.
1114    * @return the printer.
1115    */
visitTryCatchAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)1116   public Printer visitTryCatchAnnotation(
1117       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
1118     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
1119   }
1120 
1121   /**
1122    * Method debug info. See {@link org.objectweb.asm.MethodVisitor#visitLocalVariable}.
1123    *
1124    * @param name the name of a local variable.
1125    * @param descriptor the type descriptor of this local variable.
1126    * @param signature the type signature of this local variable. May be {@literal null} if the local
1127    *     variable type does not use generic types.
1128    * @param start the first instruction corresponding to the scope of this local variable
1129    *     (inclusive).
1130    * @param end the last instruction corresponding to the scope of this local variable (exclusive).
1131    * @param index the local variable's index.
1132    */
visitLocalVariable( String name, String descriptor, String signature, Label start, Label end, int index)1133   public abstract void visitLocalVariable(
1134       String name, String descriptor, String signature, Label start, Label end, int index);
1135 
1136   /**
1137    * Local variable type annotation. See {@link
1138    * org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
1139    *
1140    * @param typeRef a reference to the annotated type. The sort of this type reference must be
1141    *     {@link TypeReference#LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE}. See {@link
1142    *     TypeReference}.
1143    * @param typePath the path to the annotated type argument, wildcard bound, array element type, or
1144    *     static inner type within 'typeRef'. May be {@literal null} if the annotation targets
1145    *     'typeRef' as a whole.
1146    * @param start the fist instructions corresponding to the continuous ranges that make the scope
1147    *     of this local variable (inclusive).
1148    * @param end the last instructions corresponding to the continuous ranges that make the scope of
1149    *     this local variable (exclusive). This array must have the same size as the 'start' array.
1150    * @param index the local variable's index in each range. This array must have the same size as
1151    *     the 'start' array.
1152    * @param descriptor the class descriptor of the annotation class.
1153    * @param visible {@literal true} if the annotation is visible at runtime.
1154    * @return the printer.
1155    */
visitLocalVariableAnnotation( final int typeRef, final TypePath typePath, final Label[] start, final Label[] end, final int[] index, final String descriptor, final boolean visible)1156   public Printer visitLocalVariableAnnotation(
1157       final int typeRef,
1158       final TypePath typePath,
1159       final Label[] start,
1160       final Label[] end,
1161       final int[] index,
1162       final String descriptor,
1163       final boolean visible) {
1164     throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
1165   }
1166 
1167   /**
1168    * Method debug info. See {@link org.objectweb.asm.MethodVisitor#visitLineNumber}.
1169    *
1170    * @param line a line number. This number refers to the source file from which the class was
1171    *     compiled.
1172    * @param start the first instruction corresponding to this line number.
1173    */
visitLineNumber(int line, Label start)1174   public abstract void visitLineNumber(int line, Label start);
1175 
1176   /**
1177    * Method max stack and max locals. See {@link org.objectweb.asm.MethodVisitor#visitMaxs}.
1178    *
1179    * @param maxStack maximum stack size of the method.
1180    * @param maxLocals maximum number of local variables for the method.
1181    */
visitMaxs(int maxStack, int maxLocals)1182   public abstract void visitMaxs(int maxStack, int maxLocals);
1183 
1184   /** Method end. See {@link org.objectweb.asm.MethodVisitor#visitEnd}. */
visitMethodEnd()1185   public abstract void visitMethodEnd();
1186 
1187   // -----------------------------------------------------------------------------------------------
1188   // Print and utility methods
1189   // -----------------------------------------------------------------------------------------------
1190 
1191   /**
1192    * Returns the text constructed by this visitor.
1193    *
1194    * @return the text constructed by this visitor. See {@link #text}.
1195    */
getText()1196   public List<Object> getText() {
1197     return text;
1198   }
1199 
1200   /**
1201    * Prints the text constructed by this visitor.
1202    *
1203    * @param printWriter the print writer to be used.
1204    */
print(final PrintWriter printWriter)1205   public void print(final PrintWriter printWriter) {
1206     printList(printWriter, text);
1207   }
1208 
1209   /**
1210    * Prints the given string tree.
1211    *
1212    * @param printWriter the writer to be used to print the tree.
1213    * @param list a string tree, i.e., a string list that can contain other string lists, and so on
1214    *     recursively.
1215    */
printList(final PrintWriter printWriter, final List<?> list)1216   static void printList(final PrintWriter printWriter, final List<?> list) {
1217     for (Object o : list) {
1218       if (o instanceof List) {
1219         printList(printWriter, (List<?>) o);
1220       } else {
1221         printWriter.print(o.toString());
1222       }
1223     }
1224   }
1225 
1226   /**
1227    * Appends a quoted string to the given string builder.
1228    *
1229    * @param stringBuilder the buffer where the string must be added.
1230    * @param string the string to be added.
1231    */
appendString(final StringBuilder stringBuilder, final String string)1232   public static void appendString(final StringBuilder stringBuilder, final String string) {
1233     stringBuilder.append('\"');
1234     for (int i = 0; i < string.length(); ++i) {
1235       char c = string.charAt(i);
1236       if (c == '\n') {
1237         stringBuilder.append("\\n");
1238       } else if (c == '\r') {
1239         stringBuilder.append("\\r");
1240       } else if (c == '\\') {
1241         stringBuilder.append("\\\\");
1242       } else if (c == '"') {
1243         stringBuilder.append("\\\"");
1244       } else if (c < 0x20 || c > 0x7f) {
1245         stringBuilder.append("\\u");
1246         if (c < 0x10) {
1247           stringBuilder.append("000");
1248         } else if (c < 0x100) {
1249           stringBuilder.append("00");
1250         } else if (c < 0x1000) {
1251           stringBuilder.append('0');
1252         }
1253         stringBuilder.append(Integer.toString(c, 16));
1254       } else {
1255         stringBuilder.append(c);
1256       }
1257     }
1258     stringBuilder.append('\"');
1259   }
1260 
1261   /**
1262    * Prints the given class to the given output.
1263    *
1264    * <p>Command line arguments: [-nodebug] &lt;binary class name or class file name &gt;
1265    *
1266    * @param args the command line arguments.
1267    * @param usage the help message to show when command line arguments are incorrect.
1268    * @param printer the printer to convert the class into text.
1269    * @param output where to print the result.
1270    * @param logger where to log errors.
1271    * @throws IOException if the class cannot be found, or if an IOException occurs.
1272    */
main( final String[] args, final String usage, final Printer printer, final PrintWriter output, final PrintWriter logger)1273   static void main(
1274       final String[] args,
1275       final String usage,
1276       final Printer printer,
1277       final PrintWriter output,
1278       final PrintWriter logger)
1279       throws IOException {
1280     if (args.length < 1
1281         || args.length > 2
1282         || ((args[0].equals("-debug") || args[0].equals("-nodebug")) && args.length != 2)) {
1283       logger.println(usage);
1284       return;
1285     }
1286 
1287     TraceClassVisitor traceClassVisitor = new TraceClassVisitor(null, printer, output);
1288 
1289     String className;
1290     int parsingOptions;
1291     if (args[0].equals("-nodebug")) {
1292       className = args[1];
1293       parsingOptions = ClassReader.SKIP_DEBUG;
1294     } else {
1295       className = args[0];
1296       parsingOptions = 0;
1297     }
1298 
1299     if (className.endsWith(".class")
1300         || className.indexOf('\\') != -1
1301         || className.indexOf('/') != -1) {
1302       // Can't fix PMD warning for 1.5 compatibility.
1303       try (InputStream inputStream = new FileInputStream(className)) { // NOPMD(AvoidFileStream)
1304         new ClassReader(inputStream).accept(traceClassVisitor, parsingOptions);
1305       }
1306     } else {
1307       new ClassReader(className).accept(traceClassVisitor, parsingOptions);
1308     }
1309   }
1310 }
1311