Fully moved to using the lombok.patcher project. Means our dependency on ASM is no longer needed (our dep on lombok-patcher takes care of it), and the old EclipseTransformer system has been removed.

This commit is contained in:
Reinier Zwitserloot committed 2009-10-07 20:50:02 +02:00
1 parent 1f9d6089cd
commit e8c706a7b6
6 files changed
+97 -188

No files matched your search

Binary file not shown.
Binary file not shown.
@@ -1,169 +0,0 @@
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();
}
}
}
@@ -22,11 +22,15 @@
package lombok.eclipse.agent;
import java.lang.instrument.Instrumentation;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
import lombok.patcher.ScriptManager;
import lombok.patcher.StackRequest;
import lombok.patcher.TargetMatcher;
import lombok.patcher.equinox.EquinoxClassLoader;
import lombok.patcher.scripts.ScriptBuilder;
@@ -59,17 +63,6 @@ public class EclipsePatcher {
.wrapMethod(new Hook("lombok/eclipse/agent/PatchFixes", "fixRetrieveStartingCatchPosition", "(I)I"))
.transplant().request(StackRequest.PARAM1).build());
sm.addScript(ScriptBuilder.addField()
.targetClass("org.eclipse.jdt.internal.compiler.ast.ASTNode")
.fieldName("$generatedBy")
.fieldType("Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;")
.setPublic().setTransient().build());
sm.addScript(ScriptBuilder.addField()
.targetClass("org.eclipse.jdt.core.dom.ASTNode")
.fieldName("$isGenerated").fieldType("Z")
.setPublic().setTransient().build());
sm.addScript(ScriptBuilder.addField()
.targetClass("org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration")
.fieldName("$lombokAST").fieldType("Ljava/lang/Object;")
@@ -114,6 +107,62 @@ public class EclipsePatcher {
.decisionMethod(new Hook("lombok/eclipse/agent/PatchFixes", "checkBit24", "(Ljava/lang/Object;)Z"))
.transplant().request(StackRequest.PARAM1).build());
sm.addScript(ScriptBuilder.addField()
.targetClass("org.eclipse.jdt.internal.compiler.ast.ASTNode")
.fieldName("$generatedBy")
.fieldType("Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;")
.setPublic().setTransient().build());
sm.addScript(ScriptBuilder.addField()
.targetClass("org.eclipse.jdt.core.dom.ASTNode")
.fieldName("$isGenerated").fieldType("Z")
.setPublic().setTransient().build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new TargetMatcher() {
@Override public boolean matches(String classSpec, String methodName, String descriptor) {
if (!"convert".equals(methodName)) return false;
List<String> fullDesc = MethodTarget.decomposeFullDesc(descriptor);
if ("V".equals(fullDesc.get(0))) return false;
return fullDesc.size() == 2;
}
@Override public Collection<String> getAffectedClasses() {
return Collections.singleton("org.eclipse.jdt.core.dom.ASTConverter");
}
}).request(StackRequest.PARAM1, StackRequest.RETURN_VALUE)
.wrapMethod(new Hook("lombok/eclipse/agent/PatchFixes", "setIsGeneratedFlag",
"(Lorg/eclipse/jdt/core/dom/ASTNode;Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;)V"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new TargetMatcher() {
@Override public boolean matches(String classSpec, String methodName, String descriptor) {
if (!methodName.startsWith("convert")) return false;
List<String> fullDesc = MethodTarget.decomposeFullDesc(descriptor);
if (fullDesc.size() < 2) return false;
if (!fullDesc.get(1).startsWith("Lorg/eclipse/jdt/internal/compiler/ast/")) return false;
return true;
}
@Override public Collection<String> getAffectedClasses() {
return Collections.singleton("org.eclipse.jdt.core.dom.ASTConverter");
}
}).methodToWrap(new Hook("org/eclipse/jdt/core/dom/SimpleName", "<init>", "(Lorg/eclipse/jdt/core/dom/AST;)V"))
.requestExtra(StackRequest.PARAM1)
.replacementMethod(new Hook("lombok/eclipse/agent/PatchFixes", "setIsGeneratedFlagForSimpleName",
"(Lorg/eclipse/jdt/core/dom/SimpleName;Ljava/lang/Object;)V"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder", "findByNode"))
.wrapMethod(new Hook("lombok/eclipse/agent/PatchFixes", "removeGeneratedSimpleNames",
"([Lorg/eclipse/jdt/core/dom/SimpleName;)[Lorg/eclipse/jdt/core/dom/SimpleName;"))
.request(StackRequest.RETURN_VALUE).build());
if (reloadExistingClasses) sm.reloadClasses(instrumentation);
}
}
@@ -1,8 +0,0 @@
package lombok.eclipse.agent;
public interface EclipseTransformer {
/** slash and not dot separated */
String getTargetClassName();
byte[] transform(byte[] in);
}
@@ -1,5 +1,9 @@
package lombok.eclipse.agent;
import java.lang.reflect.Field;
import org.eclipse.jdt.core.dom.SimpleName;
public class PatchFixes {
public static int fixRetrieveStartingCatchPosition(int in) {
return in;
@@ -11,4 +15,37 @@ public class PatchFixes {
int bits = (Integer)(node.getClass().getField("bits").get(node));
return (bits & BIT24) != 0;
}
public static void setIsGeneratedFlag(org.eclipse.jdt.core.dom.ASTNode domNode,
org.eclipse.jdt.internal.compiler.ast.ASTNode internalNode) throws Exception {
boolean isGenerated = internalNode.getClass().getField("$generatedBy").get(internalNode) != null;
if (isGenerated) domNode.getClass().getField("$isGenerated").set(domNode, true);
}
public static void setIsGeneratedFlagForSimpleName(SimpleName name, Object internalNode) throws Exception {
System.out.println("Setting isGenerated on SimpleName");
if (internalNode instanceof org.eclipse.jdt.internal.compiler.ast.ASTNode) {
if (internalNode.getClass().getField("$generatedBy").get(internalNode) != null) {
name.getClass().getField("$isGenerated").set(name, true);
}
}
}
public static SimpleName[] removeGeneratedSimpleNames(SimpleName[] in) throws Exception {
System.out.print("Removing is generated...");
Field f = SimpleName.class.getField("$isGenerated");
int count = 0;
for (int i = 0; i < in.length; i++) {
if ( in[i] == null || !((Boolean)f.get(in[i])).booleanValue() ) count++;
}
System.out.println("" + (in.length - count));
if (count == in.length) return in;
SimpleName[] newSimpleNames = new SimpleName[count];
count = 0;
for (int i = 0; i < in.length; i++) {
if ( in[i] == null || !((Boolean)f.get(in[i])).booleanValue() ) newSimpleNames[count++] = in[i];
}
return newSimpleNames;
}
}