diff options
author | Reinier Zwitserloot <reinier@tipit.to> | 2009-09-23 07:44:13 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-09-23 07:44:13 +0200 |
commit | 21717cec11d5a8abdc3eba280290a65103bbeaf7 (patch) | |
tree | e18670cc2fb662d3e3069ed9632de23131e8ec46 /src_eclipseagent/lombok/eclipse/agent/EclipseLinkedNodeFinderTransformer.java | |
parent | 21ea5eeca8448c8880a3f2d975dee3107e3175b3 (diff) | |
download | lombok-21717cec11d5a8abdc3eba280290a65103bbeaf7.tar.gz lombok-21717cec11d5a8abdc3eba280290a65103bbeaf7.tar.bz2 lombok-21717cec11d5a8abdc3eba280290a65103bbeaf7.zip |
BIIG change to the eclipse agent: Now all patcher classes represent themselves via SPI. LinkedNOdeFinderTransformer is broken.
Diffstat (limited to 'src_eclipseagent/lombok/eclipse/agent/EclipseLinkedNodeFinderTransformer.java')
-rw-r--r-- | src_eclipseagent/lombok/eclipse/agent/EclipseLinkedNodeFinderTransformer.java | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src_eclipseagent/lombok/eclipse/agent/EclipseLinkedNodeFinderTransformer.java b/src_eclipseagent/lombok/eclipse/agent/EclipseLinkedNodeFinderTransformer.java new file mode 100644 index 00000000..9a1ebbb2 --- /dev/null +++ b/src_eclipseagent/lombok/eclipse/agent/EclipseLinkedNodeFinderTransformer.java @@ -0,0 +1,169 @@ +package lombok.eclipse.agent; + +import org.mangosdk.spi.ProviderFor; +import org.objectweb.asm.ClassAdapter; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import static org.objectweb.asm.Opcodes.*; + +@ProviderFor(EclipseTransformer.class) +public class EclipseLinkedNodeFinderTransformer implements EclipseTransformer { + private static final String LINKED_NODE_FINDER = "org/eclipse/jdt/core/internal/corext/dom/LinkedNodeFinder"; + + @Override public String getTargetClassName() { + return LINKED_NODE_FINDER; + } + + @Override public byte[] transform(byte[] in) { + ClassReader reader = new ClassReader(in); + ClassWriter writer = new ClassWriter(reader, 0); + + ClassAdapter adapter = new LinkedNodeFinderPatcherAdapter(writer); + reader.accept(adapter, 0); + return writer.toByteArray(); + } + + private static class LinkedNodeFinderPatcherAdapter extends ClassAdapter { + private int originalAccess; + private String originalDesc; + private String originalSignature; + private String[] originalExceptions; + + LinkedNodeFinderPatcherAdapter(ClassVisitor cv) { + super(cv); + } + + @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if ( !name.equals("findByNode") ) return super.visitMethod(access, name, desc, signature, exceptions); + + originalAccess = access; + originalDesc = desc; + originalSignature = signature; + originalExceptions = exceptions; + + return super.visitMethod(0, "findByNode0", desc, signature, exceptions); + } + + private static final String SIMPLENAME = "org/eclipse/jdt/core/dom/SimpleName"; + private static final String SIMPLENAME_ARRAY = "[L" + SIMPLENAME + ";"; + private static final String ASTNODE = "Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;"; + + /* + * code generated by running ASMifier on: + * + public SimpleName[] findByNode(ASTNode a, SimpleName b) { + SimpleName[] ps = this.findByNode0(a, b); + int count = 0; + for (int i = 0; i < ps.length; i++) { + if ( ps[i] == null || ps[i].$generatedBy == null ) count++; + } + if (count == ps.length) return ps; + SimpleName[] newPs = new SimpleName[count]; + count = 0; + for (int i = 0; i < ps.length; i++) { + if ( ps[i] == null || ps[i].p == null ) newPs[count++] = ps[i]; + } + return newPs; + } + */ + @Override public void visitEnd() { + MethodVisitor mv = super.visitMethod(originalAccess, "findByNode", originalDesc, originalSignature, originalExceptions); + mv.visitCode(); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKESPECIAL, LINKED_NODE_FINDER, "findByNode0", originalDesc); + mv.visitVarInsn(ASTORE, 3); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 4); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 5); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitFrame(F_APPEND,3, new Object[] {SIMPLENAME_ARRAY, INTEGER, INTEGER}, 0, null); + mv.visitVarInsn(ILOAD, 5); + mv.visitVarInsn(ALOAD, 3); + mv.visitInsn(ARRAYLENGTH); + Label l1 = new Label(); + mv.visitJumpInsn(IF_ICMPGE, l1); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 5); + mv.visitInsn(AALOAD); + Label l2 = new Label(); + mv.visitJumpInsn(IFNULL, l2); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 5); + mv.visitInsn(AALOAD); + mv.visitFieldInsn(GETFIELD, SIMPLENAME, "$generatedBy", ASTNODE); + Label l3 = new Label(); + mv.visitJumpInsn(IFNONNULL, l3); + mv.visitLabel(l2); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitIincInsn(4, 1); + mv.visitLabel(l3); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitIincInsn(5, 1); + mv.visitJumpInsn(GOTO, l0); + mv.visitLabel(l1); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(ALOAD, 3); + mv.visitInsn(ARRAYLENGTH); + Label l4 = new Label(); + mv.visitJumpInsn(IF_ICMPNE, l4); + mv.visitVarInsn(ALOAD, 3); + mv.visitInsn(ARETURN); + mv.visitLabel(l4); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ILOAD, 4); + mv.visitTypeInsn(ANEWARRAY, SIMPLENAME); + mv.visitVarInsn(ASTORE, 5); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 4); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 6); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitFrame(F_APPEND,2, new Object[] {SIMPLENAME_ARRAY, INTEGER}, 0, null); + mv.visitVarInsn(ILOAD, 6); + mv.visitVarInsn(ALOAD, 3); + mv.visitInsn(ARRAYLENGTH); + Label l6 = new Label(); + mv.visitJumpInsn(IF_ICMPGE, l6); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 6); + mv.visitInsn(AALOAD); + Label l7 = new Label(); + mv.visitJumpInsn(IFNULL, l7); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 6); + mv.visitInsn(AALOAD); + mv.visitFieldInsn(GETFIELD, SIMPLENAME, "$generatedBy", ASTNODE); + Label l8 = new Label(); + mv.visitJumpInsn(IFNONNULL, l8); + mv.visitLabel(l7); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ILOAD, 4); + mv.visitIincInsn(4, 1); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 6); + mv.visitInsn(AALOAD); + mv.visitInsn(AASTORE); + mv.visitLabel(l8); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitIincInsn(6, 1); + mv.visitJumpInsn(GOTO, l5); + mv.visitLabel(l6); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitVarInsn(ALOAD, 5); + mv.visitInsn(ARETURN); + mv.visitMaxs(4, 7); + super.visitEnd(); + } + } +} |