/** * Constructs a new {@link GaTraceClassVisitor}. * * @param pw the print writer to be used to print the class. */ public GaTraceClassVisitor(final PrintWriter pw) { super(Opcodes.ASM5, null); this.pw = pw; this.p = new Textifier(); }
@Override public Printer visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { buf.setLength(0); buf.append(tab2).append("TRYCATCHBLOCK @"); appendDescriptor(FIELD_DESCRIPTOR, desc); buf.append('('); text.add(buf.toString()); Textifier t = createTextifier(); text.add(t.getText()); buf.setLength(0); buf.append(") : "); appendTypeReference(typeRef); buf.append(", ").append(typePath); buf.append(visible ? "\n" : " // invisible\n"); text.add(buf.toString()); return t; }
/** * Prints a disassembled view of the given class to the standard output. * * <p>Usage: Textifier [-debug] <binary class name or class file name > * * @param args the command line arguments. * @throws IOException if the class cannot be found, or if an IOException occurs. */ public static void main(final String[] args) throws IOException { String usage = "Prints a disassembled view of the given class.\n" + "Usage: Textifier [-debug] <fully qualified class name or class file name>"; main(usage, new Textifier(), args); }
appendRawAccess(access); if (signature != null) { stringBuilder.append(tab); appendDescriptor(FIELD_SIGNATURE, signature); stringBuilder.append(tab); appendJavaDeclaration(name, signature); appendAccess(access); appendDescriptor(FIELD_DESCRIPTOR, descriptor); stringBuilder.append(' ').append(name); if (value != null) { return addNewTextifier(null);
@Override public void visitEnd() { try { accept(inner); super.visitEnd(); } catch(Exception e){ Textifier t = new Textifier(); accept(new TraceMethodVisitor(t)); StringBuilderWriter sw = new StringBuilderWriter(); PrintWriter pw = new PrintWriter(sw); t.print(pw); pw.flush(); String bytecode = sw.getBuilder().toString(); logger.error(String.format("Failure while rendering method %s, %s, %s. ByteCode:\n %s", name, desc, signature, bytecode), e); throw new RuntimeException(String.format("Failure while rendering method %s, %s, %s. ByteCode:\n %s", name, desc, signature, bytecode), e); } } }
if (signature != null) { buf.append(tab); appendDescriptor(FIELD_SIGNATURE, signature); appendAccess(access); appendDescriptor(FIELD_DESCRIPTOR, desc); buf.append(' ').append(name); if (value != null) { text.add(buf.toString()); Textifier t = createTextifier(); text.add(t.getText()); return t;
@Override public Textifier visitAnnotation(final String name, final String desc) { buf.setLength(0); appendComa(valueNumber++); if (name != null) { buf.append(name).append('='); } buf.append('@'); appendDescriptor(FIELD_DESCRIPTOR, desc); buf.append('('); text.add(buf.toString()); Textifier t = createTextifier(); text.add(t.getText()); text.add(")"); return t; }
@Override public void visitProvide(final String provide, final String... providers) { stringBuilder.setLength(0); stringBuilder.append(tab).append("provides "); appendDescriptor(INTERNAL_NAME, provide); stringBuilder.append(" with\n"); for (int i = 0; i < providers.length; ++i) { stringBuilder.append(tab2); appendDescriptor(INTERNAL_NAME, providers[i]); stringBuilder.append(i != providers.length - 1 ? ",\n" : ";\n"); } text.add(stringBuilder.toString()); }
@Override public Textifier visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { buf.setLength(0); buf.append(tab2).append('@'); appendDescriptor(FIELD_DESCRIPTOR, desc); buf.append('('); text.add(buf.toString()); Textifier t = createTextifier(); text.add(t.getText()); text.add(visible ? ") // parameter " : ") // invisible, parameter "); text.add(parameter); text.add("\n"); return t; }
@Override public Textifier visitAnnotationDefault() { text.add(tab2 + "default="); Textifier t = createTextifier(); text.add(t.getText()); text.add("\n"); return t; }
@Override public Textifier visitArray(final String name) { buf.setLength(0); appendComa(valueNumber++); if (name != null) { buf.append(name).append('='); } buf.append('{'); text.add(buf.toString()); Textifier t = createTextifier(); text.add(t.getText()); text.add("}"); return t; }
@Override public void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { stringBuilder.setLength(0); stringBuilder.append(tab); appendRawAccess(access & ~Opcodes.ACC_SUPER); stringBuilder.append(tab); appendAccess(access); stringBuilder.append("INNERCLASS "); appendDescriptor(INTERNAL_NAME, name); stringBuilder.append(' '); appendDescriptor(INTERNAL_NAME, outerName); stringBuilder.append(' '); appendDescriptor(INTERNAL_NAME, innerName); stringBuilder.append('\n'); text.add(stringBuilder.toString()); }
@Override public Printer visitTryCatchAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { stringBuilder.setLength(0); stringBuilder.append(tab2).append("TRYCATCHBLOCK @"); appendDescriptor(FIELD_DESCRIPTOR, descriptor); stringBuilder.append('('); text.add(stringBuilder.toString()); stringBuilder.setLength(0); stringBuilder.append(") : "); appendTypeReference(typeRef); stringBuilder.append(", ").append(typePath); stringBuilder.append(visible ? "\n" : INVISIBLE); return addNewTextifier(stringBuilder.toString()); }
@Override public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { buf.setLength(0); buf.append(tab2).append("TRYCATCHBLOCK "); appendLabel(start); buf.append(' '); appendLabel(end); buf.append(' '); appendLabel(handler); buf.append(' '); appendDescriptor(INTERNAL_NAME, type); buf.append('\n'); text.add(buf.toString()); }
@Override public void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { buf.setLength(0); buf.append(tab).append("// access flags 0x"); buf.append( Integer.toHexString(access & ~Opcodes.ACC_SUPER).toUpperCase()) .append('\n'); buf.append(tab); appendAccess(access); buf.append("INNERCLASS "); appendDescriptor(INTERNAL_NAME, name); buf.append(' '); appendDescriptor(INTERNAL_NAME, outerName); buf.append(' '); appendDescriptor(INTERNAL_NAME, innerName); buf.append('\n'); text.add(buf.toString()); }
@Override public Textifier visitAnnotation(final String name, final String descriptor) { visitAnnotationValue(name); stringBuilder.append('@'); appendDescriptor(FIELD_DESCRIPTOR, descriptor); stringBuilder.append('('); text.add(stringBuilder.toString()); return addNewTextifier(")"); }
@Override public void visitEnum(final String name, final String desc, final String value) { buf.setLength(0); appendComa(valueNumber++); if (name != null) { buf.append(name).append('='); } appendDescriptor(FIELD_DESCRIPTOR, desc); buf.append('.').append(value); text.add(buf.toString()); }
@Override public void visitEnum(final String name, final String descriptor, final String value) { visitAnnotationValue(name); appendDescriptor(FIELD_DESCRIPTOR, descriptor); stringBuilder.append('.').append(value); text.add(stringBuilder.toString()); }
/** * Prints a disassembled view of the given annotation. * * @param descriptor the class descriptor of the annotation class. * @param visible {@literal true} if the annotation is visible at runtime. * @return a visitor to visit the annotation values. */ // DontCheck(OverloadMethodsDeclarationOrder): overloads are semantically different. public Textifier visitAnnotation(final String descriptor, final boolean visible) { stringBuilder.setLength(0); stringBuilder.append(tab).append('@'); appendDescriptor(FIELD_DESCRIPTOR, descriptor); stringBuilder.append('('); text.add(stringBuilder.toString()); return addNewTextifier(visible ? ")\n" : ") // invisible\n"); }