aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac/apt
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/javac/apt')
-rw-r--r--src/core/lombok/javac/apt/InterceptingJavaFileManager.java22
-rw-r--r--src/core/lombok/javac/apt/Processor.java46
2 files changed, 63 insertions, 5 deletions
diff --git a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java
index 2b570eb0..738804ea 100644
--- a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java
+++ b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java
@@ -21,13 +21,19 @@
*/
package lombok.javac.apt;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
import java.util.Iterator;
import java.util.Set;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
import javax.tools.JavaFileObject.Kind;
import lombok.core.DiagnosticsReceiver;
@@ -42,6 +48,22 @@ final class InterceptingJavaFileManager implements JavaFileManager {
}
@Override public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
+ if (className.startsWith("lombok.dummy.ForceNewRound")) {
+ String name = className.replace(".", "/") + kind.extension;
+ return new SimpleJavaFileObject(URI.create(name), kind) {
+ @Override public OutputStream openOutputStream() throws IOException {
+ return new ByteArrayOutputStream();
+ }
+
+ @Override public InputStream openInputStream() throws IOException {
+ return new ByteArrayInputStream(new byte[0]);
+ }
+
+ @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return "";
+ }
+ };
+ }
JavaFileObject fileObject = delegate.getJavaFileForOutput(location, className, kind, sibling);
if (kind != Kind.CLASS) {
return fileObject;
diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java
index 037f5ba5..b5d5c81c 100644
--- a/src/core/lombok/javac/apt/Processor.java
+++ b/src/core/lombok/javac/apt/Processor.java
@@ -23,9 +23,11 @@ package lombok.javac.apt;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -40,7 +42,9 @@ import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic.Kind;
import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
import lombok.Lombok;
import lombok.core.DiagnosticsReceiver;
@@ -48,6 +52,7 @@ import lombok.javac.JavacTransformer;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
+import com.sun.tools.javac.processing.JavacFiler;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
@@ -74,12 +79,12 @@ public class Processor extends AbstractProcessor {
@Override public void init(ProcessingEnvironment procEnv) {
super.init(procEnv);
this.processingEnv = (JavacProcessingEnvironment) procEnv;
- placePostCompileHook();
+ placePostCompileAndDontMakeForceRoundDummiesHook();
transformer = new JavacTransformer(procEnv.getMessager());
trees = Trees.instance(procEnv);
}
- private void placePostCompileHook() {
+ private void placePostCompileAndDontMakeForceRoundDummiesHook() {
stopJavacProcessingEnvironmentFromClosingOurClassloader();
Context context = processingEnv.getContext();
@@ -100,6 +105,9 @@ public class Processor extends AbstractProcessor {
JavaFileManager newFiler = new InterceptingJavaFileManager(originalFiler, receiver);
ht.put(key, newFiler);
+ Field filerFileManagerField = JavacFiler.class.getDeclaredField("fileManager");
+ filerFileManagerField.setAccessible(true);
+ filerFileManagerField.set(processingEnv.getFiler(), newFiler);
}
} catch (Exception e) {
throw Lombok.sneakyThrow(e);
@@ -164,15 +172,43 @@ public class Processor extends AbstractProcessor {
}
}
+ private final IdentityHashMap<JCCompilationUnit, Void> rootsAtPhase0 = new IdentityHashMap<JCCompilationUnit, Void>();
+ private final IdentityHashMap<JCCompilationUnit, Void> rootsAtPhase1 = new IdentityHashMap<JCCompilationUnit, Void>();
+ private int dummyCount = 0;
+
/** {@inheritDoc} */
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- IdentityHashMap<JCCompilationUnit, Void> units = new IdentityHashMap<JCCompilationUnit, Void>();
+ if (roundEnv.processingOver()) return false;
+
+ if (!rootsAtPhase0.isEmpty()) {
+ ArrayList<JCCompilationUnit> cus = new ArrayList<JCCompilationUnit>(rootsAtPhase0.keySet());
+ transformer.transform(true, processingEnv.getContext(), cus);
+ rootsAtPhase1.putAll(rootsAtPhase0);
+ rootsAtPhase0.clear();
+ }
+
for (Element element : roundEnv.getRootElements()) {
JCCompilationUnit unit = toUnit(element);
- if (unit != null) units.put(unit, null);
+ if (unit != null) {
+ if (!rootsAtPhase1.containsKey(unit)) rootsAtPhase0.put(unit, null);
+ }
}
- transformer.transform(processingEnv.getContext(), units.keySet());
+ if (!rootsAtPhase0.isEmpty()) {
+ ArrayList<JCCompilationUnit> cus = new ArrayList<JCCompilationUnit>(rootsAtPhase0.keySet());
+ transformer.transform(false, processingEnv.getContext(), cus);
+ JavacFiler filer = (JavacFiler) processingEnv.getFiler();
+ if (!filer.newFiles()) {
+ try {
+ JavaFileObject dummy = filer.createSourceFile("lombok.dummy.ForceNewRound" + (dummyCount++));
+ Writer w = dummy.openWriter();
+ w.close();
+ } catch (Exception e) {
+ processingEnv.getMessager().printMessage(Kind.WARNING,
+ "Can't force a new processing round. Lombok features that require resolution won't work.");
+ }
+ }
+ }
return false;
}