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 */ Printer(final int api)175 protected Printer(final int api) { 176 this.api = api; 177 this.buf = new StringBuffer(); 178 this.text = new ArrayList<Object>(); 179 } 180 181 /** 182 * Class header. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visit}. 183 */ visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)184 public abstract void visit(final int version, final int access, 185 final String name, final String signature, final String superName, 186 final String[] interfaces); 187 188 /** 189 * Class source. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitSource}. 190 */ visitSource(final String file, final String debug)191 public abstract void visitSource(final String file, final String debug); 192 193 /** 194 * Class outer class. See 195 * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}. 196 */ visitOuterClass(final String owner, final String name, final String desc)197 public abstract void visitOuterClass(final String owner, final String name, 198 final String desc); 199 200 /** 201 * Class annotation. See 202 * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAnnotation}. 203 */ visitClassAnnotation(final String desc, final boolean visible)204 public abstract Printer visitClassAnnotation(final String desc, 205 final boolean visible); 206 207 /** 208 * Class type annotation. See 209 * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitTypeAnnotation}. 210 */ visitClassTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible)211 public Printer visitClassTypeAnnotation(final int typeRef, 212 final TypePath typePath, final String desc, final boolean visible) { 213 throw new RuntimeException("Must be overriden"); 214 } 215 216 /** 217 * Class attribute. See 218 * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitAttribute}. 219 */ visitClassAttribute(final Attribute attr)220 public abstract void visitClassAttribute(final Attribute attr); 221 222 /** 223 * Class inner name. See 224 * {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitInnerClass}. 225 */ visitInnerClass(final String name, final String outerName, final String innerName, final int access)226 public abstract void visitInnerClass(final String name, 227 final String outerName, final String innerName, final int access); 228 229 /** 230 * Class field. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitField}. 231 */ visitField(final int access, final String name, final String desc, final String signature, final Object value)232 public abstract Printer visitField(final int access, final String name, 233 final String desc, final String signature, final Object value); 234 235 /** 236 * Class method. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitMethod}. 237 */ visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)238 public abstract Printer visitMethod(final int access, final String name, 239 final String desc, final String signature, final String[] exceptions); 240 241 /** 242 * Class end. See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitEnd}. 243 */ visitClassEnd()244 public abstract void visitClassEnd(); 245 246 // ------------------------------------------------------------------------ 247 // Annotations 248 // ------------------------------------------------------------------------ 249 250 /** 251 * Annotation value. See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visit}. 252 */ visit(final String name, final Object value)253 public abstract void visit(final String name, final Object value); 254 255 /** 256 * Annotation enum value. See 257 * {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnum}. 258 */ visitEnum(final String name, final String desc, final String value)259 public abstract void visitEnum(final String name, final String desc, 260 final String value); 261 262 /** 263 * Nested annotation value. See 264 * {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitAnnotation}. 265 */ visitAnnotation(final String name, final String desc)266 public abstract Printer visitAnnotation(final String name, final String desc); 267 268 /** 269 * Annotation array value. See 270 * {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitArray}. 271 */ visitArray(final String name)272 public abstract Printer visitArray(final String name); 273 274 /** 275 * Annotation end. See {@link jdk.internal.org.objectweb.asm.AnnotationVisitor#visitEnd}. 276 */ visitAnnotationEnd()277 public abstract void visitAnnotationEnd(); 278 279 // ------------------------------------------------------------------------ 280 // Fields 281 // ------------------------------------------------------------------------ 282 283 /** 284 * Field annotation. See 285 * {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAnnotation}. 286 */ visitFieldAnnotation(final String desc, final boolean visible)287 public abstract Printer visitFieldAnnotation(final String desc, 288 final boolean visible); 289 290 /** 291 * Field type annotation. See 292 * {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitTypeAnnotation}. 293 */ visitFieldTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible)294 public Printer visitFieldTypeAnnotation(final int typeRef, 295 final TypePath typePath, final String desc, final boolean visible) { 296 throw new RuntimeException("Must be overriden"); 297 } 298 299 /** 300 * Field attribute. See 301 * {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitAttribute}. 302 */ visitFieldAttribute(final Attribute attr)303 public abstract void visitFieldAttribute(final Attribute attr); 304 305 /** 306 * Field end. See {@link jdk.internal.org.objectweb.asm.FieldVisitor#visitEnd}. 307 */ visitFieldEnd()308 public abstract void visitFieldEnd(); 309 310 // ------------------------------------------------------------------------ 311 // Methods 312 // ------------------------------------------------------------------------ 313 314 /** 315 * Method parameter. See 316 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitParameter(String, int)}. 317 */ visitParameter(String name, int access)318 public void visitParameter(String name, int access) { 319 throw new RuntimeException("Must be overriden"); 320 } 321 322 /** 323 * Method default annotation. See 324 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotationDefault}. 325 */ visitAnnotationDefault()326 public abstract Printer visitAnnotationDefault(); 327 328 /** 329 * Method annotation. See 330 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAnnotation}. 331 */ visitMethodAnnotation(final String desc, final boolean visible)332 public abstract Printer visitMethodAnnotation(final String desc, 333 final boolean visible); 334 335 /** 336 * Method type annotation. See 337 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeAnnotation}. 338 */ visitMethodTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible)339 public Printer visitMethodTypeAnnotation(final int typeRef, 340 final TypePath typePath, final String desc, final boolean visible) { 341 throw new RuntimeException("Must be overriden"); 342 } 343 344 /** 345 * Method parameter annotation. See 346 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitParameterAnnotation}. 347 */ visitParameterAnnotation(final int parameter, final String desc, final boolean visible)348 public abstract Printer visitParameterAnnotation(final int parameter, 349 final String desc, final boolean visible); 350 351 /** 352 * Method attribute. See 353 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitAttribute}. 354 */ visitMethodAttribute(final Attribute attr)355 public abstract void visitMethodAttribute(final Attribute attr); 356 357 /** 358 * Method start. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitCode}. 359 */ visitCode()360 public abstract void visitCode(); 361 362 /** 363 * Method stack frame. See 364 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFrame}. 365 */ visitFrame(final int type, final int nLocal, final Object[] local, final int nStack, final Object[] stack)366 public abstract void visitFrame(final int type, final int nLocal, 367 final Object[] local, final int nStack, final Object[] stack); 368 369 /** 370 * Method instruction. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsn} 371 * . 372 */ visitInsn(final int opcode)373 public abstract void visitInsn(final int opcode); 374 375 /** 376 * Method instruction. See 377 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIntInsn}. 378 */ visitIntInsn(final int opcode, final int operand)379 public abstract void visitIntInsn(final int opcode, final int operand); 380 381 /** 382 * Method instruction. See 383 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitVarInsn}. 384 */ visitVarInsn(final int opcode, final int var)385 public abstract void visitVarInsn(final int opcode, final int var); 386 387 /** 388 * Method instruction. See 389 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTypeInsn}. 390 */ visitTypeInsn(final int opcode, final String type)391 public abstract void visitTypeInsn(final int opcode, final String type); 392 393 /** 394 * Method instruction. See 395 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitFieldInsn}. 396 */ visitFieldInsn(final int opcode, final String owner, final String name, final String desc)397 public abstract void visitFieldInsn(final int opcode, final String owner, 398 final String name, final String desc); 399 400 /** 401 * Method instruction. See 402 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn}. 403 */ 404 @Deprecated visitMethodInsn(final int opcode, final String owner, final String name, final String desc)405 public void visitMethodInsn(final int opcode, final String owner, 406 final String name, final String desc) { 407 if (api >= Opcodes.ASM5) { 408 boolean itf = opcode == Opcodes.INVOKEINTERFACE; 409 visitMethodInsn(opcode, owner, name, desc, itf); 410 return; 411 } 412 throw new RuntimeException("Must be overriden"); 413 } 414 415 /** 416 * Method instruction. See 417 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn}. 418 */ visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf)419 public void visitMethodInsn(final int opcode, final String owner, 420 final String name, final String desc, final boolean itf) { 421 if (api < Opcodes.ASM5) { 422 if (itf != (opcode == Opcodes.INVOKEINTERFACE)) { 423 throw new IllegalArgumentException( 424 "INVOKESPECIAL/STATIC on interfaces require ASM 5"); 425 } 426 visitMethodInsn(opcode, owner, name, desc); 427 return; 428 } 429 throw new RuntimeException("Must be overriden"); 430 } 431 432 /** 433 * Method instruction. See 434 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}. 435 */ visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs)436 public abstract void visitInvokeDynamicInsn(String name, String desc, 437 Handle bsm, Object... bsmArgs); 438 439 /** 440 * Method instruction. See 441 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitJumpInsn}. 442 */ visitJumpInsn(final int opcode, final Label label)443 public abstract void visitJumpInsn(final int opcode, final Label label); 444 445 /** 446 * Method label. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLabel}. 447 */ visitLabel(final Label label)448 public abstract void visitLabel(final Label label); 449 450 /** 451 * Method instruction. See 452 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLdcInsn}. 453 */ visitLdcInsn(final Object cst)454 public abstract void visitLdcInsn(final Object cst); 455 456 /** 457 * Method instruction. See 458 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitIincInsn}. 459 */ visitIincInsn(final int var, final int increment)460 public abstract void visitIincInsn(final int var, final int increment); 461 462 /** 463 * Method instruction. See 464 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTableSwitchInsn}. 465 */ visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels)466 public abstract void visitTableSwitchInsn(final int min, final int max, 467 final Label dflt, final Label... labels); 468 469 /** 470 * Method instruction. See 471 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn}. 472 */ visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels)473 public abstract void visitLookupSwitchInsn(final Label dflt, 474 final int[] keys, final Label[] labels); 475 476 /** 477 * Method instruction. See 478 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}. 479 */ visitMultiANewArrayInsn(final String desc, final int dims)480 public abstract void visitMultiANewArrayInsn(final String desc, 481 final int dims); 482 483 /** 484 * Instruction type annotation. See 485 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInsnAnnotation}. 486 */ visitInsnAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible)487 public Printer visitInsnAnnotation(final int typeRef, 488 final TypePath typePath, final String desc, final boolean visible) { 489 throw new RuntimeException("Must be overriden"); 490 } 491 492 /** 493 * Method exception handler. See 494 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchBlock}. 495 */ visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type)496 public abstract void visitTryCatchBlock(final Label start, final Label end, 497 final Label handler, final String type); 498 499 /** 500 * Try catch block type annotation. See 501 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}. 502 */ visitTryCatchAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible)503 public Printer visitTryCatchAnnotation(final int typeRef, 504 final TypePath typePath, final String desc, final boolean visible) { 505 throw new RuntimeException("Must be overriden"); 506 } 507 508 /** 509 * Method debug info. See 510 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLocalVariable}. 511 */ visitLocalVariable(final String name, final String desc, final String signature, final Label start, final Label end, final int index)512 public abstract void visitLocalVariable(final String name, 513 final String desc, final String signature, final Label start, 514 final Label end, final int index); 515 516 /** 517 * Local variable type annotation. See 518 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitTryCatchAnnotation}. 519 */ visitLocalVariableAnnotation(final int typeRef, final TypePath typePath, final Label[] start, final Label[] end, final int[] index, final String desc, final boolean visible)520 public Printer visitLocalVariableAnnotation(final int typeRef, 521 final TypePath typePath, final Label[] start, final Label[] end, 522 final int[] index, final String desc, final boolean visible) { 523 throw new RuntimeException("Must be overriden"); 524 } 525 526 /** 527 * Method debug info. See 528 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitLineNumber}. 529 */ visitLineNumber(final int line, final Label start)530 public abstract void visitLineNumber(final int line, final Label start); 531 532 /** 533 * Method max stack and max locals. See 534 * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMaxs}. 535 */ visitMaxs(final int maxStack, final int maxLocals)536 public abstract void visitMaxs(final int maxStack, final int maxLocals); 537 538 /** 539 * Method end. See {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitEnd}. 540 */ visitMethodEnd()541 public abstract void visitMethodEnd(); 542 543 /** 544 * Returns the text constructed by this visitor. 545 * 546 * @return the text constructed by this visitor. 547 */ getText()548 public List<Object> getText() { 549 return text; 550 } 551 552 /** 553 * Prints the text constructed by this visitor. 554 * 555 * @param pw 556 * the print writer to be used. 557 */ print(final PrintWriter pw)558 public void print(final PrintWriter pw) { 559 printList(pw, text); 560 } 561 562 /** 563 * Appends a quoted string to a given buffer. 564 * 565 * @param buf 566 * the buffer where the string must be added. 567 * @param s 568 * the string to be added. 569 */ appendString(final StringBuffer buf, final String s)570 public static void appendString(final StringBuffer buf, final String s) { 571 buf.append('\"'); 572 for (int i = 0; i < s.length(); ++i) { 573 char c = s.charAt(i); 574 if (c == '\n') { 575 buf.append("\\n"); 576 } else if (c == '\r') { 577 buf.append("\\r"); 578 } else if (c == '\\') { 579 buf.append("\\\\"); 580 } else if (c == '"') { 581 buf.append("\\\""); 582 } else if (c < 0x20 || c > 0x7f) { 583 buf.append("\\u"); 584 if (c < 0x10) { 585 buf.append("000"); 586 } else if (c < 0x100) { 587 buf.append("00"); 588 } else if (c < 0x1000) { 589 buf.append('0'); 590 } 591 buf.append(Integer.toString(c, 16)); 592 } else { 593 buf.append(c); 594 } 595 } 596 buf.append('\"'); 597 } 598 599 /** 600 * Prints the given string tree. 601 * 602 * @param pw 603 * the writer to be used to print the tree. 604 * @param l 605 * a string tree, i.e., a string list that can contain other 606 * string lists, and so on recursively. 607 */ printList(final PrintWriter pw, final List<?> l)608 static void printList(final PrintWriter pw, final List<?> l) { 609 for (int i = 0; i < l.size(); ++i) { 610 Object o = l.get(i); 611 if (o instanceof List) { 612 printList(pw, (List<?>) o); 613 } else { 614 pw.print(o.toString()); 615 } 616 } 617 } 618 } 619