aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac/apt
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2010-11-10 01:27:00 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2010-11-10 01:27:00 +0100
commit2bc8ad4dfd6e34e15f2bd7a661d62bc26cc13379 (patch)
treec95c530cc11c1e7925794204ab13d35348e079b1 /src/core/lombok/javac/apt
parentd02a0f823fb5922ddc2e29e62cc0359be3fce0a8 (diff)
downloadlombok-2bc8ad4dfd6e34e15f2bd7a661d62bc26cc13379.tar.gz
lombok-2bc8ad4dfd6e34e15f2bd7a661d62bc26cc13379.tar.bz2
lombok-2bc8ad4dfd6e34e15f2bd7a661d62bc26cc13379.zip
'val' now fully works on javac, even when referring to lombok-generated code, by (ab)using the annotation processor's round system. This breaks delombok though. That'll have to be fixed next.
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.java45
2 files changed, 62 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 58631c66..b5d5c81c 100644
--- a/src/core/lombok/javac/apt/Processor.java
+++ b/src/core/lombok/javac/apt/Processor.java
@@ -23,6 +23,7 @@ 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;
@@ -41,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;
@@ -49,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;
@@ -75,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();
@@ -101,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);
@@ -165,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(), new ArrayList<JCCompilationUnit>(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;
}