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 */
59package jdk.internal.org.objectweb.asm.util;
60
61import java.io.PrintWriter;
62import java.util.ArrayList;
63import java.util.List;
64
65import jdk.internal.org.objectweb.asm.Attribute;
66import jdk.internal.org.objectweb.asm.Handle;
67import jdk.internal.org.objectweb.asm.Label;
68import jdk.internal.org.objectweb.asm.Opcodes;
69import jdk.internal.org.objectweb.asm.TypePath;
70
71/**
72 * An abstract converter from visit events to text.
73 *
74 * @author Eric Bruneton
75 */
76public abstract class Printer {
77
78    /**
79     * The names of the Java Virtual Machine opcodes.
80     */
81    public static final String[] OPCODES;
82
83    /**
84     * The names of the for <code>operand</code> parameter values of the
85     * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIntInsn} method when
86     * <code>opcode</code> is <code>NEWARRAY</code>.
87     */
88    public static final String[] TYPES;
89
90    /**
91     * The names of the <code>tag</code> field values for
92     * {@link jdk.internal.org.objectweb.asm.Handle}.
93     */
94    public static final String[] HANDLE_TAG;
95
96    static {
97        String s = "NOP,ACONST_NULL,ICONST_M1,ICONST_0,ICONST_1,ICONST_2,"
98                + "ICONST_3,ICONST_4,ICONST_5,LCONST_0,LCONST_1,FCONST_0,"
99                + "FCONST_1,FCONST_2,DCONST_0,DCONST_1,BIPUSH,SIPUSH,LDC,,,"
100                + "ILOAD,LLOAD,FLOAD,DLOAD,ALOAD,,,,,,,,,,,,,,,,,,,,,IALOAD,"
101                + "LALOAD,FALOAD,DALOAD,AALOAD,BALOAD,CALOAD,SALOAD,ISTORE,"
102                + "LSTORE,FSTORE,DSTORE,ASTORE,,,,,,,,,,,,,,,,,,,,,IASTORE,"
103                + "LASTORE,FASTORE,DASTORE,AASTORE,BASTORE,CASTORE,SASTORE,POP,"
104                + "POP2,DUP,DUP_X1,DUP_X2,DUP2,DUP2_X1,DUP2_X2,SWAP,IADD,LADD,"
105                + "FADD,DADD,ISUB,LSUB,FSUB,DSUB,IMUL,LMUL,FMUL,DMUL,IDIV,LDIV,"
106                + "FDIV,DDIV,IREM,LREM,FREM,DREM,INEG,LNEG,FNEG,DNEG,ISHL,LSHL,"
107                + "ISHR,LSHR,IUSHR,LUSHR,IAND,LAND,IOR,LOR,IXOR,LXOR,IINC,I2L,"
108                + "I2F,I2D,L2I,L2F,L2D,F2I,F2L,F2D,D2I,D2L,D2F,I2B,I2C,I2S,LCMP,"
109                + "FCMPL,FCMPG,DCMPL,DCMPG,IFEQ,IFNE,IFLT,IFGE,IFGT,IFLE,"
110                + "IF_ICMPEQ,IF_ICMPNE,IF_ICMPLT,IF_ICMPGE,IF_ICMPGT,IF_ICMPLE,"
111                + "IF_ACMPEQ,IF_ACMPNE,GOTO,JSR,RET,TABLESWITCH,LOOKUPSWITCH,"
112                + "IRETURN,LRETURN,FRETURN,DRETURN,ARETURN,RETURN,GETSTATIC,"
113                + "PUTSTATIC,GETFIELD,PUTFIELD,INVOKEVIRTUAL,INVOKESPECIAL,"
114                + "INVOKESTATIC,INVOKEINTERFACE,INVOKEDYNAMIC,NEW,NEWARRAY,"
115                + "ANEWARRAY,ARRAYLENGTH,ATHROW,CHECKCAST,INSTANCEOF,"
116                + "MONITORENTER,MONITOREXIT,,MULTIANEWARRAY,IFNULL,IFNONNULL,";
117        OPCODES = new String[200];
118        int i = 0;
119        int j = 0;
120        int l;
121        while ((l = s.indexOf(',', j)) > 0) {
122            OPCODES[i++] = j + 1 == l ? null : s.substring(j, l);
123            j = l + 1;
124        }
125
126        s = "T_BOOLEAN,T_CHAR,T_FLOAT,T_DOUBLE,T_BYTE,T_SHORT,T_INT,T_LONG,";
127        TYPES = new String[12];
128        j = 0;
129        i = 4;
130        while ((l = s.indexOf(',', j)) > 0) {
131            TYPES[i++] = s.substring(j, l);
132            j = l + 1;
133        }
134
135        s = "H_GETFIELD,H_GETSTATIC,H_PUTFIELD,H_PUTSTATIC,"
136                + "H_INVOKEVIRTUAL,H_INVOKESTATIC,H_INVOKESPECIAL,"
137                + "H_NEWINVOKESPECIAL,H_INVOKEINTERFACE,";
138        HANDLE_TAG = new String[10];
139        j = 0;
140        i = 1;
141        while ((l = s.indexOf(',', j)) > 0) {
142            HANDLE_TAG[i++] = s.substring(j, l);
143            j = l + 1;
144        }
145    }
146
147    /**
148     * The ASM API version implemented by this class. The value of this field
149     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
150     */
151    protected final int api;
152
153    /**
154     * A buffer that can be used to create strings.
155     */
156    protected final StringBuffer buf;
157
158    /**
159     * The text to be printed. Since the code of methods is not necessarily
160     * visited in sequential order, one method after the other, but can be
161     * interlaced (some instructions from method one, then some instructions
162     * from method two, then some instructions from method one again...), it is
163     * not possible to print the visited instructions directly to a sequential
164     * stream. A class is therefore printed in a two steps process: a string
165     * tree is constructed during the visit, and printed to a sequential stream
166     * at the end of the visit. This string tree is stored in this field, as a
167     * string list that can contain other string lists, which can themselves
168     * contain other string lists, and so on.
169     */
170    public final List<Object> text;
171
172    /**
173     * Constructs a new {@link Printer}.
174     *
175     * @param api
176     *            the ASM API version implemented by this printer. Must be one
177     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
178     */
179    protected Printer(final int api) {
180        this.api = api;
181        this.buf = new StringBuffer();
182        this.text = new ArrayList<Object>();
183    }
184
185    /**
186     * Class header.
187     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visit}.
188     *
189     * @param version
190     *            the class version.
191     * @param access
192     *            the class's access flags (see {@link Opcodes}). This parameter
193     *            also indicates if the class is deprecated.
194     * @param name
195     *            the internal name of the class (see
196     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
197     * @param signature
198     *            the signature of this class. May be <tt>null</tt> if the class
199     *            is not a generic one, and does not extend or implement generic
200     *            classes or interfaces.
201     * @param superName
202     *            the internal of name of the super class (see
203     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
204     *            For interfaces, the super class is {@link Object}. May be
205     *            <tt>null</tt>, but only for the {@link Object} class.
206     * @param interfaces
207     *            the internal names of the class's interfaces (see
208     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
209     *            May be <tt>null</tt>.
210     */
211    public abstract void visit(final int version, final int access,
212            final String name, final String signature, final String superName,
213            final String[] interfaces);
214
215    /**
216     * Class source.
217     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitSource}.
218     *
219     * @param source
220     *            the name of the source file from which the class was compiled.
221     *            May be <tt>null</tt>.
222     * @param debug
223     *            additional debug information to compute the correspondance
224     *            between source and compiled elements of the class. May be
225     *            <tt>null</tt>.
226     */
227    public abstract void visitSource(final String source, final String debug);
228
229    /**
230     * Class outer class.
231     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}.
232     *
233     * Visits the enclosing class of the class. This method must be called only
234     * if the class has an enclosing class.
235     *
236     * @param owner
237     *            internal name of the enclosing class of the class.
238     * @param name
239     *            the name of the method that contains the class, or
240     *            <tt>null</tt> if the class is not enclosed in a method of its
241     *            enclosing class.
242     * @param desc
243     *            the descriptor of the method that contains the class, or
244     *            <tt>null</tt> if the class is not enclosed in a method of its
245     *            enclosing class.
246     */
247    public abstract void visitOuterClass(final String owner, final String name,
248            final String desc);
249
250    /**
251     * Class annotation.
252     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAnnotation}.
253     *
254     * @param desc
255     *            the class descriptor of the annotation class.
256     * @param visible
257     *            <tt>true</tt> if the annotation is visible at runtime.
258     * @return the printer
259     */
260    public abstract Printer visitClassAnnotation(final String desc,
261            final boolean visible);
262
263    /**
264     * Class type annotation.
265     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitTypeAnnotation}.
266     *
267     * @param typeRef
268     *            a reference to the annotated type. The sort of this type
269     *            reference must be
270     *            {@link jdk.internal.org.objectweb.asm.TypeReference#CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
271     *            {@link jdk.internal.org.objectweb.asm.TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND}
272     *            or {@link jdk.internal.org.objectweb.asm.TypeReference#CLASS_EXTENDS CLASS_EXTENDS}.
273     *            See {@link jdk.internal.org.objectweb.asm.TypeReference}.
274     * @param typePath
275     *            the path to the annotated type argument, wildcard bound, array
276     *            element type, or static inner type within 'typeRef'. May be
277     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
278     * @param desc
279     *            the class descriptor of the annotation class.
280     * @param visible
281     *            <tt>true</tt> if the annotation is visible at runtime.
282     * @return the printer
283     */
284    public Printer visitClassTypeAnnotation(final int typeRef,
285            final TypePath typePath, final String desc, final boolean visible) {
286        throw new RuntimeException("Must be overriden");
287    }
288
289    /**
290     * Class attribute.
291     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAttribute}.
292     *
293     * @param attr
294     *            an attribute.
295     */
296    public abstract void visitClassAttribute(final Attribute attr);
297
298    /**
299     * Class inner name.
300     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitInnerClass}.
301     *
302     * @param name
303     *            the internal name of an inner class (see
304     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
305     * @param outerName
306     *            the internal name of the class to which the inner class
307     *            belongs (see {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
308     *            May be <tt>null</tt> for not member classes.
309     * @param innerName
310     *            the (simple) name of the inner class inside its enclosing
311     *            class. May be <tt>null</tt> for anonymous inner classes.
312     * @param access
313     *            the access flags of the inner class as originally declared in
314     *            the enclosing class.
315     */
316    public abstract void visitInnerClass(final String name,
317            final String outerName, final String innerName, final int access);
318
319    /**
320     * Class field.
321     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitField}.
322     *
323     * @param access
324     *            the field's access flags (see {@link Opcodes}). This parameter
325     *            also indicates if the field is synthetic and/or deprecated.
326     * @param name
327     *            the field's name.
328     * @param desc
329     *            the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type Type}).
330     * @param signature
331     *            the field's signature. May be <tt>null</tt> if the field's
332     *            type does not use generic types.
333     * @param value
334     *            the field's initial value. This parameter, which may be
335     *            <tt>null</tt> if the field does not have an initial value,
336     *            must be an {@link Integer}, a {@link Float}, a {@link Long}, a
337     *            {@link Double} or a {@link String} (for <tt>int</tt>,
338     *            <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
339     *            respectively). <i>This parameter is only used for static
340     *            fields</i>. Its value is ignored for non static fields, which
341     *            must be initialized through bytecode instructions in
342     *            constructors or methods.
343     * @return the printer
344     */
345    public abstract Printer visitField(final int access, final String name,
346            final String desc, final String signature, final Object value);
347
348    /**
349     * Class method.
350     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitMethod}.
351     *
352     * @param access
353     *            the method's access flags (see {@link Opcodes}). This
354     *            parameter also indicates if the method is synthetic and/or
355     *            deprecated.
356     * @param name
357     *            the method's name.
358     * @param desc
359     *            the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type Type}).
360     * @param signature
361     *            the method's signature. May be <tt>null</tt> if the method
362     *            parameters, return type and exceptions do not use generic
363     *            types.
364     * @param exceptions
365     *            the internal names of the method's exception classes (see
366     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}). May be
367     *            <tt>null</tt>.
368     * @return the printer
369     */
370    public abstract Printer visitMethod(final int access, final String name,
371            final String desc, final String signature, final String[] exceptions);
372
373    /**
374     * Class end. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitEnd}.
375     */
376    public abstract void visitClassEnd();
377
378    // ------------------------------------------------------------------------
379    // Annotations
380    // ------------------------------------------------------------------------
381
382    /**
383     * Annotation value.
384     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visit}.
385     *
386     * @param name
387     *            the value name.
388     * @param value
389     *            the actual value, whose type must be {@link Byte},
390     *            {@link Boolean}, {@link Character}, {@link Short},
391     *            {@link Integer} , {@link Long}, {@link Float}, {@link Double},
392     *            {@link String} or {@link jdk.internal.org.objectweb.asm.Type}
393     *            or OBJECT or ARRAY sort.
394     *            This value can also be an array of byte, boolean, short, char, int,
395     *            long, float or double values (this is equivalent to using
396     *            {@link #visitArray visitArray} and visiting each array element
397     *            in turn, but is more convenient).
398     */
399    public abstract void visit(final String name, final Object value);
400
401    /**
402     * Annotation enum value.
403     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnum}.
404     *
405     * Visits an enumeration value of the annotation.
406     *
407     * @param name
408     *            the value name.
409     * @param desc
410     *            the class descriptor of the enumeration class.
411     * @param value
412     *            the actual enumeration value.
413     */
414    public abstract void visitEnum(final String name, final String desc,
415            final String value);
416
417    /**
418     * Nested annotation value.
419     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitAnnotation}.
420     *
421     * @param name
422     *            the value name.
423     * @param desc
424     *            the class descriptor of the nested annotation class.
425     * @return the printer
426     */
427    public abstract Printer visitAnnotation(final String name, final String desc);
428
429    /**
430     * Annotation array value.
431     * See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitArray}.
432     *
433     * Visits an array value of the annotation. Note that arrays of primitive
434     * types (such as byte, boolean, short, char, int, long, float or double)
435     * can be passed as value to {@link #visit visit}. This is what
436     * {@link jdk.internal.org.objectweb.asm.ClassReader} does.
437     *
438     * @param name
439     *            the value name.
440     * @return the printer
441     */
442    public abstract Printer visitArray(final String name);
443
444    /**
445     * Annotation end. See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnd}.
446     */
447    public abstract void visitAnnotationEnd();
448
449    // ------------------------------------------------------------------------
450    // Fields
451    // ------------------------------------------------------------------------
452
453    /**
454     * Field annotation.
455     * See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAnnotation}.
456     *
457     * @param desc
458     *            the class descriptor of the annotation class.
459     * @param visible
460     *            <tt>true</tt> if the annotation is visible at runtime.
461     * @return the printer
462     */
463    public abstract Printer visitFieldAnnotation(final String desc,
464            final boolean visible);
465
466    /**
467     * Field type annotation.
468     * See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitTypeAnnotation}.
469     *
470     * @param typeRef
471     *            a reference to the annotated type. The sort of this type
472     *            reference must be {@link jdk.internal.org.objectweb.asm.TypeReference#FIELD FIELD}.
473     *            See {@link jdk.internal.org.objectweb.asm.TypeReference}.
474     * @param typePath
475     *            the path to the annotated type argument, wildcard bound, array
476     *            element type, or static inner type within 'typeRef'. May be
477     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
478     * @param desc
479     *            the class descriptor of the annotation class.
480     * @param visible
481     *            <tt>true</tt> if the annotation is visible at runtime.
482     * @return the printer
483     */
484    public Printer visitFieldTypeAnnotation(final int typeRef,
485            final TypePath typePath, final String desc, final boolean visible) {
486        throw new RuntimeException("Must be overriden");
487    }
488
489    /**
490     * Field attribute.
491     * See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAttribute}.
492     *
493     * @param attr
494     *            an attribute.
495     */
496    public abstract void visitFieldAttribute(final Attribute attr);
497
498    /**
499     * Field end.
500     * See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitEnd}.
501     */
502    public abstract void visitFieldEnd();
503
504    // ------------------------------------------------------------------------
505    // Methods
506    // ------------------------------------------------------------------------
507
508    /**
509     * Method parameter.
510     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitParameter(String, int)}.
511     *
512     * @param name
513     *            parameter name or null if none is provided.
514     * @param access
515     *            the parameter's access flags, only <tt>ACC_FINAL</tt>,
516     *            <tt>ACC_SYNTHETIC</tt> or/and <tt>ACC_MANDATED</tt> are
517     *            allowed (see {@link Opcodes}).
518     */
519    public void visitParameter(String name, int access) {
520        throw new RuntimeException("Must be overriden");
521    }
522
523    /**
524     * Method default annotation.
525     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotationDefault}.
526     *
527     * @return the printer
528     */
529    public abstract Printer visitAnnotationDefault();
530
531    /**
532     * Method annotation.
533     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotation}.
534     *
535     * @param desc
536     *            the class descriptor of the annotation class.
537     * @param visible
538     *            <tt>true</tt> if the annotation is visible at runtime.
539     * @return the printer
540     */
541    public abstract Printer visitMethodAnnotation(final String desc,
542            final boolean visible);
543
544    /**
545     * Method type annotation.
546     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeAnnotation}.
547     *
548     * @param typeRef
549     *            a reference to the annotated type. The sort of this type
550     *            reference must be {@link jdk.internal.org.objectweb.asm.TypeReference#FIELD FIELD}.
551     *            See {@link jdk.internal.org.objectweb.asm.TypeReference}.
552     * @param typePath
553     *            the path to the annotated type argument, wildcard bound, array
554     *            element type, or static inner type within 'typeRef'. May be
555     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
556     * @param desc
557     *            the class descriptor of the annotation class.
558     * @param visible
559     *            <tt>true</tt> if the annotation is visible at runtime.
560     * @return the printer
561     */
562    public Printer visitMethodTypeAnnotation(final int typeRef,
563            final TypePath typePath, final String desc, final boolean visible) {
564        throw new RuntimeException("Must be overriden");
565    }
566
567    /**
568     * Method parameter annotation.
569     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitParameterAnnotation}.
570     *
571     * @param parameter
572     *            the parameter index.
573     * @param desc
574     *            the class descriptor of the annotation class.
575     * @param visible
576     *            <tt>true</tt> if the annotation is visible at runtime.
577     * @return the printer
578     */
579    public abstract Printer visitParameterAnnotation(final int parameter,
580            final String desc, final boolean visible);
581
582    /**
583     * Method attribute.
584     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAttribute}.
585     *
586     * @param attr
587     *            an attribute.
588     */
589    public abstract void visitMethodAttribute(final Attribute attr);
590
591    /**
592     * Method start.
593     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitCode}.
594     */
595    public abstract void visitCode();
596
597    /**
598     * Method stack frame.
599     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFrame}.
600     *
601     * Visits the current state of the local variables and operand stack
602     * elements. This method must(*) be called <i>just before</i> any
603     * instruction <b>i</b> that follows an unconditional branch instruction
604     * such as GOTO or THROW, that is the target of a jump instruction, or that
605     * starts an exception handler block. The visited types must describe the
606     * values of the local variables and of the operand stack elements <i>just
607     * before</i> <b>i</b> is executed.<br>
608     * <br>
609     * (*) this is mandatory only for classes whose version is greater than or
610     * equal to {@link Opcodes#V1_6 V1_6}. <br>
611     * <br>
612     * The frames of a method must be given either in expanded form, or in
613     * compressed form (all frames must use the same format, i.e. you must not
614     * mix expanded and compressed frames within a single method):
615     * <ul>
616     * <li>In expanded form, all frames must have the F_NEW type.</li>
617     * <li>In compressed form, frames are basically "deltas" from the state of
618     * the previous frame:
619     * <ul>
620     * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
621     * locals as the previous frame and with the empty stack.</li>
622     * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same
623     * locals as the previous frame and with single value on the stack (
624     * <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the
625     * type of the stack item).</li>
626     * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
627     * the same as the locals in the previous frame, except that additional
628     * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
629     * <code>local</code> elements contains values representing added types).</li>
630     * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
631     * same as the locals in the previous frame, except that the last 1-3 locals
632     * are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
633     * <li>{@link Opcodes#F_FULL} representing complete frame data.</li>
634     * </ul>
635     * </li>
636     * </ul>
637     * <br>
638     * In both cases the first frame, corresponding to the method's parameters
639     * and access flags, is implicit and must not be visited. Also, it is
640     * illegal to visit two or more frames for the same code location (i.e., at
641     * least one instruction must be visited between two calls to visitFrame).
642     *
643     * @param type
644     *            the type of this stack map frame. Must be
645     *            {@link Opcodes#F_NEW} for expanded frames, or
646     *            {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
647     *            {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
648     *            {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
649     *            compressed frames.
650     * @param nLocal
651     *            the number of local variables in the visited frame.
652     * @param local
653     *            the local variable types in this frame. This array must not be
654     *            modified. Primitive types are represented by
655     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
656     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
657     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
658     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
659     *            represented by a single element). Reference types are
660     *            represented by String objects (representing internal names),
661     *            and uninitialized types by Label objects (this label
662     *            designates the NEW instruction that created this uninitialized
663     *            value).
664     * @param nStack
665     *            the number of operand stack elements in the visited frame.
666     * @param stack
667     *            the operand stack types in this frame. This array must not be
668     *            modified. Its content has the same format as the "local"
669     *            array.
670     * @throws IllegalStateException
671     *             if a frame is visited just after another one, without any
672     *             instruction between the two (unless this frame is a
673     *             Opcodes#F_SAME frame, in which case it is silently ignored).
674     */
675    public abstract void visitFrame(final int type, final int nLocal,
676            final Object[] local, final int nStack, final Object[] stack);
677
678    /**
679     * Method instruction.
680     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsn}
681     *
682     * @param opcode
683     *            the opcode of the instruction to be visited. This opcode is
684     *            either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
685     *            ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
686     *            FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
687     *            LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
688     *            IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
689     *            SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
690     *            DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
691     *            IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
692     *            FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
693     *            IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
694     *            L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
695     *            LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
696     *            DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
697     *            or MONITOREXIT.
698     */
699    public abstract void visitInsn(final int opcode);
700
701    /**
702     * Method instruction.
703     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIntInsn}.
704     *
705     * @param opcode
706     *            the opcode of the instruction to be visited. This opcode is
707     *            either BIPUSH, SIPUSH or NEWARRAY.
708     * @param operand
709     *            the operand of the instruction to be visited.<br>
710     *            When opcode is BIPUSH, operand value should be between
711     *            Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
712     *            When opcode is SIPUSH, operand value should be between
713     *            Short.MIN_VALUE and Short.MAX_VALUE.<br>
714     *            When opcode is NEWARRAY, operand value should be one of
715     *            {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
716     *            {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
717     *            {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
718     *            {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
719     */
720    public abstract void visitIntInsn(final int opcode, final int operand);
721
722    /**
723     * Method instruction.
724     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitVarInsn}.
725     *
726     * @param opcode
727     *            the opcode of the local variable instruction to be visited.
728     *            This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
729     *            ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
730     * @param var
731     *            the operand of the instruction to be visited. This operand is
732     *            the index of a local variable.
733     */
734    public abstract void visitVarInsn(final int opcode, final int var);
735
736    /**
737     * Method instruction.
738     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeInsn}.
739     *
740    /**
741     * Visits a type instruction. A type instruction is an instruction that
742     * takes the internal name of a class as parameter.
743     *
744     * @param opcode
745     *            the opcode of the type instruction to be visited. This opcode
746     *            is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
747     * @param type
748     *            the operand of the instruction to be visited. This operand
749     *            must be the internal name of an object or array class (see
750     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
751     */
752    public abstract void visitTypeInsn(final int opcode, final String type);
753
754    /**
755     * Method instruction.
756     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFieldInsn}.
757     *
758     * @param opcode
759     *            the opcode of the type instruction to be visited. This opcode
760     *            is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
761     * @param owner
762     *            the internal name of the field's owner class (see
763     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
764     * @param name
765     *            the field's name.
766     * @param desc
767     *            the field's descriptor (see {@link jdk.internal.org.objectweb.asm.Type Type}).
768     */
769    public abstract void visitFieldInsn(final int opcode, final String owner,
770            final String name, final String desc);
771
772    /**
773     * Method instruction.
774     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn}.
775     *
776     * @param opcode
777     *            the opcode of the type instruction to be visited. This opcode
778     *            is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
779     *            INVOKEINTERFACE.
780     * @param owner
781     *            the internal name of the method's owner class (see
782     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
783     * @param name
784     *            the method's name.
785     * @param desc
786     *            the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type Type}).
787     */
788    @Deprecated
789    public void visitMethodInsn(final int opcode, final String owner,
790            final String name, final String desc) {
791        if (api >= Opcodes.ASM5) {
792            boolean itf = opcode == Opcodes.INVOKEINTERFACE;
793            visitMethodInsn(opcode, owner, name, desc, itf);
794            return;
795        }
796        throw new RuntimeException("Must be overriden");
797    }
798
799    /**
800     * Method instruction.
801     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn}.
802     *
803     * @param opcode
804     *            the opcode of the type instruction to be visited. This opcode
805     *            is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
806     *            INVOKEINTERFACE.
807     * @param owner
808     *            the internal name of the method's owner class (see
809     *            {@link jdk.internal.org.objectweb.asm.Type#getInternalName() getInternalName}).
810     * @param name
811     *            the method's name.
812     * @param desc
813     *            the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type Type}).
814     * @param itf
815     *            if the method's owner class is an interface.
816     */
817    public void visitMethodInsn(final int opcode, final String owner,
818            final String name, final String desc, final boolean itf) {
819        if (api < Opcodes.ASM5) {
820            if (itf != (opcode == Opcodes.INVOKEINTERFACE)) {
821                throw new IllegalArgumentException(
822                        "INVOKESPECIAL/STATIC on interfaces require ASM 5");
823            }
824            visitMethodInsn(opcode, owner, name, desc);
825            return;
826        }
827        throw new RuntimeException("Must be overriden");
828    }
829
830    /**
831     * Method instruction.
832     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}.
833     *
834     * Visits an invokedynamic instruction.
835     *
836     * @param name
837     *            the method's name.
838     * @param desc
839     *            the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type Type}).
840     * @param bsm
841     *            the bootstrap method.
842     * @param bsmArgs
843     *            the bootstrap method constant arguments. Each argument must be
844     *            an {@link Integer}, {@link Float}, {@link Long},
845     *            {@link Double}, {@link String}, {@link jdk.internal.org.objectweb.asm.Type} or {@link Handle}
846     *            value. This method is allowed to modify the content of the
847     *            array so a caller should expect that this array may change.
848     */
849    public abstract void visitInvokeDynamicInsn(String name, String desc,
850            Handle bsm, Object... bsmArgs);
851
852    /**
853     * Method jump instruction.
854     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitJumpInsn}.
855     *
856     * @param opcode
857     *            the opcode of the type instruction to be visited. This opcode
858     *            is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
859     *            IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
860     *            IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
861     * @param label
862     *            the operand of the instruction to be visited. This operand is
863     *            a label that designates the instruction to which the jump
864     *            instruction may jump.
865     */
866    public abstract void visitJumpInsn(final int opcode, final Label label);
867
868    /**
869     * Method label.
870     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLabel}.
871     *
872     * @param label
873     *            a {@link Label Label} object.
874     */
875    public abstract void visitLabel(final Label label);
876
877    /**
878     * Method instruction.
879     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLdcInsn}.
880     *
881     * Visits a LDC instruction. Note that new constant types may be added in
882     * future versions of the Java Virtual Machine. To easily detect new
883     * constant types, implementations of this method should check for
884     * unexpected constant types, like this:
885     *
886     * <pre>
887     * if (cst instanceof Integer) {
888     *     // ...
889     * } else if (cst instanceof Float) {
890     *     // ...
891     * } else if (cst instanceof Long) {
892     *     // ...
893     * } else if (cst instanceof Double) {
894     *     // ...
895     * } else if (cst instanceof String) {
896     *     // ...
897     * } else if (cst instanceof Type) {
898     *     int sort = ((Type) cst).getSort();
899     *     if (sort == Type.OBJECT) {
900     *         // ...
901     *     } else if (sort == Type.ARRAY) {
902     *         // ...
903     *     } else if (sort == Type.METHOD) {
904     *         // ...
905     *     } else {
906     *         // throw an exception
907     *     }
908     * } else if (cst instanceof Handle) {
909     *     // ...
910     * } else {
911     *     // throw an exception
912     * }
913     * </pre>
914     *
915     * @param cst
916     *            the constant to be loaded on the stack. This parameter must be
917     *            a non null {@link Integer}, a {@link Float}, a {@link Long}, a
918     *            {@link Double}, a {@link String}, a {@link jdk.internal.org.objectweb.asm.Type}
919     *            of OBJECT or ARRAY sort for <tt>.class</tt> constants, for classes whose
920     *            version is 49.0, a {@link jdk.internal.org.objectweb.asm.Type} of METHOD sort or a
921     *            {@link Handle} for MethodType and MethodHandle constants, for
922     *            classes whose version is 51.0.
923     */
924    public abstract void visitLdcInsn(final Object cst);
925
926    /**
927     * Method instruction.
928     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIincInsn}.
929     *
930     * @param var
931     *            index of the local variable to be incremented.
932     * @param increment
933     *            amount to increment the local variable by.
934     */
935    public abstract void visitIincInsn(final int var, final int increment);
936
937    /**
938     * Method instruction.
939     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTableSwitchInsn}.
940     *
941     * @param min
942     *            the minimum key value.
943     * @param max
944     *            the maximum key value.
945     * @param dflt
946     *            beginning of the default handler block.
947     * @param labels
948     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
949     *            beginning of the handler block for the <tt>min + i</tt> key.
950     */
951    public abstract void visitTableSwitchInsn(final int min, final int max,
952            final Label dflt, final Label... labels);
953
954    /**
955     * Method instruction.
956     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn}.
957     *
958     * @param dflt
959     *            beginning of the default handler block.
960     * @param keys
961     *            the values of the keys.
962     * @param labels
963     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
964     *            beginning of the handler block for the <tt>keys[i]</tt> key.
965     */
966    public abstract void visitLookupSwitchInsn(final Label dflt,
967            final int[] keys, final Label[] labels);
968
969    /**
970     * Method instruction.
971     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}.
972     *
973     * @param desc
974     *            an array type descriptor (see {@link jdk.internal.org.objectweb.asm.Type Type}).
975     * @param dims
976     *            number of dimensions of the array to allocate.
977     */
978    public abstract void visitMultiANewArrayInsn(final String desc,
979            final int dims);
980
981    /**
982     * Instruction type annotation.
983     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsnAnnotation}.
984     *
985     * @param typeRef
986     *            a reference to the annotated type. The sort of this type
987     *            reference must be {@link jdk.internal.org.objectweb.asm.TypeReference#INSTANCEOF INSTANCEOF},
988     *            {@link jdk.internal.org.objectweb.asm.TypeReference#NEW NEW},
989     *            {@link jdk.internal.org.objectweb.asm.TypeReference#CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
990     *            {@link jdk.internal.org.objectweb.asm.TypeReference#METHOD_REFERENCE METHOD_REFERENCE},
991     *            {@link jdk.internal.org.objectweb.asm.TypeReference#CAST CAST},
992     *            {@link jdk.internal.org.objectweb.asm.TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
993     *            {@link jdk.internal.org.objectweb.asm.TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
994     *            {@link jdk.internal.org.objectweb.asm.TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT},
995     *            or {@link jdk.internal.org.objectweb.asm.TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}.
996     *            See {@link jdk.internal.org.objectweb.asm.TypeReference}.
997     * @param typePath
998     *            the path to the annotated type argument, wildcard bound, array
999     *            element type, or static inner type within 'typeRef'. May be
1000     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
1001     * @param desc
1002     *            the class descriptor of the annotation class.
1003     * @param visible
1004     *            <tt>true</tt> if the annotation is visible at runtime.
1005     * @return the printer
1006     */
1007    public Printer visitInsnAnnotation(final int typeRef,
1008            final TypePath typePath, final String desc, final boolean visible) {
1009        throw new RuntimeException("Must be overriden");
1010    }
1011
1012    /**
1013     * Method exception handler.
1014     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchBlock}.
1015     *
1016     * @param start
1017     *            beginning of the exception handler's scope (inclusive).
1018     * @param end
1019     *            end of the exception handler's scope (exclusive).
1020     * @param handler
1021     *            beginning of the exception handler's code.
1022     * @param type
1023     *            internal name of the type of exceptions handled by the
1024     *            handler, or <tt>null</tt> to catch any exceptions (for
1025     *            "finally" blocks).
1026     * @throws IllegalArgumentException
1027     *             if one of the labels has already been visited by this visitor
1028     *             (by the {@link #visitLabel visitLabel} method).
1029     */
1030    public abstract void visitTryCatchBlock(final Label start, final Label end,
1031            final Label handler, final String type);
1032
1033    /**
1034     * Try catch block type annotation.
1035     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
1036     *
1037     * @param typeRef
1038     *            a reference to the annotated type. The sort of this type
1039     *            reference must be {@link jdk.internal.org.objectweb.asm.TypeReference#EXCEPTION_PARAMETER
1040     *            EXCEPTION_PARAMETER}.
1041     *            See {@link jdk.internal.org.objectweb.asm.TypeReference}.
1042     * @param typePath
1043     *            the path to the annotated type argument, wildcard bound, array
1044     *            element type, or static inner type within 'typeRef'. May be
1045     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
1046     * @param desc
1047     *            the class descriptor of the annotation class.
1048     * @param visible
1049     *            <tt>true</tt> if the annotation is visible at runtime.
1050     * @return the printer
1051     */
1052    public Printer visitTryCatchAnnotation(final int typeRef,
1053            final TypePath typePath, final String desc, final boolean visible) {
1054        throw new RuntimeException("Must be overriden");
1055    }
1056
1057    /**
1058     * Method debug info.
1059     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLocalVariable}.
1060     *
1061     * @param name
1062     *            the name of a local variable.
1063     * @param desc
1064     *            the type descriptor of this local variable.
1065     * @param signature
1066     *            the type signature of this local variable. May be
1067     *            <tt>null</tt> if the local variable type does not use generic
1068     *            types.
1069     * @param start
1070     *            the first instruction corresponding to the scope of this local
1071     *            variable (inclusive).
1072     * @param end
1073     *            the last instruction corresponding to the scope of this local
1074     *            variable (exclusive).
1075     * @param index
1076     *            the local variable's index.
1077     * @throws IllegalArgumentException
1078     *             if one of the labels has not already been visited by this
1079     *             visitor (by the {@link #visitLabel visitLabel} method).
1080     */
1081    public abstract void visitLocalVariable(final String name,
1082            final String desc, final String signature, final Label start,
1083            final Label end, final int index);
1084
1085    /**
1086     * Local variable type annotation.
1087     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}.
1088     *
1089     * @param typeRef
1090     *            a reference to the annotated type. The sort of this type
1091     *            reference must be {@link jdk.internal.org.objectweb.asm.TypeReference#LOCAL_VARIABLE
1092     *            LOCAL_VARIABLE} or {@link jdk.internal.org.objectweb.asm.TypeReference#RESOURCE_VARIABLE
1093     *            RESOURCE_VARIABLE}.
1094     *            See {@link jdk.internal.org.objectweb.asm.TypeReference}.
1095     * @param typePath
1096     *            the path to the annotated type argument, wildcard bound, array
1097     *            element type, or static inner type within 'typeRef'. May be
1098     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
1099     * @param start
1100     *            the fist instructions corresponding to the continuous ranges
1101     *            that make the scope of this local variable (inclusive).
1102     * @param end
1103     *            the last instructions corresponding to the continuous ranges
1104     *            that make the scope of this local variable (exclusive). This
1105     *            array must have the same size as the 'start' array.
1106     * @param index
1107     *            the local variable's index in each range. This array must have
1108     *            the same size as the 'start' array.
1109     * @param desc
1110     *            the class descriptor of the annotation class.
1111     * @param visible
1112     *            <tt>true</tt> if the annotation is visible at runtime.
1113     * @return the printer
1114     */
1115    public Printer visitLocalVariableAnnotation(final int typeRef,
1116            final TypePath typePath, final Label[] start, final Label[] end,
1117            final int[] index, final String desc, final boolean visible) {
1118        throw new RuntimeException("Must be overriden");
1119    }
1120
1121    /**
1122     * Method debug info.
1123     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLineNumber}.
1124     *
1125     * @param line
1126     *            a line number. This number refers to the source file from
1127     *            which the class was compiled.
1128     * @param start
1129     *            the first instruction corresponding to this line number.
1130     * @throws IllegalArgumentException
1131     *             if <tt>start</tt> has not already been visited by this
1132     *             visitor (by the {@link #visitLabel visitLabel} method).
1133     */
1134    public abstract void visitLineNumber(final int line, final Label start);
1135
1136    /**
1137     * Method max stack and max locals.
1138     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMaxs}.
1139     *
1140     * @param maxStack
1141     *            maximum stack size of the method.
1142     * @param maxLocals
1143     *            maximum number of local variables for the method.
1144     */
1145    public abstract void visitMaxs(final int maxStack, final int maxLocals);
1146
1147    /**
1148     * Method end.
1149     * See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitEnd}.
1150     */
1151    public abstract void visitMethodEnd();
1152
1153    /**
1154     * Returns the text constructed by this visitor.
1155     *
1156     * @return the text constructed by this visitor.
1157     */
1158    public List<Object> getText() {
1159        return text;
1160    }
1161
1162    /**
1163     * Prints the text constructed by this visitor.
1164     *
1165     * @param pw
1166     *            the print writer to be used.
1167     */
1168    public void print(final PrintWriter pw) {
1169        printList(pw, text);
1170    }
1171
1172    /**
1173     * Appends a quoted string to a given buffer.
1174     *
1175     * @param buf
1176     *            the buffer where the string must be added.
1177     * @param s
1178     *            the string to be added.
1179     */
1180    public static void appendString(final StringBuffer buf, final String s) {
1181        buf.append('\"');
1182        for (int i = 0; i < s.length(); ++i) {
1183            char c = s.charAt(i);
1184            if (c == '\n') {
1185                buf.append("\\n");
1186            } else if (c == '\r') {
1187                buf.append("\\r");
1188            } else if (c == '\\') {
1189                buf.append("\\\\");
1190            } else if (c == '"') {
1191                buf.append("\\\"");
1192            } else if (c < 0x20 || c > 0x7f) {
1193                buf.append("\\u");
1194                if (c < 0x10) {
1195                    buf.append("000");
1196                } else if (c < 0x100) {
1197                    buf.append("00");
1198                } else if (c < 0x1000) {
1199                    buf.append('0');
1200                }
1201                buf.append(Integer.toString(c, 16));
1202            } else {
1203                buf.append(c);
1204            }
1205        }
1206        buf.append('\"');
1207    }
1208
1209    /**
1210     * Prints the given string tree.
1211     *
1212     * @param pw
1213     *            the writer to be used to print the tree.
1214     * @param l
1215     *            a string tree, i.e., a string list that can contain other
1216     *            string lists, and so on recursively.
1217     */
1218    static void printList(final PrintWriter pw, final List<?> l) {
1219        for (int i = 0; i < l.size(); ++i) {
1220            Object o = l.get(i);
1221            if (o instanceof List) {
1222                printList(pw, (List<?>) o);
1223            } else {
1224                pw.print(o.toString());
1225            }
1226        }
1227    }
1228}
1229