diff options
-rwxr-xr-x | src/delombok/lombok/delombok/Delombok.java | 12 | ||||
-rw-r--r-- | test/core/src/lombok/RunTestsViaDelombok.java | 113 |
2 files changed, 123 insertions, 2 deletions
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 6b745015..6ab4d3e5 100755 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.IdentityHashMap; import java.util.LinkedHashMap; import java.util.List; @@ -51,6 +52,7 @@ import java.util.Map; import java.util.Set; import java.util.regex.Pattern; +import javax.annotation.processing.AbstractProcessor; import javax.tools.DiagnosticListener; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; @@ -59,7 +61,6 @@ import lombok.Lombok; import lombok.javac.CommentCatcher; import lombok.javac.Javac; import lombok.javac.LombokOptions; -import lombok.javac.apt.LombokProcessor; import lombok.permit.Permit; import com.sun.tools.javac.code.Symtab; @@ -97,6 +98,7 @@ public class Delombok { private LinkedHashMap<File, File> fileToBase = new LinkedHashMap<File, File>(); private List<File> filesToParse = new ArrayList<File>(); private Map<String, String> formatPrefs = new HashMap<String, String>(); + private List<AbstractProcessor> additionalAnnotationProcessors = new ArrayList<AbstractProcessor>(); /** If null, output to standard out. */ private File output = null; @@ -642,6 +644,10 @@ public class Delombok { fileToBase.put(f, base); } + public void addAdditionalAnnotationProcessor(AbstractProcessor processor) { + additionalAnnotationProcessors.add(processor); + } + private static <T> com.sun.tools.javac.util.List<T> toJavacList(List<T> list) { com.sun.tools.javac.util.List<T> out = com.sun.tools.javac.util.List.nil(); ListIterator<T> li = list.listIterator(list.size()); @@ -718,7 +724,9 @@ public class Delombok { List<JCCompilationUnit> roots = new ArrayList<JCCompilationUnit>(); Map<JCCompilationUnit, File> baseMap = new IdentityHashMap<JCCompilationUnit, File>(); - Set<LombokProcessor> processors = Collections.singleton(new lombok.javac.apt.LombokProcessor()); + Set<AbstractProcessor> processors = new HashSet<AbstractProcessor>(); + processors.add(new lombok.javac.apt.LombokProcessor()); + processors.addAll(additionalAnnotationProcessors); if (Javac.getJavaCompilerVersion() >= 9) { JavaFileManager jfm_ = context.get(JavaFileManager.class); diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java index ffac8372..433d8b07 100644 --- a/test/core/src/lombok/RunTestsViaDelombok.java +++ b/test/core/src/lombok/RunTestsViaDelombok.java @@ -21,17 +21,42 @@ */ package lombok; +import static org.junit.Assert.fail; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.PrintStream; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.Collection; +import java.util.Collections; import java.util.Locale; import java.util.Map; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; + +import com.sun.source.util.TreePath; +import com.sun.source.util.Trees; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeScanner; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCAssign; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCModifiers; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import lombok.delombok.Delombok; import lombok.javac.CapturingDiagnosticListener; +import lombok.javac.Javac; import lombok.javac.CapturingDiagnosticListener.CompilerMessage; public class RunTestsViaDelombok extends AbstractRunTests { @@ -48,6 +73,8 @@ public class RunTestsViaDelombok extends AbstractRunTests { delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, messages)); + delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor()); + delombok.addFile(file.getAbsoluteFile().getParentFile(), file.getName()); delombok.setSourcepath(file.getAbsoluteFile().getParent()); String bcp = System.getProperty("delombok.bootclasspath"); @@ -63,6 +90,92 @@ public class RunTestsViaDelombok extends AbstractRunTests { } } + public static class ValidatePositionProcessor extends TreeProcessor { + @Override void processCompilationUnit(final JCCompilationUnit unit) { + unit.accept(new TreeScanner() { + @Override public void scan(JCTree tree) { + if (tree == null) return; + if (tree instanceof JCMethodDecl && (((JCMethodDecl) tree).mods.flags & Flags.GENERATEDCONSTR) != 0) return; + try { + if (tree instanceof JCModifiers) return; + + if (tree.pos == -1) { + fail("Start position of " + tree + " not set"); + } + if (Javac.getEndPosition(tree, unit) == -1) { + fail("End position of " + tree + " not set"); + } + } finally { + super.scan(tree); + } + } + + @Override public void visitMethodDef(JCMethodDecl tree) { + super.visitMethodDef(tree); + } + + @Override public void visitVarDef(JCVariableDecl tree) { + if ((tree.mods.flags & Flags.ENUM) != 0) return; + super.visitVarDef(tree); + } + + @Override public void visitAnnotation(JCAnnotation tree) { + scan(tree.annotationType); + // Javac parser maps @Annotation("val") to @Annotation(value = "val") but does not add an end position for the new JCIdent... + if (tree.args.length() == 1 && tree.args.head instanceof JCAssign && ((JCIdent)((JCAssign) tree.args.head).lhs).name.toString().equals("value")) { + scan(((JCAssign) tree.args.head).rhs); + } else { + scan(tree.args); + } + } + }); + } + } + + public static abstract class TreeProcessor extends AbstractProcessor { + private Trees trees; + @Override public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + trees = Trees.instance(processingEnv); + } + + @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + for (Element element : roundEnv.getRootElements()) { + JCCompilationUnit unit = toUnit(element); + if (unit != null) { + processCompilationUnit(unit); + } + } + return false; + } + + abstract void processCompilationUnit(JCCompilationUnit unit); + + @Override public Set<String> getSupportedAnnotationTypes() { + return Collections.singleton("*"); + } + + @Override public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + private JCCompilationUnit toUnit(Element element) { + TreePath path = null; + if (trees != null) { + try { + path = trees.getPath(element); + } catch (NullPointerException ignore) { + // Happens if a package-info.java dowsn't conatin a package declaration. + // https://github.com/rzwitserloot/lombok/issues/2184 + // We can safely ignore those, since they do not need any processing + } + } + if (path == null) return null; + + return (JCCompilationUnit) path.getCompilationUnit(); + } + } + static class ChangedChecker { private final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); private final PrintStream feedback; |