'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.

This commit is contained in:
Reinier Zwitserloot committed 2010-11-10 01:27:00 +01:00
1 parent d02a0f823f
commit 2bc8ad4dfd
5 files changed
+84 -25

No files matched your search

+18 -15
View File
@@ -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);
if (!postResolution) {
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);
}
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) {
@@ -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;
+42 -7
View File
@@ -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>();
for (Element element : roundEnv.getRootElements()) {
JCCompilationUnit unit = toUnit(element);
if (unit != null) units.put(unit, null);
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();
}
transformer.transform(processingEnv.getContext(), new ArrayList<JCCompilationUnit>(units.keySet()));
for (Element element : roundEnv.getRootElements()) {
JCCompilationUnit unit = toUnit(element);
if (unit != null) {
if (!rootsAtPhase1.containsKey(unit)) rootsAtPhase0.put(unit, null);
}
}
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;
}
@@ -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;
+2 -1
View File
@@ -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;