diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2010-11-10 01:27:00 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2010-11-10 01:27:00 +0100 |
commit | 2bc8ad4dfd6e34e15f2bd7a661d62bc26cc13379 (patch) | |
tree | c95c530cc11c1e7925794204ab13d35348e079b1 | |
parent | d02a0f823fb5922ddc2e29e62cc0359be3fce0a8 (diff) | |
download | lombok-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.java | 33 | ||||
-rw-r--r-- | src/core/lombok/javac/apt/InterceptingJavaFileManager.java | 22 | ||||
-rw-r--r-- | src/core/lombok/javac/apt/Processor.java | 45 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleVal.java | 2 | ||||
-rw-r--r-- | src/delombok/lombok/delombok/Delombok.java | 3 |
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; |