diff options
Diffstat (limited to 'test')
7 files changed, 212 insertions, 28 deletions
diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java index ffac8372..d4df50d7 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,96 @@ 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 (!Javac.validateDocComment(unit, tree)) { + fail("Start position of doc comment (" + Javac.getDocComment(unit, tree) + ") of " + tree + " not set"); + } + + 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; diff --git a/test/transform/resource/after-delombok/CheckerFrameworkSuperBuilder.java b/test/transform/resource/after-delombok/CheckerFrameworkSuperBuilder.java index 919a3e33..e1ac7c00 100644 --- a/test/transform/resource/after-delombok/CheckerFrameworkSuperBuilder.java +++ b/test/transform/resource/after-delombok/CheckerFrameworkSuperBuilder.java @@ -1,4 +1,3 @@ -// skip-idempotent import java.util.List; class CheckerFrameworkSuperBuilder { public static class Parent { @@ -128,7 +127,7 @@ class CheckerFrameworkSuperBuilder { } @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") - public static CheckerFrameworkSuperBuilder.Parent.ParentBuilder<?, ?> builder() { + public static CheckerFrameworkSuperBuilder.Parent.@org.checkerframework.common.aliasing.qual.Unique ParentBuilder<?, ?> builder() { return new CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl(); } } @@ -211,7 +210,7 @@ class CheckerFrameworkSuperBuilder { } @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") - public static CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<?, ?> builder() { + public static CheckerFrameworkSuperBuilder.ZChild.@org.checkerframework.common.aliasing.qual.Unique ZChildBuilder<?, ?> builder() { return new CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl(); } } diff --git a/test/transform/resource/after-delombok/DataWithOverrideEqualsAndHashCode.java b/test/transform/resource/after-delombok/DataWithOverrideEqualsAndHashCode.java new file mode 100644 index 00000000..7e84dda4 --- /dev/null +++ b/test/transform/resource/after-delombok/DataWithOverrideEqualsAndHashCode.java @@ -0,0 +1,25 @@ +class DataWithOverrideEqualsAndHashCode { + + class Data1 { + } + + class Data2 extends Data1 { + public int hashCode() { + return 42; + } + + public boolean equals(Object other) { + return false; + } + + @java.lang.SuppressWarnings("all") + public Data2() { + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "DataWithOverrideEqualsAndHashCode.Data2()"; + } + } +} diff --git a/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java b/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java index 1c552fcc..6236fc72 100644 --- a/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java +++ b/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java @@ -78,7 +78,7 @@ class CheckerFrameworkSuperBuilder { private static @java.lang.SuppressWarnings("all") int $default$x() { return 5; } - protected @java.lang.SuppressWarnings("all") Parent(final CheckerFrameworkSuperBuilder.Parent.ParentBuilder<?, ?> b) { + protected @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") Parent(final CheckerFrameworkSuperBuilder.Parent.ParentBuilder<?, ?> b) { super(); if (b.x$set) this.x = b.x$value; @@ -99,7 +99,7 @@ class CheckerFrameworkSuperBuilder { } this.names = names; } - public static @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent. @org.checkerframework.common.aliasing.qual.Unique ParentBuilder<?, ?> builder() { + public static @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent. @org.checkerframework.common.aliasing.qual.Unique ParentBuilder<?, ?> builder() { return new CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl(); } } @@ -148,7 +148,7 @@ class CheckerFrameworkSuperBuilder { private static @java.lang.SuppressWarnings("all") int $default$a() { return 1; } - protected @java.lang.SuppressWarnings("all") ZChild(final CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<?, ?> b) { + protected @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") ZChild(final CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<?, ?> b) { super(b); if (b.a$set) this.a = b.a$value; @@ -156,7 +156,7 @@ class CheckerFrameworkSuperBuilder { this.a = CheckerFrameworkSuperBuilder.ZChild.$default$a(); this.b = b.b; } - public static @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.common.aliasing.qual.Unique ZChildBuilder<?, ?> builder() { + public static @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.common.aliasing.qual.Unique ZChildBuilder<?, ?> builder() { return new CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl(); } } diff --git a/test/transform/resource/after-ecj/DataWithOverrideEqualsAndHashCode.java b/test/transform/resource/after-ecj/DataWithOverrideEqualsAndHashCode.java new file mode 100644 index 00000000..2149321f --- /dev/null +++ b/test/transform/resource/after-ecj/DataWithOverrideEqualsAndHashCode.java @@ -0,0 +1,25 @@ +import lombok.Data; +class DataWithOverrideEqualsAndHashCode { + class Data1 { + Data1() { + super(); + } + } + @Data class Data2 extends Data1 { + public int hashCode() { + return 42; + } + public boolean equals(Object other) { + return false; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return "DataWithOverrideEqualsAndHashCode.Data2()"; + } + public @java.lang.SuppressWarnings("all") Data2() { + super(); + } + } + DataWithOverrideEqualsAndHashCode() { + super(); + } +} diff --git a/test/transform/resource/after-ecj/NullAnnotatedCheckerFrameworkSuperBuilder.java b/test/transform/resource/after-ecj/NullAnnotatedCheckerFrameworkSuperBuilder.java index a1c8e74e..94b708d2 100644 --- a/test/transform/resource/after-ecj/NullAnnotatedCheckerFrameworkSuperBuilder.java +++ b/test/transform/resource/after-ecj/NullAnnotatedCheckerFrameworkSuperBuilder.java @@ -11,12 +11,12 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { public ParentBuilder() { super(); } - protected abstract @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self(); - public abstract @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(NullAnnotatedCheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.calledmethods.qual.CalledMethods({"y", "z"}) ParentBuilder<C, B> this); + protected abstract @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.SuppressWarnings("all") C build(); /** * @return {@code this}. */ - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B x(NullAnnotatedCheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.calledmethods.qual.NotCalledMethods("x") ParentBuilder<C, B> this, final int x) { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B x(final int x) { this.x$value = x; x$set = true; return self(); @@ -24,24 +24,24 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { /** * @return {@code this}. */ - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B y(NullAnnotatedCheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.calledmethods.qual.NotCalledMethods("y") ParentBuilder<C, B> this, final int y) { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B y(final int y) { this.y = y; return self(); } /** * @return {@code this}. */ - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B z(NullAnnotatedCheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.calledmethods.qual.NotCalledMethods("z") ParentBuilder<C, B> this, final int z) { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B z(final int z) { this.z = z; return self(); } - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B name(final String name) { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B name(final String name) { if ((this.names == null)) this.names = new java.util.ArrayList<String>(); this.names.add(name); return self(); } - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B names(final java.util.Collection<? extends String> names) { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B names(final java.util. @org.checkerframework.checker.nullness.qual.NonNull Collection<? extends String> names) { if ((names == null)) { throw new java.lang.NullPointerException("names cannot be null"); @@ -51,12 +51,12 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { this.names.addAll(names); return self(); } - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B clearNames() { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B clearNames() { if ((this.names != null)) this.names.clear(); return self(); } - public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") java.lang.String toString() { + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.@org.checkerframework.checker.nullness.qual.NonNull String toString() { return (((((((("NullAnnotatedCheckerFrameworkSuperBuilder.Parent.ParentBuilder(x$value=" + this.x$value) + ", y=") + this.y) + ", z=") + this.z) + ", names=") + this.names) + ")"); } } @@ -64,10 +64,10 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { private ParentBuilderImpl() { super(); } - protected @java.lang.Override @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl self() { + protected @java.lang.Override @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl self() { return this; } - public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.Parent build(NullAnnotatedCheckerFrameworkSuperBuilder.Parent.@org.checkerframework.checker.calledmethods.qual.CalledMethods({"y", "z"}) ParentBuilderImpl this) { + public @java.lang.Override @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.@org.checkerframework.checker.nullness.qual.NonNull Parent build() { return new NullAnnotatedCheckerFrameworkSuperBuilder.Parent(this); } } @@ -99,7 +99,7 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { } this.names = names; } - public static @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.Parent. @org.checkerframework.common.aliasing.qual.Unique ParentBuilder<?, ?> builder() { + public static @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.nullness.qual.NonNull ParentBuilder<?, ?> builder() { return new NullAnnotatedCheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl(); } } @@ -111,12 +111,12 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { public ZChildBuilder() { super(); } - protected abstract @java.lang.Override @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self(); - public abstract @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(NullAnnotatedCheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.checker.calledmethods.qual.CalledMethods("b") ZChildBuilder<C, B> this); + protected abstract @java.lang.Override @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.Override @java.lang.SuppressWarnings("all") C build(); /** * @return {@code this}. */ - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B a(NullAnnotatedCheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.checker.calledmethods.qual.NotCalledMethods("a") ZChildBuilder<C, B> this, final int a) { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B a(final int a) { this.a$value = a; a$set = true; return self(); @@ -124,11 +124,11 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { /** * @return {@code this}. */ - public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B b(NullAnnotatedCheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.checker.calledmethods.qual.NotCalledMethods("b") ZChildBuilder<C, B> this, final int b) { + public @org.checkerframework.checker.nullness.qual.NonNull @java.lang.SuppressWarnings("all") B b(final int b) { this.b = b; return self(); } - public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") java.lang.String toString() { + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.@org.checkerframework.checker.nullness.qual.NonNull String toString() { return (((((("NullAnnotatedCheckerFrameworkSuperBuilder.ZChild.ZChildBuilder(super=" + super.toString()) + ", a$value=") + this.a$value) + ", b=") + this.b) + ")"); } } @@ -136,10 +136,10 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { private ZChildBuilderImpl() { super(); } - protected @java.lang.Override @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl self() { + protected @java.lang.Override @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl self() { return this; } - public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.ZChild build(NullAnnotatedCheckerFrameworkSuperBuilder.ZChild.@org.checkerframework.checker.calledmethods.qual.CalledMethods("b") ZChildBuilderImpl this) { + public @java.lang.Override @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.@org.checkerframework.checker.nullness.qual.NonNull ZChild build() { return new NullAnnotatedCheckerFrameworkSuperBuilder.ZChild(this); } } @@ -156,11 +156,11 @@ class NullAnnotatedCheckerFrameworkSuperBuilder { this.a = NullAnnotatedCheckerFrameworkSuperBuilder.ZChild.$default$a(); this.b = b.b; } - public static @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.common.aliasing.qual.Unique ZChildBuilder<?, ?> builder() { + public static @java.lang.SuppressWarnings("all") NullAnnotatedCheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.checker.nullness.qual.NonNull ZChildBuilder<?, ?> builder() { return new NullAnnotatedCheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl(); } } NullAnnotatedCheckerFrameworkSuperBuilder() { super(); } -} +}
\ No newline at end of file diff --git a/test/transform/resource/before/DataWithOverrideEqualsAndHashCode.java b/test/transform/resource/before/DataWithOverrideEqualsAndHashCode.java new file mode 100644 index 00000000..78138bbf --- /dev/null +++ b/test/transform/resource/before/DataWithOverrideEqualsAndHashCode.java @@ -0,0 +1,18 @@ +import lombok.Data; + +class DataWithOverrideEqualsAndHashCode { + class Data1 { + + } + + @Data + class Data2 extends Data1 { + public int hashCode() { + return 42; + } + + public boolean equals(Object other) { + return false; + } + } +}
\ No newline at end of file |