1f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// Copyright 2017 The Bazel Authors. All rights reserved. 2f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// 3f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// Licensed under the Apache License, Version 2.0 (the "License"); 4f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// you may not use this file except in compliance with the License. 5f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// You may obtain a copy of the License at 6f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// 7f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// http://www.apache.org/licenses/LICENSE-2.0 8f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// 9f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// Unless required by applicable law or agreed to in writing, software 10f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// distributed under the License is distributed on an "AS IS" BASIS, 11f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// See the License for the specific language governing permissions and 13f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun// limitations under the License. 14f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunpackage com.google.devtools.build.android.desugar; 15f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 16f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport com.google.common.base.Preconditions; 17f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport com.google.common.collect.ImmutableList; 18f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport java.io.IOException; 19f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport java.io.InputStream; 20f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport java.io.PrintWriter; 21f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport java.nio.file.Files; 22f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport java.nio.file.Path; 230156e0d255709355b1e8f5303bd8256ab6967b0aColin Crossimport java.util.Comparator; 24f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport java.util.zip.ZipEntry; 25f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport java.util.zip.ZipFile; 26f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport org.objectweb.asm.ClassReader; 27f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport org.objectweb.asm.ClassVisitor; 28f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport org.objectweb.asm.Handle; 29f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport org.objectweb.asm.Label; 30f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport org.objectweb.asm.MethodVisitor; 31f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport org.objectweb.asm.Opcodes; 32f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunimport org.objectweb.asm.util.Textifier; 33f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 34f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun/** Print the types of the operand stack for each method. */ 35f0971e886d2142be6219bb4a0ffa03f26b02f110cnsunpublic class ByteCodeTypePrinter { 36f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 37f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public static void printClassesWithTypes(Path inputJarFile, PrintWriter printWriter) 38f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun throws IOException { 39f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun Preconditions.checkState( 40f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun Files.exists(inputJarFile), "The input jar file %s does not exist.", inputJarFile); 41f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun try (ZipFile jarFile = new ZipFile(inputJarFile.toFile())) { 42f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun for (ZipEntry entry : getSortedClassEntriess(jarFile)) { 43f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun try (InputStream classStream = jarFile.getInputStream(entry)) { 44f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printWriter.println("\nClass: " + entry.getName()); 45f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun ClassReader classReader = new ClassReader(classStream); 46f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun ClassVisitor visitor = new ClassWithTypeDumper(printWriter); 47f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun classReader.accept(visitor, 0); 48f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 49f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printWriter.println("\n"); 50f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 51f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 52f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 53f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 54f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private static ImmutableList<ZipEntry> getSortedClassEntriess(ZipFile jar) { 55f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun return jar.stream() 56f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun .filter(entry -> entry.getName().endsWith(".class")) 570156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross .sorted(Comparator.comparing(ZipEntry::getName)) 58f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun .collect(ImmutableList.toImmutableList()); 59f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 60f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 61f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private static class ClassWithTypeDumper extends ClassVisitor { 62f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 63f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private String internalName; 64f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private final PrintWriter printWriter; 65f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 66f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public ClassWithTypeDumper(PrintWriter printWriter) { 67f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super(Opcodes.ASM5); 68f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun this.printWriter = printWriter; 69f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 70f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 71f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 72f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visit( 73f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun int version, 74f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun int access, 75f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun String name, 76f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun String signature, 77f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun String superName, 78f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun String[] interfaces) { 79f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun internalName = name; 80f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visit(version, access, name, signature, superName, interfaces); 81f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 82f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 83f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 84f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public MethodVisitor visitMethod( 85f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun int access, String name, String desc, String signature, String[] exceptions) { 86f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printWriter.println("Method " + name); 87f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 88f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun BytecodeTypeInference inference = new BytecodeTypeInference(access, internalName, name, desc); 89f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun mv = new MethodIrTypeDumper(mv, inference, printWriter); 90f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun inference.setDelegateMethodVisitor(mv); 91f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun // Let the type inference runs first. 92f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun return inference; 93f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 94f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 95f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 96f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private static final class TextifierExt extends Textifier { 97f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 98f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public TextifierExt() { 99f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super(Opcodes.ASM5); 100f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 101f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 102f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void print(String string) { 103f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun text.add(tab2 + string); 104f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 105f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 106f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 107f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private static class MethodIrTypeDumper extends MethodVisitor { 108f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 109f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private final BytecodeTypeInference inference; 110f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private final TextifierExt printer = new TextifierExt(); 111f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun private final PrintWriter printWriter; 112f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 113f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public MethodIrTypeDumper( 114f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun MethodVisitor visitor, BytecodeTypeInference inference, PrintWriter printWriter) { 115f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super(Opcodes.ASM5, visitor); 116f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun this.inference = inference; 117f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun this.printWriter = printWriter; 118f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 119f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 1200156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross private void printTypeOfOperandStack() { 121f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.print(" |__STACK: " + inference.getOperandStackAsString() + "\n"); 1220156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printer.print(" |__LOCAL: " + inference.getLocalsAsString() + "\n"); 123f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 124f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 125f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 126f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitIntInsn(int opcode, int operand) { 127f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitIntInsn(opcode, operand); 1280156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 129f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitIntInsn(opcode, operand); 130f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 131f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 132f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 133f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitInsn(int opcode) { 134f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitInsn(opcode); 1350156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 136f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitInsn(opcode); 137f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 138f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 139f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 140f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitMultiANewArrayInsn(String desc, int dims) { 141f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitMultiANewArrayInsn(desc, dims); 1420156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 143f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitMultiANewArrayInsn(desc, dims); 144f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 145f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 146f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 147f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 148f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitLookupSwitchInsn(dflt, keys, labels); 1490156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 150f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitLookupSwitchInsn(dflt, keys, labels); 151f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 152f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 153f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 154f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { 155f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitTableSwitchInsn(min, max, dflt, labels); 1560156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 157f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitTableSwitchInsn(min, max, dflt, labels); 158f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 159f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 160f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 161f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitIincInsn(int var, int increment) { 162f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitIincInsn(var, increment); 1630156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 164f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitIincInsn(var, increment); 165f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 166f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 167f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 168f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitLdcInsn(Object cst) { 169f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitLdcInsn(cst); 1700156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 171f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitLdcInsn(cst); 172f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 173f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 174f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 175f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitJumpInsn(int opcode, Label label) { 176f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitJumpInsn(opcode, label); 1770156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 178f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitJumpInsn(opcode, label); 179f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 180f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 181f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 182f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { 183f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); 1840156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 185f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); 186f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 187f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 188f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 189f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { 190f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitMethodInsn(opcode, owner, name, desc, itf); 1910156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 192f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitMethodInsn(opcode, owner, name, desc, itf); 193f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 194f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 195f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 196f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitMethodInsn(int opcode, String owner, String name, String desc) { 197f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitMethodInsn(opcode, owner, name, desc); 1980156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 199f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitMethodInsn(opcode, owner, name, desc); 200f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 201f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 202f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 203f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitFieldInsn(int opcode, String owner, String name, String desc) { 204f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitFieldInsn(opcode, owner, name, desc); 2050156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 206f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitFieldInsn(opcode, owner, name, desc); 207f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 208f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 209f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 210f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitTypeInsn(int opcode, String type) { 211f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitTypeInsn(opcode, type); 2120156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 213f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitTypeInsn(opcode, type); 214f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 215f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 216f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 217f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitVarInsn(int opcode, int var) { 218f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitVarInsn(opcode, var); 2190156e0d255709355b1e8f5303bd8256ab6967b0aColin Cross printTypeOfOperandStack(); 220f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitVarInsn(opcode, var); 221f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 222f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 223f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 224f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { 225f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitFrame(type, nLocal, local, nStack, stack); 226f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitFrame(type, nLocal, local, nStack, stack); 227f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 228f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 229f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 230f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitLabel(Label label) { 231f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.visitLabel(label); 232f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitLabel(label); 233f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 234f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun 235f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun @Override 236f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun public void visitEnd() { 237f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printer.print(printWriter); 238f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun printWriter.flush(); 239f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun super.visitEnd(); 240f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 241f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun } 242f0971e886d2142be6219bb4a0ffa03f26b02f110cnsun} 243