1 package org.hansel; 2 3 import org.objectweb.asm.ClassAdapter; 4 import org.objectweb.asm.ClassVisitor; 5 import org.objectweb.asm.MethodVisitor; 6 import org.objectweb.asm.Opcodes; 7 import org.objectweb.asm.tree.ClassNode; 8 import org.objectweb.asm.tree.InsnList; 9 import org.objectweb.asm.tree.MethodNode; 10 import org.objectweb.asm.tree.analysis.Analyzer; 11 import org.objectweb.asm.tree.analysis.AnalyzerException; 12 import org.objectweb.asm.tree.analysis.Frame; 13 14 public class TransformingAdapter extends ClassAdapter { 15 private ClassNode classNode; 16 private ClassLoader loader; 17 18 public TransformingAdapter(final ClassVisitor cv, final ClassNode classNode, 19 ClassLoader loader) { 20 super(cv); 21 this.classNode = classNode; 22 this.loader = loader; 23 } 24 25 public void visit(int version, int access, String name, String signature, String superName, String [] interfaces) { 26 super.visit(version, access, name, signature, superName, interfaces); 27 } 28 29 private MethodNode getMethodNode(String name, String desc) { 30 for (int i=0; i<classNode.methods.size(); i++) { 31 MethodNode mn = (MethodNode) classNode.methods.get(i); 32 if (mn.name.equals(name) && mn.desc.equals(desc)) { 33 return mn; 34 } 35 } 36 37 throw new IllegalStateException ("Method: " + name + " - " + desc 38 + " not found."); 39 } 40 41 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 42 try { 44 MethodNode mn = getMethodNode(name, desc); 45 if ((mn.access & Opcodes.ACC_ABSTRACT) != 0) { 46 return cv.visitMethod(access, name, desc, signature, 47 exceptions); 48 } 49 50 if (isPrivateEmptyConstructor(name, access, mn.instructions) 51 || isSynthetic(access)) { 52 return super.visitMethod(access, name, desc, signature, exceptions); 53 } 54 55 Analyzer analyzer = 56 new Analyzer(new HanselInterpreter(mn.localVariables)) { 57 protected Frame newFrame (final int nLocals, final int nStack) { 58 return new HanselFrame(nLocals, nStack); 59 } 60 61 protected Frame newFrame (final Frame src) { 62 return new HanselFrame((HanselFrame) src); 63 } 64 }; 65 66 Frame[] frames = analyzer.analyze(classNode.name, mn); 67 HanselFrame[] hanselFrames = new HanselFrame[frames.length]; 68 for (int i=0; i<frames.length; i++) { 69 hanselFrames[i] = (HanselFrame) frames[i]; 70 } 71 return new HanselCodeAdapter(access, classNode.name, mn.name, 72 mn.instructions, mn.tryCatchBlocks, 73 cv.visitMethod(access, name, desc, signature, 74 exceptions), 75 hanselFrames, loader); 76 } catch (AnalyzerException e) { 77 e.printStackTrace(); 78 throw new IllegalStateException (classNode.name + "." + name, e); 79 } 80 } 81 82 private boolean isSynthetic(int access) { 83 return (access & Opcodes.ACC_SYNTHETIC) != 0; 84 } 85 86 private boolean isPrivateEmptyConstructor(String name, 87 int access, InsnList instructions) { 88 return ((access & Opcodes.ACC_PRIVATE) != 0) 89 && "<init>".equals(name) && (instructions.size() == 6); 90 } 91 } 92 | Popular Tags |