From 0ab433b41a6d2afa446d7e46204531c1efa606e2 Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Tue, 11 Feb 2020 12:25:53 +0100 Subject: [PATCH] SuperBuilder javac fix for nested generic types; fixes #2359 --- .../javac/handlers/HandleSuperBuilder.java | 15 ++++--- .../SuperBuilderNestedGenericTypes.java | 41 +++++++++++++++++++ .../SuperBuilderNestedGenericTypes.java | 37 +++++++++++++++++ .../SuperBuilderNestedGenericTypes.java | 12 ++++++ 4 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 test/transform/resource/after-delombok/SuperBuilderNestedGenericTypes.java create mode 100644 test/transform/resource/after-ecj/SuperBuilderNestedGenericTypes.java create mode 100644 test/transform/resource/before/SuperBuilderNestedGenericTypes.java diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index c9df48112a..5f4f3c1d07 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -53,6 +53,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.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; @@ -414,7 +415,7 @@ private JavacNode generateBuilderAbstractClass(JavacNode source, JavacNode tdPar allTypeParams.add(maker.TypeParameter(tdParent.toName(classGenericName), List.of(annotatedClass))); // 2. The return type for all setter methods, named "B", which extends this builder class. Name builderClassName = tdParent.toName(builderClass); - ListBuffer typeParamsForBuilder = getTypeParamExpressions(typeParams, maker); + ListBuffer typeParamsForBuilder = getTypeParamExpressions(typeParams, maker, source.getContext()); typeParamsForBuilder.add(maker.Ident(tdParent.toName(classGenericName))); typeParamsForBuilder.add(maker.Ident(tdParent.toName(builderGenericName))); JCTypeApply typeApply = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, tdParent, builderClassName, false, List.nil()), typeParamsForBuilder.toList()); @@ -424,7 +425,7 @@ private JavacNode generateBuilderAbstractClass(JavacNode source, JavacNode tdPar if (superclassBuilderClassExpression != null) { // If the annotated class extends another class, we want this builder to extend the builder of the superclass. // 1. Add the type parameters of the superclass. - typeParamsForBuilder = getTypeParamExpressions(superclassTypeParams, maker); + typeParamsForBuilder = getTypeParamExpressions(superclassTypeParams, maker, source.getContext()); // 2. Add the builder type params . typeParamsForBuilder.add(maker.Ident(tdParent.toName(classGenericName))); typeParamsForBuilder.add(maker.Ident(tdParent.toName(builderGenericName))); @@ -453,7 +454,7 @@ private JavacNode generateBuilderImplClass(JavacNode source, JavacNode tdParent, // 2. The return type for all setter methods (named "B" in the abstract builder), which is this builder class. JCExpression builderImplClassExpression = namePlusTypeParamsToTypeReference(maker, tdParent, tdParent.toName(builderImplClass), false, typeParams); - ListBuffer typeParamsForBuilder = getTypeParamExpressions(typeParams, maker); + ListBuffer typeParamsForBuilder = getTypeParamExpressions(typeParams, maker, source.getContext()); typeParamsForBuilder.add(annotatedClass); typeParamsForBuilder.add(builderImplClassExpression); extending = maker.TypeApply(extending, typeParamsForBuilder.toList()); @@ -522,7 +523,7 @@ private void generateBuilderBasedConstructor(CheckerFrameworkVersion cfv, JavacN long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext()); Name builderClassname = typeNode.toName(builderClassName); // First add all generics that are present on the parent type. - ListBuffer typeParamsForBuilderParameter = getTypeParamExpressions(typeParams, maker); + ListBuffer typeParamsForBuilderParameter = getTypeParamExpressions(typeParams, maker, typeNode.getContext()); // Now add the . JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null); typeParamsForBuilderParameter.add(wildcard); @@ -685,7 +686,7 @@ private JCMethodDecl generateStaticFillValuesMethod(JavacNode type, String build // 2nd parameter: "FoobarBuilder b" (plus generics on the annotated type) // First add all generics that are present on the parent type. - ListBuffer typeParamsForBuilderParameter = getTypeParamExpressions(typeParams, maker); + ListBuffer typeParamsForBuilderParameter = getTypeParamExpressions(typeParams, maker, type.getContext()); // Now add the . JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null); typeParamsForBuilderParameter.add(wildcard); @@ -1029,7 +1030,7 @@ private JavacNode findInnerClass(JavacNode parent, String name) { return null; } - private ListBuffer getTypeParamExpressions(List typeParams, JavacTreeMaker maker) { + private ListBuffer getTypeParamExpressions(List typeParams, JavacTreeMaker maker, Context context) { ListBuffer typeParamsForBuilderParameter = new ListBuffer(); for (JCTree typeParam : typeParams) { if (typeParam instanceof JCTypeParameter) { @@ -1038,6 +1039,8 @@ private ListBuffer getTypeParamExpressions(List typeParamsForBuilderParameter.add(maker.Ident(((JCIdent)typeParam).getName())); } else if (typeParam instanceof JCFieldAccess) { typeParamsForBuilderParameter.add(copySelect(maker, (JCFieldAccess) typeParam)); + } else if (typeParam instanceof JCTypeApply) { + typeParamsForBuilderParameter.add(cloneType(maker, (JCTypeApply)typeParam, typeParam, context)); } } return typeParamsForBuilderParameter; diff --git a/test/transform/resource/after-delombok/SuperBuilderNestedGenericTypes.java b/test/transform/resource/after-delombok/SuperBuilderNestedGenericTypes.java new file mode 100644 index 0000000000..ad738c0134 --- /dev/null +++ b/test/transform/resource/after-delombok/SuperBuilderNestedGenericTypes.java @@ -0,0 +1,41 @@ +public class SuperBuilderNestedGenericTypes { + public static abstract class Generic> { + @java.lang.SuppressWarnings("all") + public static abstract class GenericBuilder, C extends SuperBuilderNestedGenericTypes.Generic, B extends SuperBuilderNestedGenericTypes.Generic.GenericBuilder> { + @java.lang.SuppressWarnings("all") + protected abstract B self(); + @java.lang.SuppressWarnings("all") + public abstract C build(); + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "SuperBuilderNestedGenericTypes.Generic.GenericBuilder()"; + } + } + @java.lang.SuppressWarnings("all") + protected Generic(final SuperBuilderNestedGenericTypes.Generic.GenericBuilder b) { + } + } + public static abstract class NestedGeneric> extends Generic>> { + @java.lang.SuppressWarnings("all") + public static abstract class NestedGenericBuilder, C extends SuperBuilderNestedGenericTypes.NestedGeneric, B extends SuperBuilderNestedGenericTypes.NestedGeneric.NestedGenericBuilder> extends Generic.GenericBuilder>, C, B> { + @java.lang.Override + @java.lang.SuppressWarnings("all") + protected abstract B self(); + @java.lang.Override + @java.lang.SuppressWarnings("all") + public abstract C build(); + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "SuperBuilderNestedGenericTypes.NestedGeneric.NestedGenericBuilder(super=" + super.toString() + ")"; + } + } + @java.lang.SuppressWarnings("all") + protected NestedGeneric(final SuperBuilderNestedGenericTypes.NestedGeneric.NestedGenericBuilder b) { + super(b); + } + } + public interface OtherGeneric { + } +} diff --git a/test/transform/resource/after-ecj/SuperBuilderNestedGenericTypes.java b/test/transform/resource/after-ecj/SuperBuilderNestedGenericTypes.java new file mode 100644 index 0000000000..e511b27680 --- /dev/null +++ b/test/transform/resource/after-ecj/SuperBuilderNestedGenericTypes.java @@ -0,0 +1,37 @@ +public class SuperBuilderNestedGenericTypes { + public static abstract @lombok.experimental.SuperBuilder class Generic> { + public static abstract @java.lang.SuppressWarnings("all") class GenericBuilder, C extends SuperBuilderNestedGenericTypes.Generic, B extends SuperBuilderNestedGenericTypes.Generic.GenericBuilder> { + public GenericBuilder() { + super(); + } + protected abstract @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.SuppressWarnings("all") C build(); + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return "SuperBuilderNestedGenericTypes.Generic.GenericBuilder()"; + } + } + protected @java.lang.SuppressWarnings("all") Generic(final SuperBuilderNestedGenericTypes.Generic.GenericBuilder b) { + super(); + } + } + public static abstract @lombok.experimental.SuperBuilder class NestedGeneric> extends Generic>> { + public static abstract @java.lang.SuppressWarnings("all") class NestedGenericBuilder, C extends SuperBuilderNestedGenericTypes.NestedGeneric, B extends SuperBuilderNestedGenericTypes.NestedGeneric.NestedGenericBuilder> extends Generic.GenericBuilder>, C, B> { + public NestedGenericBuilder() { + super(); + } + protected abstract @java.lang.Override @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.Override @java.lang.SuppressWarnings("all") C build(); + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("SuperBuilderNestedGenericTypes.NestedGeneric.NestedGenericBuilder(super=" + super.toString()) + ")"); + } + } + protected @java.lang.SuppressWarnings("all") NestedGeneric(final SuperBuilderNestedGenericTypes.NestedGeneric.NestedGenericBuilder b) { + super(b); + } + } + public interface OtherGeneric { + } + public SuperBuilderNestedGenericTypes() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/SuperBuilderNestedGenericTypes.java b/test/transform/resource/before/SuperBuilderNestedGenericTypes.java new file mode 100644 index 0000000000..c463357e1b --- /dev/null +++ b/test/transform/resource/before/SuperBuilderNestedGenericTypes.java @@ -0,0 +1,12 @@ +public class SuperBuilderNestedGenericTypes { + @lombok.experimental.SuperBuilder + public static abstract class Generic> { + } + + @lombok.experimental.SuperBuilder + public static abstract class NestedGeneric> extends Generic>> { + } + + public interface OtherGeneric { + } +}