aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorPascal Bihler <pascal@qfs.de>2018-05-03 11:57:01 +0200
committerPascal Bihler <pascal@qfs.de>2018-05-03 12:09:12 +0200
commita2623f1965848cb941374f70ae008f56d7738736 (patch)
treec314f6c57124d3facb362661a1f6eb148f1c4ff4 /src/core
parenta9aafe2d794b7c0aacb37c7b4e6ba1ec359dc2a9 (diff)
downloadlombok-a2623f1965848cb941374f70ae008f56d7738736.tar.gz
lombok-a2623f1965848cb941374f70ae008f56d7738736.tar.bz2
lombok-a2623f1965848cb941374f70ae008f56d7738736.zip
Allow gradle incremental compiling with lombok in annotation processor path
Fixes issue #1580
Diffstat (limited to 'src/core')
-rw-r--r--src/core/lombok/core/AnnotationProcessor.java30
-rw-r--r--src/core/lombok/javac/apt/LombokProcessor.java84
2 files changed, 93 insertions, 21 deletions
diff --git a/src/core/lombok/core/AnnotationProcessor.java b/src/core/lombok/core/AnnotationProcessor.java
index 5b4ef393..d05597b6 100644
--- a/src/core/lombok/core/AnnotationProcessor.java
+++ b/src/core/lombok/core/AnnotationProcessor.java
@@ -26,6 +26,7 @@ import static lombok.core.Augments.ClassLoader_lombokAlreadyAddedTo;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
@@ -63,6 +64,27 @@ public class AnnotationProcessor extends AbstractProcessor {
private final List<ProcessorDescriptor> registered = Arrays.asList(new JavacDescriptor(), new EcjDescriptor());
private final List<ProcessorDescriptor> active = new ArrayList<ProcessorDescriptor>();
private final List<String> delayedWarnings = new ArrayList<String>();
+
+ /**
+ * This method is a simplified version of {@link lombok.javac.apt.LombokProcessor.getJavacProcessingEnvironment}
+ * It simply returns the processing environment, but in case of gradle incremental compilation,
+ * 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")) {
+ try {
+ Field field = procEnvClass.getDeclaredField("delegate");
+ field.setAccessible(true);
+ Object delegate = field.get(procEnv);
+ return (ProcessingEnvironment) delegate;
+ } catch (final Exception e) {
+ delayedWarnings.add("Can't get the delegate of the gradle IncrementalProcessingEnvironment: " + trace(e));
+ }
+ }
+ return procEnv;
+ }
+
static class JavacDescriptor extends ProcessorDescriptor {
private Processor processor;
@@ -72,10 +94,12 @@ public class AnnotationProcessor extends AbstractProcessor {
}
@Override boolean want(ProcessingEnvironment procEnv, List<String> delayedWarnings) {
- if (!procEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) return false;
-
+ ProcessingEnvironment javacProcEnv = getJavacProcessingEnvironment(procEnv, delayedWarnings);
+
+ if (!javacProcEnv.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment")) return false;
+
try {
- ClassLoader classLoader = findAndPatchClassLoader(procEnv);
+ ClassLoader classLoader = findAndPatchClassLoader(javacProcEnv);
processor = (Processor) Class.forName("lombok.javac.apt.LombokProcessor", false, classLoader).newInstance();
} catch (Exception e) {
delayedWarnings.add("You found a bug in lombok; lombok.javac.apt.LombokProcessor is not available. Lombok will not run during this compilation: " + trace(e));
diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java
index 9c0a2dfa..fc457735 100644
--- a/src/core/lombok/javac/apt/LombokProcessor.java
+++ b/src/core/lombok/javac/apt/LombokProcessor.java
@@ -37,6 +37,7 @@ 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;
@@ -69,7 +70,9 @@ import com.sun.tools.javac.util.Context;
*/
@SupportedAnnotationTypes("*")
public class LombokProcessor extends AbstractProcessor {
- private JavacProcessingEnvironment processingEnv;
+ private ProcessingEnvironment processingEnv;
+ private JavacProcessingEnvironment javacProcessingEnv;
+ private JavacFiler javacFiler;
private JavacTransformer transformer;
private Trees trees;
private boolean lombokDisabled = false;
@@ -81,11 +84,13 @@ public class LombokProcessor extends AbstractProcessor {
lombokDisabled = true;
return;
}
-
- this.processingEnv = (JavacProcessingEnvironment) procEnv;
-
+
+ this.processingEnv = procEnv;
+ this.javacProcessingEnv = getJavacProcessingEnvironment(procEnv);
+ this.javacFiler = getJavacFiler(procEnv.getFiler());
+
placePostCompileAndDontMakeForceRoundDummiesHook();
- trees = Trees.instance(procEnv);
+ trees = Trees.instance(javacProcessingEnv);
transformer = new JavacTransformer(procEnv.getMessager(), trees);
SortedSet<Long> p = transformer.getPriorities();
if (p.isEmpty()) {
@@ -124,7 +129,7 @@ public class LombokProcessor extends AbstractProcessor {
@SuppressWarnings("unused")
private String listAnnotationProcessorsBeforeOurs() {
try {
- Object discoveredProcessors = javacProcessingEnvironment_discoveredProcs.get(this.processingEnv);
+ Object discoveredProcessors = javacProcessingEnvironment_discoveredProcs.get(this.javacProcessingEnv);
ArrayList<?> states = (ArrayList<?>) discoveredProcessors_procStateList.get(discoveredProcessors);
if (states == null || states.isEmpty()) return null;
if (states.size() == 1) return processorState_processor.get(states.get(0)).getClass().getName();
@@ -147,7 +152,7 @@ public class LombokProcessor extends AbstractProcessor {
stopJavacProcessingEnvironmentFromClosingOurClassloader();
forceMultipleRoundsInNetBeansEditor();
- Context context = processingEnv.getContext();
+ Context context = javacProcessingEnv.getContext();
disablePartialReparseInNetBeansEditor(context);
try {
Method keyMethod = Context.class.getDeclaredMethod("key", Class.class);
@@ -161,14 +166,14 @@ public class LombokProcessor extends AbstractProcessor {
if (!(originalFiler instanceof InterceptingJavaFileManager)) {
final Messager messager = processingEnv.getMessager();
DiagnosticsReceiver receiver = new MessagerDiagnosticsReceiver(messager);
-
- JavaFileManager newFiler = new InterceptingJavaFileManager(originalFiler, receiver);
- ht.put(key, newFiler);
+
+ JavaFileManager newFilerManager = new InterceptingJavaFileManager(originalFiler, receiver);
+ ht.put(key, newFilerManager);
Field filerFileManagerField = JavacFiler.class.getDeclaredField("fileManager");
filerFileManagerField.setAccessible(true);
- filerFileManagerField.set(processingEnv.getFiler(), newFiler);
-
- replaceFileManagerJdk9(context, newFiler);
+ filerFileManagerField.set(javacFiler, newFilerManager);
+
+ replaceFileManagerJdk9(context, newFilerManager);
}
} catch (Exception e) {
throw Lombok.sneakyThrow(e);
@@ -203,7 +208,7 @@ public class LombokProcessor extends AbstractProcessor {
try {
Field f = JavacProcessingEnvironment.class.getDeclaredField("isBackgroundCompilation");
f.setAccessible(true);
- f.set(processingEnv, true);
+ f.set(javacProcessingEnv, true);
} catch (NoSuchFieldException e) {
// only NetBeans has it
} catch (Throwable t) {
@@ -277,10 +282,10 @@ public class LombokProcessor extends AbstractProcessor {
try {
Field f = JavacProcessingEnvironment.class.getDeclaredField("processorClassLoader");
f.setAccessible(true);
- ClassLoader unwrapped = (ClassLoader) f.get(processingEnv);
+ ClassLoader unwrapped = (ClassLoader) f.get(javacProcessingEnv);
if (unwrapped == null) return;
ClassLoader wrapped = wrapClassLoader(unwrapped);
- f.set(processingEnv, wrapped);
+ f.set(javacProcessingEnv, wrapped);
} catch (NoSuchFieldException e) {
// Some versions of javac have this (and call close on it), some don't. I guess this one doesn't have it.
} catch (Throwable t) {
@@ -321,7 +326,7 @@ public class LombokProcessor extends AbstractProcessor {
if (prioOfCu == null || prioOfCu != prio) continue;
cusForThisRound.add(entry.getKey());
}
- transformer.transform(prio, processingEnv.getContext(), cusForThisRound);
+ transformer.transform(prio, javacProcessingEnv.getContext(), cusForThisRound);
}
// Step 3: Push up all CUs to the next level. Set level to null if there is no next level.
@@ -349,7 +354,7 @@ public class LombokProcessor extends AbstractProcessor {
newLevels.retainAll(priorityLevelsRequiringResolutionReset);
if (!newLevels.isEmpty()) {
// Force a new round to reset resolution. The next round will cause this method (process) to be called again.
- forceNewRound(randomModuleName, (JavacFiler) processingEnv.getFiler());
+ forceNewRound(randomModuleName, javacFiler);
return false;
}
// None of the new levels need resolution, so just keep going.
@@ -399,4 +404,47 @@ public class LombokProcessor extends AbstractProcessor {
@Override public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
+
+ /**
+ * 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")) {
+ try {
+ Field field = procEnvClass.getDeclaredField("delegate");
+ field.setAccessible(true);
+ Object delegate = field.get(procEnv);
+ return (JavacProcessingEnvironment) delegate;
+ } catch (final Exception e) {
+ e.printStackTrace();
+ procEnv.getMessager().printMessage(Kind.WARNING,
+ "Can't get the delegate of the gradle IncrementalProcessingEnvironment. Lombok won't work.");
+ }
+ }
+ return (JavacProcessingEnvironment) procEnv;
+ }
+
+ /**
+ * This class casts the given filer to a JavacFiler. In case of
+ * gradle incremental compilation, the delegate Filer of the gradle wrapper is returned.
+ */
+ public JavacFiler getJavacFiler(Filer filer) {
+ final Class<?> filerSuperClass = filer.getClass().getSuperclass();
+ if (filerSuperClass.getName().equals("org.gradle.api.internal.tasks.compile.processing.IncrementalFiler")) {
+ try {
+ Field field = filerSuperClass.getDeclaredField("delegate");
+ field.setAccessible(true);
+ Object delegate = field.get(filer);
+ return (JavacFiler) delegate;
+ } catch (final Exception e) {
+ e.printStackTrace();
+ processingEnv.getMessager().printMessage(Kind.WARNING,
+ "Can't get the delegate of the gradle IncrementalFiler. Lombok won't work.");
+ }
+ }
+ return (JavacFiler) filer;
+ }
+
}