aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/core/lombok/javac/JavacTransformer.java33
-rw-r--r--src/core/lombok/javac/apt/InterceptingJavaFileManager.java22
-rw-r--r--src/core/lombok/javac/apt/Processor.java45
-rw-r--r--src/core/lombok/javac/handlers/HandleVal.java2
-rw-r--r--src/delombok/lombok/delombok/Delombok.java3
5 files changed, 82 insertions, 23 deletions
diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java
index 5d1e79af..e90f780b 100644
--- a/src/core/lombok/javac/JavacTransformer.java
+++ b/src/core/lombok/javac/JavacTransformer.java
@@ -42,7 +42,7 @@ public class JavacTransformer {
this.handlers = HandlerLibrary.load(messager);
}
- public boolean transform(Context context, java.util.List<JCCompilationUnit> compilationUnitsRaw) {
+ public boolean transform(boolean postResolution, Context context, java.util.List<JCCompilationUnit> compilationUnitsRaw) {
List<JCCompilationUnit> compilationUnits;
if (compilationUnitsRaw instanceof List<?>) {
compilationUnits = (List<JCCompilationUnit>)compilationUnitsRaw;
@@ -57,22 +57,25 @@ public class JavacTransformer {
for (JCCompilationUnit unit : compilationUnits) asts.add(new JavacAST(messager, context, unit));
- handlers.setPreResolutionPhase();
- for (JavacAST ast : asts) {
- ast.traverse(new AnnotationVisitor());
- handlers.callASTVisitors(ast);
- }
-
- handlers.setPostResolutionPhase();
- for (JavacAST ast : asts) {
- ast.traverse(new AnnotationVisitor());
- handlers.callASTVisitors(ast);
+ if (!postResolution) {
+ handlers.setPreResolutionPhase();
+ for (JavacAST ast : asts) {
+ ast.traverse(new AnnotationVisitor());
+ handlers.callASTVisitors(ast);
+ }
}
-
- handlers.setPrintASTPhase();
- for (JavacAST ast : asts) {
- ast.traverse(new AnnotationVisitor());
+ if (postResolution) {
+ handlers.setPostResolutionPhase();
+ for (JavacAST ast : asts) {
+ ast.traverse(new AnnotationVisitor());
+ handlers.callASTVisitors(ast);
+ }
+
+ handlers.setPrintASTPhase();
+ for (JavacAST ast : asts) {
+ ast.traverse(new AnnotationVisitor());
+ }
}
for (JavacAST ast : asts) {
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;
}
diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java
index 983f2d86..bf938362 100644
--- a/src/core/lombok/javac/handlers/HandleVal.java
+++ b/src/core/lombok/javac/handlers/HandleVal.java
@@ -31,10 +31,8 @@ import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCNewArray;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index 846b448f..95ceb309 100644
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -384,7 +384,8 @@ public class Delombok {
for (JCCompilationUnit unit : roots) {
// Run one single massive transform instead of a lot of singleton calls, as this causes a heck of a lot of refilling of the enter cache.
- boolean changed = new JavacTransformer(messager).transform(context, Collections.singletonList(unit));
+ // XXX This isn't enough - we need to call transform again after resetting everything.
+ boolean changed = new JavacTransformer(messager).transform(false, context, Collections.singletonList(unit));
DelombokResult result = new DelombokResult(commentsMap.get(unit).comments, unit, force || changed);
if (verbose) feedback.printf("File: %s [%s]\n", unit.sourcefile.getName(), result.isChanged() ? "delomboked" : "unchanged");
Writer rawWriter;