diff options
author | Reinier Zwitserloot <reinier@tipit.to> | 2009-06-12 03:40:07 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@tipit.to> | 2009-06-12 03:40:07 +0200 |
commit | e84bdd32e71b029d8d1f2fa7849e998953984f47 (patch) | |
tree | d3e7ff61b9d1b84de36b5d41496f5436d853d114 /src_eclipseagent | |
parent | 4c18c774fc60eca7e104b3eaa5535ce94ec66198 (diff) | |
download | lombok-e84bdd32e71b029d8d1f2fa7849e998953984f47.tar.gz lombok-e84bdd32e71b029d8d1f2fa7849e998953984f47.tar.bz2 lombok-e84bdd32e71b029d8d1f2fa7849e998953984f47.zip |
Singularly massive code change, too hard to document. Basically, hooking now occurs in the two most sane places:
- After the parser is done building a first rendition of the AST. (Usually lightweight and missing method bodies etc)
- After the parser is done taking such a lightweight AST and filling in the gaps.
Lombok then builts its own bidirectional and somewhat saner AST out of this, and hands this saner AST off for treatment. Things in the AST can be marked as 'handled'.
This seems to work swimmingly and should allow us to easily identify the annotations that are for us, and work our magic, no matter where they appear or on what, including
stuff inside method bodies.
Diffstat (limited to 'src_eclipseagent')
-rw-r--r-- | src_eclipseagent/java/lombok/ClassLoaderWorkaround.java | 49 | ||||
-rw-r--r-- | src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java | 59 |
2 files changed, 43 insertions, 65 deletions
diff --git a/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java b/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java index 0238b592..a3fc1521 100644 --- a/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java +++ b/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java @@ -3,8 +3,10 @@ package java.lombok; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; + /** * Allows you to inject the lombok classes into any classloader, even if that classloader does not * know how to find the lombok classes. @@ -14,35 +16,32 @@ import java.lang.reflect.Method; * @author rzwitserloot */ public class ClassLoaderWorkaround { - private static boolean initialized; - private static Method transformCompilationUnitDeclaration; - private static Method transformMethodDeclaration; - private static Method transformConstructorDeclaration; - private static Method transformInitializer; - - public static void transformCompilationUnitDeclaration(Object parser, Object cud) throws Exception { - initialize(cud); - transformCompilationUnitDeclaration.invoke(null, parser, cud); + static RuntimeException sneakyThrow(Throwable t) { + if ( t == null ) throw new NullPointerException("t"); + ClassLoaderWorkaround.<RuntimeException>sneakyThrow0(t); + return null; } - public static void transformMethodDeclaration(Object parser, Object methodDeclaration) throws Exception { - initialize(methodDeclaration); - transformMethodDeclaration.invoke(null, parser, methodDeclaration); + @SuppressWarnings("unchecked") + private static <T extends Throwable> void sneakyThrow0(Throwable t) throws T { + throw (T)t; } - public static void transformConstructorDeclaration(Object parser, Object constructorDeclaration) throws Exception { - initialize(constructorDeclaration); - transformConstructorDeclaration.invoke(null, parser, constructorDeclaration); - } + private static boolean initialized; + private static Method transform; - public static void transformInitializer(Object parser, Object initializer) throws Exception { - initialize(initializer); - transformInitializer.invoke(null, parser, initializer); + public static void transformCompilationUnitDeclaration(Object parser, Object cud) throws Exception { + initialize(cud); + try { + transform.invoke(null, parser, cud); + } catch ( InvocationTargetException e ) { + throw sneakyThrow(e.getCause()); + } } private static void initialize(Object cud) throws ClassNotFoundException { if ( initialized ) { - if ( transformInitializer == null ) throw new ClassNotFoundException("lombok.eclipse.TransformEclipseAST"); + if ( transform == null ) throw new ClassNotFoundException("lombok.eclipse.TransformEclipseAST"); return; } @@ -87,15 +86,7 @@ public class ClassLoaderWorkaround { Class<?> c = loader.loadClass("lombok.eclipse.TransformEclipseAST"); for ( Method m : c.getMethods() ) { if ( m.getName().equals("transform") ) { - if ( m.getParameterTypes().length >= 2 ) { - Class<?> astType = m.getParameterTypes()[1]; - String astName = astType.getName(); - astName = astName.substring(astName.lastIndexOf('.') + 1); - if ( astName.equals("CompilationUnitDeclaration") ) transformCompilationUnitDeclaration = m; - else if ( astName.equals("MethodDeclaration") ) transformMethodDeclaration = m; - else if ( astName.equals("ConstructorDeclaration") ) transformConstructorDeclaration = m; - else if ( astName.equals("Initializer") ) transformInitializer = m; - } + transform = m; } } } catch ( ClassNotFoundException ignore ) {} diff --git a/src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java b/src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java index c0e64061..4a1b4a01 100644 --- a/src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java +++ b/src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java @@ -19,6 +19,7 @@ class EclipseParserTransformer { private static final String COMPILER_PKG = "Lorg/eclipse/jdt/internal/compiler/ast/"; private static final String TARGET_STATIC_CLASS = "java/lombok/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; @@ -26,9 +27,10 @@ class EclipseParserTransformer { 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("parse(%1$sMethodDeclaration;%1$sCompilationUnitDeclaration;)V", COMPILER_PKG), ParseMethodPatcher.class); - map.put(String.format("parse(%1$sConstructorDeclaration;%1$sCompilationUnitDeclaration;Z)V", COMPILER_PKG), ParseConstructorPatcher.class); - map.put(String.format("parse(%1$sInitializer;%1$sTypeDeclaration;%1$sCompilationUnitDeclaration;)V", COMPILER_PKG), ParseInitializerPatcher.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); } @@ -85,12 +87,26 @@ class EclipseParserTransformer { private static final int BIT24 = 0x800000; - static class ParseBlockContainerPatcher extends MethodAdapter { - private final String staticMethodName; + static class GetMethodBodiesPatcher extends MethodAdapter { + GetMethodBodiesPatcher(MethodVisitor mv) { + super(mv); + } - ParseBlockContainerPatcher(MethodVisitor mv, String staticMethodName) { + @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); - this.staticMethodName = staticMethodName; } @Override public void visitCode() { @@ -106,35 +122,6 @@ class EclipseParserTransformer { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); super.visitCode(); } - - @Override public void visitInsn(int opcode) { - if ( opcode == Opcodes.RETURN ) { - //injects: ClassLoaderWorkaround.transformConstructorDeclaration(parser, constructorDeclaration); - super.visitVarInsn(Opcodes.ALOAD, 0); - super.visitVarInsn(Opcodes.ALOAD, 1); - super.visitMethodInsn(Opcodes.INVOKESTATIC, TARGET_STATIC_CLASS, - staticMethodName, TARGET_STATIC_METHOD_DESC); - } - super.visitInsn(opcode); - } - } - - static class ParseConstructorPatcher extends ParseBlockContainerPatcher { - public ParseConstructorPatcher(MethodVisitor mv) { - super(mv, "transformConstructorDeclaration"); - } - } - - static class ParseMethodPatcher extends ParseBlockContainerPatcher { - public ParseMethodPatcher(MethodVisitor mv) { - super(mv, "transformMethodDeclaration"); - } - } - - static class ParseInitializerPatcher extends ParseBlockContainerPatcher { - public ParseInitializerPatcher(MethodVisitor mv) { - super(mv, "transformInitializer"); - } } static class EndParsePatcher extends MethodAdapter { |