下面列出了怎么用org.objectweb.asm.util.Textifier的API类实例代码及写法,或者点击链接到github查看源代码。
@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);
}
}
public static void viewByteCode(byte[] bytecode) {
ClassReader cr = new ClassReader(bytecode);
ClassNode cn = new ClassNode();
cr.accept(cn, 0);
final List<MethodNode> mns = cn.methods;
Printer printer = new Textifier();
TraceMethodVisitor mp = new TraceMethodVisitor(printer);
for (MethodNode mn : mns) {
InsnList inList = mn.instructions;
System.out.println(mn.name);
for (int i = 0; i < inList.size(); i++) {
inList.get(i).accept(mp);
StringWriter sw = new StringWriter();
printer.print(new PrintWriter(sw));
printer.getText().clear();
System.out.print(sw.toString());
}
}
}
public static void viewByteCode(byte[] bytecode) {
ClassReader classReader = new ClassReader(bytecode);
ClassNode classNode = new ClassNode();
classReader.accept(classNode, 0);
final List<MethodNode> methodNodes = classNode.methods;
Printer printer = new Textifier();
TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer);
for (MethodNode methodNode : methodNodes) {
InsnList insnList = methodNode.instructions;
System.out.println(methodNode.name);
for (int i = 0; i < insnList.size(); i++) {
insnList.get(i).accept(traceMethodVisitor);
StringWriter sw = new StringWriter();
printer.print(new PrintWriter(sw));
printer.getText().clear();
System.out.print(sw.toString());
}
}
}
public static void dump(Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals, boolean textify) {
try {
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
if(!file.exists())
file.createNewFile();
PrintWriter pout = new PrintWriter(file);
ClassVisitor cv = new TraceClassVisitor(null, textify ? new Textifier() : new ASMifier(), pout);
if(filterImportant) cv = new ImportantInsnVisitor(cv);
if(sortLocals) cv = new LocalVariablesSorterVisitor(cv);
acceptor.accept(cv);
pout.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected Textifier createTextifier() {
if(null == nextTracker){
return new Textifier();
}
return nextTracker;
}
@Override
public Textifier visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
nextTracker = new TextifierLabelTrack();
alllabelMaps.put(name + desc, nextTracker.getLabelNames());
return super.visitMethod(access, name, desc, signature, exceptions);
}
/**
* Converts the given method to a String.
*/
public static String textify(@NonNull MethodNode method) {
Textifier textifier = new Textifier();
TraceMethodVisitor trace = new TraceMethodVisitor(textifier);
method.accept(trace);
String ret = "";
for (Object line : textifier.getText()) {
ret += line;
}
return ret;
}
public static String textify(byte[] bytes, boolean skipDebug) {
Printer textifier = new Textifier();
StringWriter sw = new StringWriter();
new ClassReader(bytes)
.accept(
new TraceClassVisitor(null, textifier, new PrintWriter(sw, true)),
ClassReader.SKIP_FRAMES
| ClassReader.SKIP_CODE
| (skipDebug ? ClassReader.SKIP_DEBUG : 0));
return sw.toString();
}
private void writeBytecodeToDisk(final byte[] clazz, Path folder) throws IOException {
final ClassReader reader = new ClassReader(clazz);
final CharArrayWriter buffer = new CharArrayWriter();
reader.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(
buffer)), ClassReader.EXPAND_FRAMES);
final Path outFile = folder.resolve(this.currentClass.asJavaName() + ".txt");
Files.write(outFile, Collections.singleton(buffer.toString()), StandardCharsets.UTF_8, StandardOpenOption.CREATE);
}
@Override
public String toString() {
final StringWriter writer = new StringWriter();
this.rawNode.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(
writer)));
return writer.toString();
}
private String toString(MethodTree mt) {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final TraceMethodVisitor mv = new TraceMethodVisitor(new Textifier());
mt.rawNode().accept(mv);
try (PrintWriter pw = new PrintWriter(bos)) {
mv.p.print(pw);
}
return "Byte code is \n" + new String(bos.toByteArray());
}
public String dumpBytecode(final byte[] bytecode) {
if (bytecode == null) {
throw new NullPointerException("bytecode");
}
return writeBytecode(bytecode, new Textifier());
}
public String toString() {
Textifier t = new Textifier();
accept(new TraceMethodVisitor(t));
StringWriter sw = new StringWriter();
t.print(new PrintWriter(sw));
return sw.toString();
}
private Stream<String> dumpClassFile(InputStream stream) throws IOException {
byte[] textifiedClass;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(bos)) { // NOPMD required by API
ClassReader reader = new ClassReader(stream);
TraceClassVisitor traceVisitor = new TraceClassVisitor(null, new Textifier(), pw);
reader.accept(traceVisitor, asmFlags);
textifiedClass = bos.toByteArray();
}
try (InputStreamReader streamReader =
new InputStreamReader(new ByteArrayInputStream(textifiedClass))) {
return CharStreams.readLines(streamReader).stream();
}
}
@SuppressWarnings("unchecked")
public <T extends TypeEntry> void emitOuterType(T ast) {
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
this.cw = writer;
if (VERIFY_EMITTED_BYTECODE) {
this.cw = new CheckClassAdapter(this.cw);
}
AstEmitter<AbstractEmitterContext, T> emitter = (AstEmitter<AbstractEmitterContext, T>) this.set.getAstEmitter(ast.getClass());
if (emitter == null) {
throw new IllegalArgumentException("No emitter for ast entry " + ast.getClass().getName());
}
emitter.emit(this, ast);
this.cw.visitEnd();
byte[] clazz = writer.toByteArray();
if (DUMP_INSTRUCTIONS_AFTER_WRITE) {
ClassReader cr = new ClassReader(clazz);
ClassNode cn = new ClassNode();
cr.accept(cn, 0);
List<MethodNode> methods = cn.methods;
for (MethodNode mn : methods) {
System.out.println("Method: " + mn.name + mn.desc);
Printer printer = new Textifier();
TraceMethodVisitor mp = new TraceMethodVisitor(printer);
for (Iterator<AbstractInsnNode> it = mn.instructions.iterator(); it.hasNext();) {
AbstractInsnNode insn = it.next();
insn.accept(mp);
}
StringWriter sw = new StringWriter();
printer.print(new PrintWriter(sw));
String s = sw.toString();
if (s.endsWith("\n")) {
s = s.substring(0, s.length() - 1);
}
System.out.println(s);
mn.instructions.accept(mp);
}
}
try {
this.out.write(clazz);
} catch (IOException e) {
Throwables.propagate(e);
}
}
public static String toString(MethodNode mn) {
Textifier t = new Textifier();
TraceMethodVisitor tmv = new TraceMethodVisitor(t);
mn.accept(tmv);
return t.toString();
}
@Override
protected Textifier createTextifier() {
return new LoggableTextifier();
}
@Override
public Textifier visitClassAnnotation(String desc, boolean visible) {
Textifier t = super.visitClassAnnotation(desc, visible);
log();
return t;
}
@Override
public Textifier visitField(int access, String name, String desc, String signature, Object value) {
Textifier t = super.visitField(access, name, desc, signature, value);
log();
return t;
}
@Override
public Textifier visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
Textifier t = super.visitMethod(access, name, desc, signature, exceptions);
log();
return t;
}
@Override
public Textifier visitAnnotation(String name, String desc) {
Textifier t = super.visitAnnotation(name, desc);
log();
return t;
}
@Override
public Textifier visitArray(String name) {
Textifier t = super.visitArray(name);
log();
return t;
}
@Override
public Textifier visitFieldAnnotation(String desc, boolean visible) {
Textifier t = super.visitFieldAnnotation(desc, visible);
log();
return t;
}
@Override
public Textifier visitAnnotationDefault() {
Textifier t = super.visitAnnotationDefault();
log();
return t;
}
@Override
public Textifier visitMethodAnnotation(String desc, boolean visible) {
Textifier t = super.visitMethodAnnotation(desc, visible);
log();
return t;
}
@Override
public Textifier visitParameterAnnotation(int parameter, String desc, boolean visible) {
Textifier t = super.visitParameterAnnotation(parameter, desc, visible);
log();
return t;
}
@Override
public Textifier visitAnnotation(String desc, boolean visible) {
Textifier t = super.visitAnnotation(desc, visible);
log();
return t;
}
@Override
public Textifier visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
Textifier t = super.visitTypeAnnotation(typeRef, typePath, desc, visible);
log();
return t;
}
@Override
public Textifier visitAnnotableParameterCount(int parameterCount, boolean visible) {
Textifier t = super.visitAnnotableParameterCount(parameterCount, visible);
log();
return t;
}
@Override
protected Textifier createTextifier() {
return new ExtraTextifier();
}