From a38b41f100ac759eadb05433341cf062e7094f4c Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 16 Feb 2017 22:02:32 +0100 Subject: Added a test case to highlight issue #1302: `@Builder` on non-static inner classes (or constructors of non-static inner classes) doesn't work. --- .../knownBroken/before/I1302BuilderInInstanceInnerClass.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 test/transform/knownBroken/before/I1302BuilderInInstanceInnerClass.java (limited to 'test/transform/knownBroken') diff --git a/test/transform/knownBroken/before/I1302BuilderInInstanceInnerClass.java b/test/transform/knownBroken/before/I1302BuilderInInstanceInnerClass.java new file mode 100644 index 00000000..cf37abc4 --- /dev/null +++ b/test/transform/knownBroken/before/I1302BuilderInInstanceInnerClass.java @@ -0,0 +1,5 @@ +public class I1302BuilderInInstanceInnerClass { + @lombok.Builder public class NonStaticInner { + private int test; + } +} -- cgit From 8ec7abf996ba1089104f5d56cc417b17dcadca5f Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 16 Feb 2017 22:16:34 +0100 Subject: Reproduces the bug with recursive generics in builder (issue #1298). --- .../knownBroken/before/I1298BuilderWithGenerics.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/transform/knownBroken/before/I1298BuilderWithGenerics.java (limited to 'test/transform/knownBroken') diff --git a/test/transform/knownBroken/before/I1298BuilderWithGenerics.java b/test/transform/knownBroken/before/I1298BuilderWithGenerics.java new file mode 100644 index 00000000..af154d42 --- /dev/null +++ b/test/transform/knownBroken/before/I1298BuilderWithGenerics.java @@ -0,0 +1,15 @@ +import java.util.Set; +import lombok.Builder; +import lombok.Value; + +public class I1298BuilderWithGenerics { + interface Inter> {} + + @Builder @Value public static class Test< + Foo, + Bar extends Set, + Quz extends Inter> { + Foo foo; + Bar bar; + } +} -- cgit From 74603cd9d355353f5373deb167988c5eaf015346 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 16 Feb 2017 23:32:17 +0100 Subject: Fixing issue #1298: `@Builder` with recursive generics didn’t work in javac/delombok. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/lombok/javac/handlers/HandleBuilder.java | 13 ++- .../lombok/javac/handlers/JavacHandlerUtil.java | 17 +++- .../before/I1298BuilderWithGenerics.java | 15 ---- .../BuilderWithRecursiveGenerics.java | 100 +++++++++++++++++++++ .../after-ecj/BuilderWithRecursiveGenerics.java | 78 ++++++++++++++++ .../before/BuilderWithRecursiveGenerics.java | 13 +++ 6 files changed, 212 insertions(+), 24 deletions(-) delete mode 100644 test/transform/knownBroken/before/I1298BuilderWithGenerics.java create mode 100644 test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java create mode 100644 test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java create mode 100644 test/transform/resource/before/BuilderWithRecursiveGenerics.java (limited to 'test/transform/knownBroken') diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index d37e1f79..2704981b 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -297,7 +297,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JavacNode builderType = findInnerClass(tdParent, builderClassName); if (builderType == null) { - builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast); + builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast); } else { JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get(); if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) { @@ -319,7 +319,6 @@ public class HandleBuilder extends JavacAnnotationHandler { } } } - } for (BuilderFieldData bfd : builderFields) { @@ -374,7 +373,7 @@ public class HandleBuilder extends JavacAnnotationHandler { if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast)); if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) { - JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams); + JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams); recursiveSetGeneratedBy(md, ast, annotationNode.getContext()); if (md != null) injectMethod(tdParent, md); } @@ -549,7 +548,7 @@ public class HandleBuilder extends JavacAnnotationHandler { return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.nil(), List.nil(), thrownExceptions, body, null); } - public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode type, List typeParams) { + public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode source, JavacNode type, List typeParams) { JavacTreeMaker maker = type.getTreeMaker(); ListBuffer typeArgs = new ListBuffer(); @@ -563,7 +562,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCBlock body = maker.Block(0, List.of(statement)); int modifiers = Flags.PUBLIC; if (isStatic) modifiers |= Flags.STATIC; - return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.nil(), List.nil(), body, null); + return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(source, typeParams), List.nil(), List.nil(), body, null); } public void generateBuilderFields(JavacNode builderType, java.util.List builderFields, JCTree source) { @@ -628,12 +627,12 @@ public class HandleBuilder extends JavacAnnotationHandler { return null; } - public JavacNode makeBuilderClass(boolean isStatic, JavacNode tdParent, String builderClassName, List typeParams, JCAnnotation ast) { + public JavacNode makeBuilderClass(boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List typeParams, JCAnnotation ast) { JavacTreeMaker maker = tdParent.getTreeMaker(); int modifiers = Flags.PUBLIC; if (isStatic) modifiers |= Flags.STATIC; JCModifiers mods = maker.Modifiers(modifiers); - JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.nil(), List.nil()); + JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(source, typeParams), null, List.nil(), List.nil()); return injectType(tdParent, builder); } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 2b67118e..27289108 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -92,6 +92,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.JCWildcard; import com.sun.tools.javac.tree.JCTree.TypeBoundKind; +import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -1317,10 +1318,22 @@ public class JavacHandlerUtil { return result.toList(); } - public static List copyTypeParams(JavacTreeMaker maker, List params) { + public static List copyTypeParams(JavacNode source, List params) { if (params == null || params.isEmpty()) return params; ListBuffer out = new ListBuffer(); - for (JCTypeParameter tp : params) out.append(maker.TypeParameter(tp.name, tp.bounds)); + JavacTreeMaker maker = source.getTreeMaker(); + Context context = source.getContext(); + for (JCTypeParameter tp : params) { + List bounds = tp.bounds; + if (bounds != null && !bounds.isEmpty()) { + ListBuffer boundsCopy = new ListBuffer(); + for (JCExpression expr : tp.bounds) { + boundsCopy.append(cloneType(maker, expr, source.get(), context)); + } + bounds = boundsCopy.toList(); + } + out.append(maker.TypeParameter(tp.name, bounds)); + } return out.toList(); } diff --git a/test/transform/knownBroken/before/I1298BuilderWithGenerics.java b/test/transform/knownBroken/before/I1298BuilderWithGenerics.java deleted file mode 100644 index af154d42..00000000 --- a/test/transform/knownBroken/before/I1298BuilderWithGenerics.java +++ /dev/null @@ -1,15 +0,0 @@ -import java.util.Set; -import lombok.Builder; -import lombok.Value; - -public class I1298BuilderWithGenerics { - interface Inter> {} - - @Builder @Value public static class Test< - Foo, - Bar extends Set, - Quz extends Inter> { - Foo foo; - Bar bar; - } -} diff --git a/test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java b/test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java new file mode 100644 index 00000000..edc1e3c6 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java @@ -0,0 +1,100 @@ +import java.util.Set; +public class BuilderWithRecursiveGenerics { + interface Inter> { + } + public static final class Test, Quz extends Inter> { + private final Foo foo; + private final Bar bar; + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + Test(final Foo foo, final Bar bar) { + this.foo = foo; + this.bar = bar; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public static class TestBuilder, Quz extends Inter> { + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + private Foo foo; + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + private Bar bar; + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + TestBuilder() { + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public TestBuilder foo(final Foo foo) { + this.foo = foo; + return this; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public TestBuilder bar(final Bar bar) { + this.bar = bar; + return this; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public Test build() { + return new Test(foo, bar); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public java.lang.String toString() { + return "BuilderWithRecursiveGenerics.Test.TestBuilder(foo=" + this.foo + ", bar=" + this.bar + ")"; + } + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public static , Quz extends Inter> TestBuilder builder() { + return new TestBuilder(); + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public Foo getFoo() { + return this.foo; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public Bar getBar() { + return this.bar; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public boolean equals(final java.lang.Object o) { + if (o == this) return true; + if (!(o instanceof BuilderWithRecursiveGenerics.Test)) return false; + final BuilderWithRecursiveGenerics.Test other = (BuilderWithRecursiveGenerics.Test) o; + final java.lang.Object this$foo = this.getFoo(); + final java.lang.Object other$foo = other.getFoo(); + if (this$foo == null ? other$foo != null : !this$foo.equals(other$foo)) return false; + final java.lang.Object this$bar = this.getBar(); + final java.lang.Object other$bar = other.getBar(); + if (this$bar == null ? other$bar != null : !this$bar.equals(other$bar)) return false; + return true; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public int hashCode() { + final int PRIME = 59; + int result = 1; + final java.lang.Object $foo = this.getFoo(); + result = result * PRIME + ($foo == null ? 43 : $foo.hashCode()); + final java.lang.Object $bar = this.getBar(); + result = result * PRIME + ($bar == null ? 43 : $bar.hashCode()); + return result; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public java.lang.String toString() { + return "BuilderWithRecursiveGenerics.Test(foo=" + this.getFoo() + ", bar=" + this.getBar() + ")"; + } + } +} diff --git a/test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java b/test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java new file mode 100644 index 00000000..f13b8b9b --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java @@ -0,0 +1,78 @@ +import java.util.Set; +import lombok.Builder; +import lombok.Value; +public class BuilderWithRecursiveGenerics { + interface Inter> { + } + public static final @Builder @Value class Test, Quz extends Inter> { + public static @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") class TestBuilder, Quz extends Inter> { + private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Foo foo; + private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Bar bar; + @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") TestBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") TestBuilder foo(final Foo foo) { + this.foo = foo; + return this; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") TestBuilder bar(final Bar bar) { + this.bar = bar; + return this; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Test build() { + return new Test(foo, bar); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() { + return (((("BuilderWithRecursiveGenerics.Test.TestBuilder(foo=" + this.foo) + ", bar=") + this.bar) + ")"); + } + } + private final Foo foo; + private final Bar bar; + @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Test(final Foo foo, final Bar bar) { + super(); + this.foo = foo; + this.bar = bar; + } + public static @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") , Quz extends Inter>TestBuilder builder() { + return new TestBuilder(); + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Foo getFoo() { + return this.foo; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Bar getBar() { + return this.bar; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") boolean equals(final java.lang.Object o) { + if ((o == this)) + return true; + if ((! (o instanceof BuilderWithRecursiveGenerics.Test))) + return false; + final BuilderWithRecursiveGenerics.Test other = (BuilderWithRecursiveGenerics.Test) o; + final java.lang.Object this$foo = this.getFoo(); + final java.lang.Object other$foo = other.getFoo(); + if (((this$foo == null) ? (other$foo != null) : (! this$foo.equals(other$foo)))) + return false; + final java.lang.Object this$bar = this.getBar(); + final java.lang.Object other$bar = other.getBar(); + if (((this$bar == null) ? (other$bar != null) : (! this$bar.equals(other$bar)))) + return false; + return true; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int hashCode() { + final int PRIME = 59; + int result = 1; + final java.lang.Object $foo = this.getFoo(); + result = ((result * PRIME) + (($foo == null) ? 43 : $foo.hashCode())); + final java.lang.Object $bar = this.getBar(); + result = ((result * PRIME) + (($bar == null) ? 43 : $bar.hashCode())); + return result; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() { + return (((("BuilderWithRecursiveGenerics.Test(foo=" + this.getFoo()) + ", bar=") + this.getBar()) + ")"); + } + } + public BuilderWithRecursiveGenerics() { + super(); + } +} + diff --git a/test/transform/resource/before/BuilderWithRecursiveGenerics.java b/test/transform/resource/before/BuilderWithRecursiveGenerics.java new file mode 100644 index 00000000..041da414 --- /dev/null +++ b/test/transform/resource/before/BuilderWithRecursiveGenerics.java @@ -0,0 +1,13 @@ +//issue #1298 +import java.util.Set; +import lombok.Builder; +import lombok.Value; + +public class BuilderWithRecursiveGenerics { + interface Inter> {} + + @Builder @Value public static class Test, Quz extends Inter> { + Foo foo; + Bar bar; + } +} -- cgit From b7cede3c27e42351e72618c45fd5e960df0e0133 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 17 Feb 2017 00:27:43 +0100 Subject: Reproduced issue #1132 (javac only); self-ref generics doesn’t work in `@Builder` in javac. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../knownBroken/before/I1132RecursiveGenerics.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test/transform/knownBroken/before/I1132RecursiveGenerics.java (limited to 'test/transform/knownBroken') diff --git a/test/transform/knownBroken/before/I1132RecursiveGenerics.java b/test/transform/knownBroken/before/I1132RecursiveGenerics.java new file mode 100644 index 00000000..781886a7 --- /dev/null +++ b/test/transform/knownBroken/before/I1132RecursiveGenerics.java @@ -0,0 +1,19 @@ +// Compile with javac, it'll think the T in the generated build() method isn't type compatible. +// Yet, when you take the delomboked output (which delombok will give, but with errors), THAT does compile. + +public class I1132RecursiveGenerics { + public static class Recursive> {} + public static final class Rec extends Recursive {} + + @lombok.Builder(builderClassName = "MethodBuilder") + public static > T create() { + return null; + } + + public static void main(String[] args) { + final MethodBuilder builder = I1132RecursiveGenerics.builder(); + final Rec rec = builder.build(); +// final Rec rec = I1132RecursiveGenerics.builder().build(); + } +} + -- cgit