001: package de.loskutov.bco.asm;
002:
003: import java.util.BitSet;
004: import java.util.HashMap;
005: import java.util.List;
006: import java.util.Map;
007:
008: import org.objectweb.asm.AnnotationVisitor;
009: import org.objectweb.asm.Attribute;
010: import org.objectweb.asm.Label;
011: import org.objectweb.asm.MethodAdapter;
012: import org.objectweb.asm.MethodVisitor;
013: import org.objectweb.asm.Opcodes;
014: import org.objectweb.asm.tree.LabelNode;
015: import org.objectweb.asm.tree.MethodNode;
016: import org.objectweb.asm.util.AbstractVisitor;
017:
018: import de.loskutov.bco.asm.CommentedClassVisitor.CommentedAnnotationVisitor;
019:
020: /**
021: * @author Eric Bruneton
022: */
023:
024: public class DecompilerMethodVisitor extends MethodAdapter {
025:
026: private String owner;
027:
028: private List text;
029:
030: private MethodNode meth;
031:
032: private LabelNode currentLabel;
033:
034: private int currentInsn;
035:
036: private Map lineNumbers;
037:
038: private final BitSet modes;
039:
040: public DecompilerMethodVisitor(final String owner,
041: final MethodNode meth, final MethodVisitor mv, BitSet modes) {
042: super (mv);
043: this .owner = owner;
044: this .modes = modes;
045: this .text = ((AbstractVisitor) mv).getText();
046: this .meth = meth;
047: this .lineNumbers = new HashMap();
048: }
049:
050: public DecompiledMethod getResult(final ClassLoader cl) {
051: return new DecompiledMethod(owner, text, lineNumbers, meth, cl,
052: modes);
053: }
054:
055: public AnnotationVisitor visitAnnotationDefault() {
056: AnnotationVisitor annVisitor = super .visitAnnotationDefault();
057: AnnotationVisitor visitor = meth.visitAnnotationDefault();
058: if (annVisitor instanceof CommentedAnnotationVisitor) {
059: CommentedAnnotationVisitor av = (CommentedAnnotationVisitor) annVisitor;
060: av.setAnnotationVisitor(visitor);
061: }
062: return annVisitor;
063: }
064:
065: public AnnotationVisitor visitAnnotation(String desc,
066: boolean visible) {
067: AnnotationVisitor annVisitor = super .visitAnnotation(desc,
068: visible);
069: AnnotationVisitor visitor = meth.visitAnnotation(desc, visible);
070: if (annVisitor instanceof CommentedAnnotationVisitor) {
071: CommentedAnnotationVisitor av = (CommentedAnnotationVisitor) annVisitor;
072: av.setAnnotationVisitor(visitor);
073: }
074: return annVisitor;
075: }
076:
077: public AnnotationVisitor visitParameterAnnotation(int parameter,
078: String desc, boolean visible) {
079: AnnotationVisitor annVisitor = super .visitParameterAnnotation(
080: parameter, desc, visible);
081: AnnotationVisitor visitor = meth.visitParameterAnnotation(
082: parameter, desc, visible);
083: if (annVisitor instanceof CommentedAnnotationVisitor) {
084: CommentedAnnotationVisitor av = (CommentedAnnotationVisitor) annVisitor;
085: av.setAnnotationVisitor(visitor);
086: }
087: return annVisitor;
088: }
089:
090: public void visitCode() {
091: super .visitCode();
092: meth.visitCode();
093: }
094:
095: public void visitEnd() {
096: super .visitEnd();
097: meth.visitEnd();
098: }
099:
100: public void visitAttribute(Attribute attr) {
101: super .visitAttribute(attr);
102: meth.visitAttribute(attr);
103: }
104:
105: public void visitInsn(final int opcode) {
106: addIndex(opcode);
107: super .visitInsn(opcode);
108: meth.visitInsn(opcode);
109: }
110:
111: public void visitIntInsn(final int opcode, final int operand) {
112: addIndex(opcode);
113: super .visitIntInsn(opcode, operand);
114: meth.visitIntInsn(opcode, operand);
115: }
116:
117: public void visitVarInsn(final int opcode, final int var) {
118: addIndex(opcode);
119: super .visitVarInsn(opcode, var);
120: meth.visitVarInsn(opcode, var);
121: }
122:
123: public void visitTypeInsn(final int opcode, final String desc) {
124: addIndex(opcode);
125: super .visitTypeInsn(opcode, desc);
126: meth.visitTypeInsn(opcode, desc);
127: }
128:
129: public void visitFieldInsn(final int opcode, final String owner1,
130: final String name, final String desc) {
131: addIndex(opcode);
132: super .visitFieldInsn(opcode, owner1, name, desc);
133: meth.visitFieldInsn(opcode, owner1, name, desc);
134: }
135:
136: public void visitMethodInsn(final int opcode, final String owner1,
137: final String name, final String desc) {
138: addIndex(opcode);
139: super .visitMethodInsn(opcode, owner1, name, desc);
140: meth.visitMethodInsn(opcode, owner1, name, desc);
141: }
142:
143: public void visitJumpInsn(final int opcode, final Label label) {
144: addIndex(opcode);
145: super .visitJumpInsn(opcode, label);
146: meth.visitJumpInsn(opcode, label);
147: }
148:
149: public void visitLabel(final Label label) {
150: super .visitLabel(label);
151: meth.visitLabel(label);
152: currentLabel = (LabelNode) meth.instructions.getLast();
153: addIndex(-1);
154: }
155:
156: public void visitLdcInsn(final Object cst) {
157: addIndex(Opcodes.LDC);
158: super .visitLdcInsn(cst);
159: meth.visitLdcInsn(cst);
160: }
161:
162: public void visitIincInsn(final int var, final int increment) {
163: addIndex(Opcodes.IINC);
164: super .visitIincInsn(var, increment);
165: meth.visitIincInsn(var, increment);
166: }
167:
168: public void visitTableSwitchInsn(final int min, final int max,
169: final Label dflt, final Label[] labels) {
170: addIndex(Opcodes.TABLESWITCH);
171: super .visitTableSwitchInsn(min, max, dflt, labels);
172: meth.visitTableSwitchInsn(min, max, dflt, labels);
173: }
174:
175: public void visitLookupSwitchInsn(final Label dflt,
176: final int[] keys, final Label[] labels) {
177: addIndex(Opcodes.LOOKUPSWITCH);
178: super .visitLookupSwitchInsn(dflt, keys, labels);
179: meth.visitLookupSwitchInsn(dflt, keys, labels);
180: }
181:
182: public void visitMultiANewArrayInsn(final String desc,
183: final int dims) {
184: addIndex(Opcodes.MULTIANEWARRAY);
185: super .visitMultiANewArrayInsn(desc, dims);
186: meth.visitMultiANewArrayInsn(desc, dims);
187: }
188:
189: public void visitTryCatchBlock(final Label start, final Label end,
190: final Label handler, final String type) {
191: super .visitTryCatchBlock(start, end, handler, type);
192: meth.visitTryCatchBlock(start, end, handler, type);
193: }
194:
195: public void visitLocalVariable(final String name,
196: final String desc, final String signature,
197: final Label start, final Label end, final int index) {
198: // localVariables.add(new LocalVariableNode(
199: // name, desc, signature, new LabelNode(start), new LabelNode(end), index));
200: super .visitLocalVariable(name, desc, signature, start, end,
201: index);
202: meth.visitLocalVariable(name, desc, signature, start, end,
203: index);
204: }
205:
206: public void visitLineNumber(final int line, final Label start) {
207: lineNumbers.put(start, new Integer(line));
208: super .visitLineNumber(line, start);
209: meth.visitLineNumber(line, start);
210: }
211:
212: public void visitMaxs(final int maxStack, final int maxLocals) {
213: super .visitMaxs(maxStack, maxLocals);
214: meth.visitMaxs(maxStack, maxLocals);
215: }
216:
217: public void visitFrame(int type, int nLocal, Object[] local,
218: int nStack, Object[] stack) {
219: addIndex(-1);
220: super .visitFrame(type, nLocal, local, nStack, stack);
221: meth.visitFrame(type, nLocal, local, nStack, stack);
222: }
223:
224: protected void addIndex(final int opcode) {
225: text.add(new Index(currentLabel, currentInsn++, opcode));
226: }
227: }
|