diff options
-rw-r--r-- | src/core/lombok/core/AnnotationProcessor.java | 28 | ||||
-rw-r--r-- | src/core/lombok/javac/apt/LombokProcessor.java | 60 |
2 files changed, 57 insertions, 31 deletions
diff --git a/src/core/lombok/core/AnnotationProcessor.java b/src/core/lombok/core/AnnotationProcessor.java index d05597b6..04448ecb 100644 --- a/src/core/lombok/core/AnnotationProcessor.java +++ b/src/core/lombok/core/AnnotationProcessor.java @@ -49,6 +49,7 @@ import lombok.patcher.ClassRootFinder; @SupportedAnnotationTypes("*") public class AnnotationProcessor extends AbstractProcessor { + private static String trace(Throwable t) { StringWriter w = new StringWriter(); t.printStackTrace(new PrintWriter(w, true)); @@ -71,18 +72,33 @@ public class AnnotationProcessor extends AbstractProcessor { * the delegate ProcessingEnvironment of the gradle wrapper is returned. */ public static ProcessingEnvironment getJavacProcessingEnvironment(ProcessingEnvironment procEnv, List<String> delayedWarnings) { - final Class<? extends ProcessingEnvironment> procEnvClass = procEnv.getClass(); - if (procEnvClass.getName().equals("org.gradle.api.internal.tasks.compile.processing.IncrementalProcessingEnvironment")) { + ProcessingEnvironment javacProcEnv = tryRecursivelyObtainJavacProcessingEnvironment(procEnv); + + if (javacProcEnv == null) { + delayedWarnings.add("Can't get the delegate of the gradle IncrementalProcessingEnvironment."); + } + + return javacProcEnv; + } + + private static ProcessingEnvironment tryRecursivelyObtainJavacProcessingEnvironment(ProcessingEnvironment procEnv) { + if (procEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) { + return procEnv; + } + + for (Class<?> procEnvClass = procEnv.getClass(); procEnvClass != null; procEnvClass = procEnvClass.getSuperclass()) { try { Field field = procEnvClass.getDeclaredField("delegate"); field.setAccessible(true); Object delegate = field.get(procEnv); - return (ProcessingEnvironment) delegate; + + return tryRecursivelyObtainJavacProcessingEnvironment((ProcessingEnvironment) delegate); } catch (final Exception e) { - delayedWarnings.add("Can't get the delegate of the gradle IncrementalProcessingEnvironment: " + trace(e)); + // no valid delegate, try superclass } } - return procEnv; + + return null; } @@ -96,7 +112,7 @@ public class AnnotationProcessor extends AbstractProcessor { @Override boolean want(ProcessingEnvironment procEnv, List<String> delayedWarnings) { ProcessingEnvironment javacProcEnv = getJavacProcessingEnvironment(procEnv, delayedWarnings); - if (!javacProcEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) return false; + if (javacProcEnv == null) return false; try { ClassLoader classLoader = findAndPatchClassLoader(javacProcEnv); diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java index fc457735..04b494bf 100644 --- a/src/core/lombok/javac/apt/LombokProcessor.java +++ b/src/core/lombok/javac/apt/LombokProcessor.java @@ -37,7 +37,6 @@ import java.util.Set; import java.util.SortedSet; import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; @@ -70,6 +69,7 @@ import com.sun.tools.javac.util.Context; */ @SupportedAnnotationTypes("*") public class LombokProcessor extends AbstractProcessor { + private ProcessingEnvironment processingEnv; private JavacProcessingEnvironment javacProcessingEnv; private JavacFiler javacFiler; @@ -409,42 +409,52 @@ public class LombokProcessor extends AbstractProcessor { * This class casts the given processing environment to a JavacProcessingEnvironment. In case of * gradle incremental compilation, the delegate ProcessingEnvironment of the gradle wrapper is returned. */ - public JavacProcessingEnvironment getJavacProcessingEnvironment(ProcessingEnvironment procEnv) { - final Class<?> procEnvClass = procEnv.getClass(); - if (procEnv.getClass().getName().equals("org.gradle.api.internal.tasks.compile.processing.IncrementalProcessingEnvironment")) { + public JavacProcessingEnvironment getJavacProcessingEnvironment(Object procEnv) { + if (procEnv instanceof JavacProcessingEnvironment) { + return (JavacProcessingEnvironment) procEnv; + } + + // try to find a "delegate" field in the object, and use this to try to obtain a JavacProcessingEnvironment + for (Class<?> procEnvClass = procEnv.getClass(); procEnvClass != null; procEnvClass = procEnvClass.getSuperclass()) { try { - Field field = procEnvClass.getDeclaredField("delegate"); - field.setAccessible(true); - Object delegate = field.get(procEnv); - return (JavacProcessingEnvironment) delegate; + return getJavacProcessingEnvironment(tryGetDelegateField(procEnvClass, procEnv)); } catch (final Exception e) { - e.printStackTrace(); - procEnv.getMessager().printMessage(Kind.WARNING, - "Can't get the delegate of the gradle IncrementalProcessingEnvironment. Lombok won't work."); + // delegate field was not found, try on superclass } } - return (JavacProcessingEnvironment) procEnv; + + processingEnv.getMessager().printMessage(Kind.WARNING, + "Can't get the delegate of the gradle IncrementalProcessingEnvironment. Lombok won't work."); + return null; } /** - * This class casts the given filer to a JavacFiler. In case of - * gradle incremental compilation, the delegate Filer of the gradle wrapper is returned. + * This class returns the given filer as a JavacFiler. In case the case that the filer is no + * JavacFiler (e.g. the Gradle IncrementalFiler), its "delegate" field is used to get the JavacFiler + * (directly or through a delegate field again) */ - public JavacFiler getJavacFiler(Filer filer) { - final Class<?> filerSuperClass = filer.getClass().getSuperclass(); - if (filerSuperClass.getName().equals("org.gradle.api.internal.tasks.compile.processing.IncrementalFiler")) { + public JavacFiler getJavacFiler(Object filer) { + if (filer instanceof JavacFiler) { + return (JavacFiler) filer; + } + + // try to find a "delegate" field in the object, and use this to check for a JavacFiler + for (Class<?> filerClass = filer.getClass(); filerClass != null; filerClass = filerClass.getSuperclass()) { try { - Field field = filerSuperClass.getDeclaredField("delegate"); - field.setAccessible(true); - Object delegate = field.get(filer); - return (JavacFiler) delegate; + return getJavacFiler(tryGetDelegateField(filerClass, filer)); } catch (final Exception e) { - e.printStackTrace(); - processingEnv.getMessager().printMessage(Kind.WARNING, - "Can't get the delegate of the gradle IncrementalFiler. Lombok won't work."); + // delegate field was not found, try on superclass } } - return (JavacFiler) filer; + + processingEnv.getMessager().printMessage(Kind.WARNING, + "Can't get a JavacFiler from " + filer.getClass().getName() + ". Lombok won't work."); + return null; } + private Object tryGetDelegateField(Class<?> delegateClass, Object instance) throws Exception { + Field field = delegateClass.getDeclaredField("delegate"); + field.setAccessible(true); + return field.get(instance); + } } |