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