I am trying (with no success) to print only the contents of a given method. The following code almost does the trick:
class MyTraceMethodVisitor extends MethodVisitor {
public MyTraceMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM4, mv);
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
}
}
class MyClassVisitor extends ClassVisitor {
public MyClassVisitor(ClassVisitor cv) {
super(Opcodes.ASM4, cv);
}
@Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
return null;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
if (name.equals("get777"))
return new MyTraceMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
return null;
}
}
running it with
ClassReader classReader = new ClassReader("something.Point");
PrintWriter printWriter = new PrintWriter(System.out);
TraceClassVisitor traceClassVisitor = new TraceClassVisitor(printWriter);
MyClassVisitor myClassVisitor = new MyClassVisitor(traceClassVisitor);
classReader.accept(myClassVisitor, ClassReader.SKIP_DEBUG);
resulting in
// class version 50.0 (50)
// access flags 0x21
public class something/Point {
// access flags 0x1
public get777()I
SIPUSH 777
IRETURN
}
What I'd like to get was just
SIPUSH 777
IRETURN
without signature, comments and whatsoever. How can I accomplish that?
The answer is already pretty old and involves writing much code.
As of asm v5 printing method instructions is straightforward:
// Setup for asm ClassReader, ClassWriter and your implementation of the ClassVisitor(e.g.: YourClassVisitor)
final ClassReader reader = new ClassReader(classBytes);
final ClassWriter writer = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
final ClassVisitor visitor =new YourClassVisitor(Opcodes.ASM5, visitor);
In your implementation of the ClassVisitor, simply override the visitMethod method. Here an example:
public class YourClassVisitor extends ClassVisitor {
public InstrumentationClassVisitor(int api, ClassVisitor cv) {
super(api, cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
Printer p = new Textifier(Opcodes.ASM5) {
@Override
public void visitMethodEnd() {
print(new PrintWriter(System.out)); // print it after it has been visited
}
};
return new TraceMethodVisitor(mv, p);
}
}
The TraceMethodVisitor will receive the event calls for visiting method instructions etc. by the classVisitor. The code will then be printed by the TraceMethodVisitor with the help of the Printer.