01: package org.hansel;
02:
03: import org.objectweb.asm.ClassAdapter;
04: import org.objectweb.asm.ClassVisitor;
05: import org.objectweb.asm.MethodVisitor;
06: import org.objectweb.asm.Opcodes;
07: import org.objectweb.asm.tree.ClassNode;
08: import org.objectweb.asm.tree.InsnList;
09: 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,
19: final ClassNode classNode, 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,
26: String signature, String super Name, String[] interfaces) {
27: super .visit(version, access, name, signature, super Name,
28: interfaces);
29: }
30:
31: private MethodNode getMethodNode(String name, String desc) {
32: for (int i = 0; i < classNode.methods.size(); i++) {
33: MethodNode mn = (MethodNode) classNode.methods.get(i);
34: if (mn.name.equals(name) && mn.desc.equals(desc)) {
35: return mn;
36: }
37: }
38:
39: throw new IllegalStateException("Method: " + name + " - "
40: + desc + " not found.");
41: }
42:
43: public MethodVisitor visitMethod(int access, String name,
44: String desc, String signature, String[] exceptions) {
45: //System.err.println("-->" + name);
46: try {
47: MethodNode mn = getMethodNode(name, desc);
48: if ((mn.access & Opcodes.ACC_ABSTRACT) != 0) {
49: return cv.visitMethod(access, name, desc, signature,
50: exceptions);
51: }
52:
53: if (isPrivateEmptyConstructor(name, access, mn.instructions)
54: || isSynthetic(access)) {
55: return super .visitMethod(access, name, desc, signature,
56: exceptions);
57: }
58:
59: Analyzer analyzer = new Analyzer(new HanselInterpreter(
60: /*mn.instructions, */mn.localVariables)) {
61: protected Frame newFrame(final int nLocals,
62: final int nStack) {
63: return new HanselFrame(nLocals, nStack);
64: }
65:
66: protected Frame newFrame(final Frame src) {
67: return new HanselFrame((HanselFrame) src);
68: }
69: };
70:
71: Frame[] frames = analyzer.analyze(classNode.name, mn);
72: HanselFrame[] hanselFrames = new HanselFrame[frames.length];
73: for (int i = 0; i < frames.length; i++) {
74: hanselFrames[i] = (HanselFrame) frames[i];
75: }
76: return new HanselCodeAdapter(access, classNode.name,
77: mn.name, mn.instructions, mn.tryCatchBlocks, cv
78: .visitMethod(access, name, desc, signature,
79: exceptions), hanselFrames, loader);
80: } catch (AnalyzerException e) {
81: e.printStackTrace();
82: throw new IllegalStateException(
83: classNode.name + "." + name, e);
84: }
85: }
86:
87: private boolean isSynthetic(int access) {
88: return (access & Opcodes.ACC_SYNTHETIC) != 0;
89: }
90:
91: private boolean isPrivateEmptyConstructor(String name, int access,
92: InsnList instructions) {
93: return ((access & Opcodes.ACC_PRIVATE) != 0)
94: && "<init>".equals(name) && (instructions.size() == 6);
95: }
96: }
|