mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 18:15:55 +00:00
'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:
1 parent
d02a0f823f
commit
2bc8ad4dfd
5 files changed
+84
-25
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user