diff options
-rw-r--r-- | .classpath | 1 | ||||
-rw-r--r-- | lib/eclipse.agent/lombok-patcher.jar | bin | 0 -> 66886 bytes | |||
-rw-r--r-- | src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java | 4 | ||||
-rw-r--r-- | src_eclipseagent/java/lombok/eclipse/PatchFixes.java | 14 | ||||
-rw-r--r-- | src_eclipseagent/lombok/eclipse/agent/EclipseASTConverterTransformer.java | 95 | ||||
-rw-r--r-- | src_eclipseagent/lombok/eclipse/agent/EclipseASTNodeTransformer.java | 68 | ||||
-rw-r--r-- | src_eclipseagent/lombok/eclipse/agent/EclipseCUDTransformer.java | 66 | ||||
-rw-r--r-- | src_eclipseagent/lombok/eclipse/agent/EclipseParserTransformer.java | 178 | ||||
-rw-r--r-- | src_eclipseagent/lombok/eclipse/agent/EclipsePatcher.java | 59 |
9 files changed, 78 insertions, 407 deletions
@@ -18,5 +18,6 @@ <classpathentry kind="lib" path="deps/lombok/org.eclipse.equinox.common_3.5.0.v20090520-1800.jar"/> <classpathentry kind="lib" path="deps/lombok/spi-0.2.3-pre.jar"/> <classpathentry kind="lib" path="deps/tools.jar"/> + <classpathentry combineaccessrules="false" kind="src" path="/lombok.patcher"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/lib/eclipse.agent/lombok-patcher.jar b/lib/eclipse.agent/lombok-patcher.jar Binary files differnew file mode 100644 index 00000000..3c22f4f0 --- /dev/null +++ b/lib/eclipse.agent/lombok-patcher.jar diff --git a/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java b/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java index f5c8bbd3..3d8e9ec9 100644 --- a/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java +++ b/src_eclipseagent/java/lombok/eclipse/ClassLoaderWorkaround.java @@ -52,6 +52,10 @@ public class ClassLoaderWorkaround { private static final Map<ClassLoader, Method> transform = new HashMap<ClassLoader, Method>(); + public static void transformCompilationUnitDeclarationSwapped(Object cud, Object parser) throws Exception { + transformCompilationUnitDeclaration(parser, cud); + } + public static void transformCompilationUnitDeclaration(Object parser, Object cud) throws Exception { Method transformMethod = getTransformMethod(cud); try { diff --git a/src_eclipseagent/java/lombok/eclipse/PatchFixes.java b/src_eclipseagent/java/lombok/eclipse/PatchFixes.java new file mode 100644 index 00000000..23c60d32 --- /dev/null +++ b/src_eclipseagent/java/lombok/eclipse/PatchFixes.java @@ -0,0 +1,14 @@ +package java.lombok.eclipse; + +public class PatchFixes { + public static int fixRetrieveStartingCatchPosition(int in) { + return in; + } + + private static final int BIT24 = 0x800000; + + public static boolean checkBit24(Object node) throws Exception { + int bits = (Integer)(node.getClass().getField("bits").get(node)); + return (bits & BIT24) != 0; + } +} diff --git a/src_eclipseagent/lombok/eclipse/agent/EclipseASTConverterTransformer.java b/src_eclipseagent/lombok/eclipse/agent/EclipseASTConverterTransformer.java deleted file mode 100644 index 4245e246..00000000 --- a/src_eclipseagent/lombok/eclipse/agent/EclipseASTConverterTransformer.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -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.MethodAdapter; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -/** - * Transforms Eclipse's <code>org.eclipse.jdt.core.dom.ASTConverter</code> class, which sometimes rescans bits and pieces - * of source files because Eclipse's own AST doesn't actually have enough information for eclipse (why they don't just fix - * the AST tree generator is beyond me). At any rate, for catch blocks generated by lombok, eclipse tries to rescan the - * source file to find the source position of the catch statement, which will of course fail as there's nothing there. - * We will fix the code to return the original starting position, which is a pretty good simile, instead of '-1', which - * screws up all sorts of things. - * - * Transformations applied:<ul> - * <li>The <code>retrieveStartingCatchPosition(int, int)</code> method is instrumented to return its first parameter - * instead of the constant -1.</li></ul> - */ -@ProviderFor(EclipseTransformer.class) -public class EclipseASTConverterTransformer implements EclipseTransformer { - public byte[] transform(byte[] classfileBuffer) { - ClassReader reader = new ClassReader(classfileBuffer); - ClassWriter writer = new ClassWriter(reader, 0); - - ClassAdapter adapter = new ASTConverterPatcherAdapter(writer); - reader.accept(adapter, 0); - return writer.toByteArray(); - } - - private static class ASTConverterPatcherAdapter extends ClassAdapter { - public ASTConverterPatcherAdapter(ClassVisitor cv) { - super(cv); - } - - @Override public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - MethodVisitor writerVisitor = super.visitMethod(access, name, desc, signature, exceptions); - if ( !name.equals("retrieveStartingCatchPosition") ) return writerVisitor; - - return new RetrieveStartingCatchPositionPatcher(writerVisitor); - } - } - - static class RetrieveStartingCatchPositionPatcher extends MethodAdapter { - RetrieveStartingCatchPositionPatcher(MethodVisitor mv) { - super(mv); - } - - int count = 0; - @Override public void visitInsn(int opcode) { - if ( opcode == Opcodes.IRETURN ) { - if ( count++ == 0 ) { - super.visitInsn(opcode); - return; - } - //replaces: "return -1" with "return [firstParam]"; - super.visitInsn(Opcodes.POP); - super.visitVarInsn(Opcodes.ILOAD, 1); - super.visitInsn(Opcodes.IRETURN); - } else { - super.visitInsn(opcode); - } - } - } - - @Override public String getTargetClassName() { - return "org/eclipse/jdt/core/dom/ASTConverter"; - } -} diff --git a/src_eclipseagent/lombok/eclipse/agent/EclipseASTNodeTransformer.java b/src_eclipseagent/lombok/eclipse/agent/EclipseASTNodeTransformer.java deleted file mode 100644 index e27aa08c..00000000 --- a/src_eclipseagent/lombok/eclipse/agent/EclipseASTNodeTransformer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -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.FieldVisitor; -import org.objectweb.asm.Opcodes; - -/** - * Transforms Eclipse's {@code org.eclipse.jdt.internal.compiler.ast.ASTNode} class, - * which is the super-class of all AST Node class for Eclipse. - * - * Transformations applied:<ul> - * <li>A field is added: 'public transient ASTNode $generatedBy = null;'. It is set to something other than {@code null} if - * this node is generated; the reference then points at the node that is responsible for its generation (example: a {@code @Data} annotation).</li></ul> - */ -@ProviderFor(EclipseTransformer.class) -public class EclipseASTNodeTransformer implements EclipseTransformer { - private static final String ASTNODE = "org/eclipse/jdt/internal/compiler/ast/ASTNode"; - - public byte[] transform(byte[] classfileBuffer) { - ClassReader reader = new ClassReader(classfileBuffer); - ClassWriter writer = new ClassWriter(reader, 0); - - ClassAdapter adapter = new ASTNodePatcherAdapter(writer); - reader.accept(adapter, 0); - return writer.toByteArray(); - } - - private static class ASTNodePatcherAdapter extends ClassAdapter { - ASTNodePatcherAdapter(ClassVisitor cv) { - super(cv); - } - - @Override public void visitEnd() { - FieldVisitor fv = cv.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_TRANSIENT, "$generatedBy", "L" + ASTNODE + ";", null, null); - fv.visitEnd(); - cv.visitEnd(); - } - } - - @Override public String getTargetClassName() { - return ASTNODE; - } -} diff --git a/src_eclipseagent/lombok/eclipse/agent/EclipseCUDTransformer.java b/src_eclipseagent/lombok/eclipse/agent/EclipseCUDTransformer.java deleted file mode 100644 index b18a1ff1..00000000 --- a/src_eclipseagent/lombok/eclipse/agent/EclipseCUDTransformer.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -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.FieldVisitor; -import org.objectweb.asm.Opcodes; - -/** - * Transforms Eclipse's <code>org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration</code> class, - * which is the top-level AST Node class for Eclipse. - * - * Transformations applied:<ul> - * <li>A field is added: 'public transient Object $lombokAST = null;'. We use it to cache our own AST object, - * usually of type <code>lombok.eclipse.EclipseAST.</code></li></ul> - */ -@ProviderFor(EclipseTransformer.class) -public class EclipseCUDTransformer implements EclipseTransformer { - public byte[] transform(byte[] classfileBuffer) { - ClassReader reader = new ClassReader(classfileBuffer); - ClassWriter writer = new ClassWriter(reader, 0); - - ClassAdapter adapter = new CUDPatcherAdapter(writer); - reader.accept(adapter, 0); - return writer.toByteArray(); - } - - private static class CUDPatcherAdapter extends ClassAdapter { - CUDPatcherAdapter(ClassVisitor cv) { - super(cv); - } - - @Override public void visitEnd() { - FieldVisitor fv = cv.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_TRANSIENT, "$lombokAST", "Ljava/lang/Object;", null, null); - fv.visitEnd(); - cv.visitEnd(); - } - } - - @Override public String getTargetClassName() { - return "org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration"; - } -} diff --git a/src_eclipseagent/lombok/eclipse/agent/EclipseParserTransformer.java b/src_eclipseagent/lombok/eclipse/agent/EclipseParserTransformer.java deleted file mode 100644 index 38917332..00000000 --- a/src_eclipseagent/lombok/eclipse/agent/EclipseParserTransformer.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.eclipse.agent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import lombok.Lombok; - -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.MethodAdapter; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -/** - * Transforms Eclipse's <code>org.eclipse.jdt.internal.compiler.parser.Parser</code> class, - * which handles all the actual java source to AST tree conversion in eclipse. - * - * Transformations applied:<ul> - * <li>The <code>CompilationUnitDeclaration endParse(int)</code> method is instrumented to call - * the lombok framework via ClassLoaderWorkaround to TransformEclipseAST with the CompilationUnitDeclaration - * right before it returns the CompilationUnitDeclaration.</li> - * <li>The <code>getMethodBodies(CompilationUnitDeclaration)</code> is similarly instrumented; eclipse uses a - * 2-step parsing system, where the bodies of methods aren't filled in until its actually neccessary. Lombok - * gets a chance to change the AST immediately after either step.</li> - * <li>The <code>parse(MethodDeclaration, CUD)</code>, <code>parse(ConstructorDeclaration, CUD)</code> and - * <code>parse(Initializer, TypeDeclaration, CUD)</code> methods are all instrumented to not attempt to - * complete parsing a method generated by lombok, as the source positions are obviously all wrong - * (the method content isn't in the source file!) - lombok has already filled in the complete AST. - * - * Bit24 on the flags field on all ASTNode objects is used as a marker.</li></ul> - */ -@ProviderFor(EclipseTransformer.class) -public class EclipseParserTransformer implements EclipseTransformer { - private static final String COMPILER_PKG = - "Lorg/eclipse/jdt/internal/compiler/ast/"; - private static final String TARGET_STATIC_CLASS = "java/lombok/eclipse/ClassLoaderWorkaround"; - private static final String TARGET_STATIC_METHOD_NAME = "transformCompilationUnitDeclaration"; - private static final String TARGET_STATIC_METHOD_DESC = "(Ljava/lang/Object;Ljava/lang/Object;)V"; - - private static final Map<String, Class<? extends MethodVisitor>> rewriters; - - static { - Map<String, Class<? extends MethodVisitor>> map = new HashMap<String, Class<? extends MethodVisitor>>(); - map.put(String.format("endParse(I)%sCompilationUnitDeclaration;", COMPILER_PKG), EndParsePatcher.class); - map.put(String.format("getMethodBodies(%sCompilationUnitDeclaration;)V", COMPILER_PKG), GetMethodBodiesPatcher.class); - map.put(String.format("parse(%1$sMethodDeclaration;%1$sCompilationUnitDeclaration;)V", COMPILER_PKG), ParseBlockContainerPatcher.class); - map.put(String.format("parse(%1$sConstructorDeclaration;%1$sCompilationUnitDeclaration;Z)V", COMPILER_PKG), ParseBlockContainerPatcher.class); - map.put(String.format("parse(%1$sInitializer;%1$sTypeDeclaration;%1$sCompilationUnitDeclaration;)V", COMPILER_PKG), ParseBlockContainerPatcher.class); - rewriters = Collections.unmodifiableMap(map); - } - - public byte[] transform(byte[] classfileBuffer) { - ClassReader reader = new ClassReader(classfileBuffer); - ClassWriter writer = new ClassWriter(reader, 0); - - ClassAdapter adapter = new ParserPatcherAdapter(writer); - reader.accept(adapter, 0); - return writer.toByteArray(); - } - - private static class ParserPatcherAdapter extends ClassAdapter { - public ParserPatcherAdapter(ClassVisitor cv) { - super(cv); - } - - @Override public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - MethodVisitor writerVisitor = super.visitMethod(access, name, desc, signature, exceptions); - Class<? extends MethodVisitor> targetVisitorClass = rewriters.get(name+desc); - if ( targetVisitorClass == null ) return writerVisitor; - - try { - Constructor<? extends MethodVisitor> c = targetVisitorClass.getDeclaredConstructor(MethodVisitor.class); - c.setAccessible(true); - return c.newInstance(writerVisitor); - } catch ( InvocationTargetException e ) { - throw Lombok.sneakyThrow(e.getCause()); - } catch ( Exception e ) { - //NoSuchMethodException: We know they exist. - //IllegalAccessException: We called setAccessible. - //InstantiationException: None of these classes are abstract. - throw Lombok.sneakyThrow(e); - } - } - } - - private static final int BIT24 = 0x800000; - - static class GetMethodBodiesPatcher extends MethodAdapter { - GetMethodBodiesPatcher(MethodVisitor mv) { - super(mv); - } - - @Override public void visitInsn(int opcode) { - if ( opcode == Opcodes.RETURN ) { - //injects: ClassLoaderWorkaround.transformCUD(parser, compilationUnitDeclaration); - super.visitVarInsn(Opcodes.ALOAD, 0); - super.visitVarInsn(Opcodes.ALOAD, 1); - super.visitMethodInsn(Opcodes.INVOKESTATIC, TARGET_STATIC_CLASS, - TARGET_STATIC_METHOD_NAME, TARGET_STATIC_METHOD_DESC); - } - super.visitInsn(opcode); - } - } - - static class ParseBlockContainerPatcher extends MethodAdapter { - ParseBlockContainerPatcher(MethodVisitor mv) { - super(mv); - } - - @Override public void visitCode() { - //injects: if ( constructorDeclaration.bits & BIT24 > 0 ) return; - mv.visitVarInsn(Opcodes.ALOAD, 1); - mv.visitFieldInsn(Opcodes.GETFIELD, "org/eclipse/jdt/internal/compiler/ast/ASTNode", "bits", "I"); - mv.visitLdcInsn(Integer.valueOf(BIT24)); - mv.visitInsn(Opcodes.IAND); - Label l0 = new Label(); - mv.visitJumpInsn(Opcodes.IFLE, l0); - mv.visitInsn(Opcodes.RETURN); - mv.visitLabel(l0); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - super.visitCode(); - } - } - - static class EndParsePatcher extends MethodAdapter { - private static final String TARGET_STATIC_METHOD_NAME = "transformCompilationUnitDeclaration"; - - EndParsePatcher(MethodVisitor mv) { - super(mv); - } - - @Override public void visitInsn(int opcode) { - if ( opcode == Opcodes.ARETURN ) { - //injects: ClassLoaderWorkaround.transformCUD(parser, compilationUnitDeclaration); - super.visitInsn(Opcodes.DUP); - super.visitVarInsn(Opcodes.ALOAD, 0); - super.visitInsn(Opcodes.SWAP); - super.visitMethodInsn(Opcodes.INVOKESTATIC, TARGET_STATIC_CLASS, - TARGET_STATIC_METHOD_NAME, TARGET_STATIC_METHOD_DESC); - } - - super.visitInsn(opcode); - } - } - - @Override public String getTargetClassName() { - return "org/eclipse/jdt/internal/compiler/parser/Parser"; - } -} diff --git a/src_eclipseagent/lombok/eclipse/agent/EclipsePatcher.java b/src_eclipseagent/lombok/eclipse/agent/EclipsePatcher.java index 7659302c..c7aa48ff 100644 --- a/src_eclipseagent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src_eclipseagent/lombok/eclipse/agent/EclipsePatcher.java @@ -37,8 +37,17 @@ import java.util.jar.JarFile; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.objectweb.asm.Opcodes; + import lombok.Lombok; import lombok.core.SpiLoadUtil; +import lombok.patcher.Hook; +import lombok.patcher.MethodTarget; +import lombok.patcher.ScriptManager; +import lombok.patcher.StackRequest; +import lombok.patcher.scripts.AddFieldScript; +import lombok.patcher.scripts.ExitFromMethodEarlyScript; +import lombok.patcher.scripts.WrapReturnValuesScript; /** * This is a java-agent that patches some of eclipse's classes so AST Nodes are handed off to Lombok @@ -108,6 +117,56 @@ public class EclipsePatcher { public static void premain(String agentArgs, Instrumentation instrumentation) throws Exception { registerPatcher(instrumentation, false); addLombokToSearchPaths(instrumentation); + ScriptManager sm = new ScriptManager(); + sm.registerTransformer(instrumentation); + + sm.addScript(new WrapReturnValuesScript( + new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveStartingCatchPosition"), + new Hook("java/lombok/eclipse/PatchFixes", "fixRetrieveStartingCatchPosition", "(I)I"), + StackRequest.PARAM1)); + + sm.addScript(new AddFieldScript("org.eclipse.jdt.internal.compiler.ast.ASTNode", + Opcodes.ACC_PUBLIC | Opcodes.ACC_TRANSIENT, "$generatedBy", "Lorg/eclipse/jdt/internal/compiler/ast/ASTNode;")); + + sm.addScript(new AddFieldScript("org.eclipse.jdt.core.dom.ASTNode", + Opcodes.ACC_PUBLIC | Opcodes.ACC_TRANSIENT, "$isGenerated", "Z")); + + sm.addScript(new AddFieldScript("org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration", + Opcodes.ACC_PUBLIC | Opcodes.ACC_TRANSIENT, "$lombokAST", "Ljava/lang/Object;")); + + sm.addScript(new WrapReturnValuesScript( + new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "getMethodBodies", "void", + "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration"), + new Hook("java/lombok/eclipse/ClassLoaderWorkaround", "transformCompilationUnitDeclaration", + "(Ljava/lang/Object;Ljava/lang/Object;)V"), StackRequest.THIS, StackRequest.PARAM1)); + + sm.addScript(new WrapReturnValuesScript( + new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "endParse", + "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration", "int"), + new Hook("java/lombok/eclipse/ClassLoaderWorkaround", "transformCompilationUnitDeclarationSwapped", + "(Ljava/lang/Object;Ljava/lang/Object;)V"), StackRequest.THIS, StackRequest.RETURN_VALUE)); + + sm.addScript(new ExitFromMethodEarlyScript( + new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "parse", "void", + "org.eclipse.jdt.internal.compiler.ast.MethodDeclaration", + "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration"), + new Hook("java/lombok/eclipse/PatchFixes", "checkBit24", + "(Ljava/lang/Object;)Z"), null, StackRequest.PARAM1)); + + sm.addScript(new ExitFromMethodEarlyScript( + new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "parse", "void", + "org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration", + "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration", "boolean"), + new Hook("java/lombok/eclipse/PatchFixes", "checkBit24", + "(Ljava/lang/Object;)Z"), null, StackRequest.PARAM1)); + + sm.addScript(new ExitFromMethodEarlyScript( + new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "parse", "void", + "org.eclipse.jdt.internal.compiler.ast.Initializer", + "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", + "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration"), + new Hook("java/lombok/eclipse/PatchFixes", "checkBit24", + "(Ljava/lang/Object;)Z"), null, StackRequest.PARAM1)); } private static void registerPatcher(Instrumentation instrumentation, boolean transformExisting) throws IOException { |