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.PrintWriter;
  62 import java.util.ArrayList;
  63 import java.util.List;
  64 
  65 import jdk.internal.org.objectweb.asm.Attribute;
  66 import jdk.internal.org.objectweb.asm.Handle;
  67 import jdk.internal.org.objectweb.asm.Label;
  68 import jdk.internal.org.objectweb.asm.Opcodes;
  69 import jdk.internal.org.objectweb.asm.TypePath;
  70 
  71 /**
  72  * An abstract converter from visit events to text.
  73  *
  74  * @author Eric Bruneton
  75  */
  76 public 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 }