From 41fb7cba62b543243c784757d1af4e05824ddc4e Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 9 Jun 2009 18:27:10 +0200 Subject: Many changes: - Split off the actual agent work into a separate src package in preparation for creating separate jars. Involved a lot of renaming - Renamed TransformCompilationUnitDeclaration to TransformEclipseAST, as this class will also be transforming e.g. MethodDeclaration objects. - Expanded the patching to also patch in transform calls when the parser fills in the Statement array for existing constructors, methods, and initializers. - Redesigned the ClassLoaderWorkaround class quite a bit. - Positioning should not work correctly ('jump to method' should jump to the getter annotation). (Apparently, Clinit objects are always fully parsed in the original run, so no need to patch anything there). --- .../java/lombok/ClassLoaderWorkaround.java | 104 +++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src_eclipseagent/java/lombok/ClassLoaderWorkaround.java (limited to 'src_eclipseagent/java') diff --git a/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java b/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java new file mode 100644 index 00000000..0238b592 --- /dev/null +++ b/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java @@ -0,0 +1,104 @@ +package java.lombok; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +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. + * + * Example: Injecting lombok's Eclipse Parser patching code into eclipse's OSGi BundleLoader. + * + * @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); + } + + public static void transformMethodDeclaration(Object parser, Object methodDeclaration) throws Exception { + initialize(methodDeclaration); + transformMethodDeclaration.invoke(null, parser, methodDeclaration); + } + + public static void transformConstructorDeclaration(Object parser, Object constructorDeclaration) throws Exception { + initialize(constructorDeclaration); + transformConstructorDeclaration.invoke(null, parser, constructorDeclaration); + } + + public static void transformInitializer(Object parser, Object initializer) throws Exception { + initialize(initializer); + transformInitializer.invoke(null, parser, initializer); + } + + private static void initialize(Object cud) throws ClassNotFoundException { + if ( initialized ) { + if ( transformInitializer == null ) throw new ClassNotFoundException("lombok.eclipse.TransformEclipseAST"); + return; + } + + final ClassLoader parent = cud.getClass().getClassLoader(); + ClassLoader loader = new ClassLoader() { + @Override public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + if ( name.startsWith("lombok.") ) { + InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/") + ".class"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + byte[] b = new byte[65536]; + try { + while ( true ) { + int r = in.read(b); + if ( r == -1 ) break; + if ( r > 0 ) out.write(b, 0, r); + } + + in.close(); + byte[] data = out.toByteArray(); + Class result = defineClass(name, data, 0, data.length); + if ( resolve ) resolveClass(result); + return result; + } catch ( IOException e ) { + throw new ClassNotFoundException(); + } + } else { + try { + Class result = ClassLoader.getSystemClassLoader().loadClass(name); + if ( resolve ) resolveClass(result); + return result; + } catch ( ClassNotFoundException e ) { + Class result = parent.loadClass(name); + if ( resolve ) resolveClass(result); + return result; + } + } + } + }; + + try { + 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; + } + } + } + } catch ( ClassNotFoundException ignore ) {} + initialized = true; + } +} -- cgit