diff options
Diffstat (limited to 'src_eclipseagent/java/lombok/ClassLoaderWorkaround.java')
-rw-r--r-- | src_eclipseagent/java/lombok/ClassLoaderWorkaround.java | 104 |
1 files changed, 104 insertions, 0 deletions
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; + } +} |