SuperBuilder support for abstract classes

This commit is contained in:
Jan Rieke committed 2018-06-04 17:52:38 +02:00
1 parent d4fa7c583b
commit e2fc6fa564
5 files changed
+292 -27

No files matched your search

@@ -333,6 +333,11 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
}
if ((td.modifiers & ClassFileConstants.AccAbstract) != 0) {
// Abstract classes to not get the Builder implementation nor the builder() method.
return;
}
// Create the builder implementation class.
EclipseNode builderImplType = findInnerClass(tdParent, builderImplClassName);
if (builderImplType == null) {
@@ -282,42 +282,51 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
if (addCleaning) {
injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
}
recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
// Create the builder implementation class.
JavacNode builderImplType = findInnerClass(tdParent, builderImplClassName);
if (builderImplType == null) {
builderImplType = generateBuilderImplClass(annotationNode, tdParent, builderImplClassName, builderClassName, typeParams, ast);
} else {
annotationNode.addError("@SuperBuilder does not support customized builders. Use @Builder instead.");
return;
if ((td.mods.flags & Flags.ABSTRACT) == 0) {
// Only non-abstract classes get the Builder implementation.
// Create the builder implementation class.
JavacNode builderImplType = findInnerClass(tdParent, builderImplClassName);
if (builderImplType == null) {
builderImplType = generateBuilderImplClass(annotationNode, tdParent, builderImplClassName, builderClassName, typeParams, ast);
} else {
annotationNode.addError("@SuperBuilder does not support customized builders. Use @Builder instead.");
return;
}
// Create a simple constructor for the BuilderImpl class.
JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PRIVATE, List.<JCAnnotation>nil(), builderImplType, List.<JavacNode>nil(), false, annotationNode);
if (cd != null) {
injectMethod(builderImplType, cd);
}
// Create the self() and build() methods in the BuilderImpl.
injectMethod(builderImplType, generateSelfMethod(builderImplType));
injectMethod(builderImplType, generateBuildMethod(buildMethodName, returnType, builderImplType, thrownExceptions));
recursiveSetGeneratedBy(builderImplType.get(), ast, annotationNode.getContext());
}
// Create a simple constructor for the BuilderImpl class.
JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PRIVATE, List.<JCAnnotation>nil(), builderImplType, List.<JavacNode>nil(), false, annotationNode);
if (cd != null) {
injectMethod(builderImplType, cd);
}
// Create the self() and build() methods in the BuilderImpl.
injectMethod(builderImplType, generateSelfMethod(builderImplType));
injectMethod(builderImplType, generateBuildMethod(buildMethodName, returnType, builderImplType, thrownExceptions));
// Generate a constructor in the annotated class that takes a builder as argument.
generateBuilderBasedConstructor(tdParent, typeParams, builderFields, annotationNode, builderClassName,
superclassBuilderClassExpression != null);
// Add the builder() method to the annotated class.
// Allow users to specify their own builder() methods, e.g., to provide default values.
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl builderMethod = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams);
recursiveSetGeneratedBy(builderMethod, ast, annotationNode.getContext());
if (builderMethod != null) {
injectMethod(tdParent, builderMethod);
if ((td.mods.flags & Flags.ABSTRACT) == 0) {
// Only non-abstract classes get the Builder implementation and the builder() method.
// Add the builder() method to the annotated class.
// Allow users to specify their own builder() methods, e.g., to provide default values.
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl builderMethod = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams);
recursiveSetGeneratedBy(builderMethod, ast, annotationNode.getContext());
if (builderMethod != null) {
injectMethod(tdParent, builderMethod);
}
}
}
recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
recursiveSetGeneratedBy(builderImplType.get(), ast, annotationNode.getContext());
}
/**
@@ -0,0 +1,129 @@
public class SuperBuilderAbstract {
public static class Parent {
int parentField;
@java.lang.SuppressWarnings("all")
public static abstract class ParentBuilder<C extends Parent, B extends ParentBuilder<C, B>> {
@java.lang.SuppressWarnings("all")
private int parentField;
@java.lang.SuppressWarnings("all")
protected abstract B self();
@java.lang.SuppressWarnings("all")
public abstract C build();
@java.lang.SuppressWarnings("all")
public B parentField(final int parentField) {
this.parentField = parentField;
return self();
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
return "SuperBuilderAbstract.Parent.ParentBuilder(parentField=" + this.parentField + ")";
}
}
@java.lang.SuppressWarnings("all")
private static final class ParentBuilderImpl extends ParentBuilder<Parent, ParentBuilderImpl> {
@java.lang.SuppressWarnings("all")
private ParentBuilderImpl() {
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
protected ParentBuilderImpl self() {
return this;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public Parent build() {
return new Parent(this);
}
}
@java.lang.SuppressWarnings("all")
protected Parent(final ParentBuilder<?, ?> b) {
this.parentField = b.parentField;
}
@java.lang.SuppressWarnings("all")
public static ParentBuilder<?, ?> builder() {
return new ParentBuilderImpl();
}
}
public static abstract class Child extends Parent {
double childField;
@java.lang.SuppressWarnings("all")
public static abstract class ChildBuilder<C extends Child, B extends ChildBuilder<C, B>> extends Parent.ParentBuilder<C, B> {
@java.lang.SuppressWarnings("all")
private double childField;
@java.lang.Override
@java.lang.SuppressWarnings("all")
protected abstract B self();
@java.lang.Override
@java.lang.SuppressWarnings("all")
public abstract C build();
@java.lang.SuppressWarnings("all")
public B childField(final double childField) {
this.childField = childField;
return self();
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
return "SuperBuilderAbstract.Child.ChildBuilder(super=" + super.toString() + ", childField=" + this.childField + ")";
}
}
@java.lang.SuppressWarnings("all")
protected Child(final ChildBuilder<?, ?> b) {
super(b);
this.childField = b.childField;
}
}
public static class GrandChild extends Child {
String grandChildField;
@java.lang.SuppressWarnings("all")
public static abstract class GrandChildBuilder<C extends GrandChild, B extends GrandChildBuilder<C, B>> extends Child.ChildBuilder<C, B> {
@java.lang.SuppressWarnings("all")
private String grandChildField;
@java.lang.Override
@java.lang.SuppressWarnings("all")
protected abstract B self();
@java.lang.Override
@java.lang.SuppressWarnings("all")
public abstract C build();
@java.lang.SuppressWarnings("all")
public B grandChildField(final String grandChildField) {
this.grandChildField = grandChildField;
return self();
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
return "SuperBuilderAbstract.GrandChild.GrandChildBuilder(super=" + super.toString() + ", grandChildField=" + this.grandChildField + ")";
}
}
@java.lang.SuppressWarnings("all")
private static final class GrandChildBuilderImpl extends GrandChildBuilder<GrandChild, GrandChildBuilderImpl> {
@java.lang.SuppressWarnings("all")
private GrandChildBuilderImpl() {
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
protected GrandChildBuilderImpl self() {
return this;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public GrandChild build() {
return new GrandChild(this);
}
}
@java.lang.SuppressWarnings("all")
protected GrandChild(final GrandChildBuilder<?, ?> b) {
super(b);
this.grandChildField = b.grandChildField;
}
@java.lang.SuppressWarnings("all")
public static GrandChildBuilder<?, ?> builder() {
return new GrandChildBuilderImpl();
}
}
public static void test() {
GrandChild x = GrandChild.builder().grandChildField("").parentField(5).childField(2.5).build();
}
}
@@ -0,0 +1,102 @@
public class SuperBuilderAbstract {
public static @lombok.experimental.SuperBuilder class Parent {
public static abstract @java.lang.SuppressWarnings("all") class ParentBuilder<C extends Parent, B extends ParentBuilder<C, B>> {
private @java.lang.SuppressWarnings("all") int parentField;
public ParentBuilder() {
super();
}
protected abstract @java.lang.SuppressWarnings("all") B self();
public abstract @java.lang.SuppressWarnings("all") C build();
public @java.lang.SuppressWarnings("all") B parentField(final int parentField) {
this.parentField = parentField;
return self();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
return (("SuperBuilderAbstract.Parent.ParentBuilder(parentField=" + this.parentField) + ")");
}
}
private static final @java.lang.SuppressWarnings("all") class ParentBuilderImpl extends ParentBuilder<Parent, ParentBuilderImpl> {
private ParentBuilderImpl() {
super();
}
protected @java.lang.Override @java.lang.SuppressWarnings("all") ParentBuilderImpl self() {
return this;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") Parent build() {
return new Parent(this);
}
}
int parentField;
protected @java.lang.SuppressWarnings("all") Parent(final ParentBuilder<?, ?> b) {
super();
this.parentField = b.parentField;
}
public static @java.lang.SuppressWarnings("all") ParentBuilder<?, ?> builder() {
return new ParentBuilderImpl();
}
}
public static abstract @lombok.experimental.SuperBuilder class Child extends Parent {
public static abstract @java.lang.SuppressWarnings("all") class ChildBuilder<C extends Child, B extends ChildBuilder<C, B>> extends Parent.ParentBuilder<C, B> {
private @java.lang.SuppressWarnings("all") double childField;
public ChildBuilder() {
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.SuppressWarnings("all") B childField(final double childField) {
this.childField = childField;
return self();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
return (((("SuperBuilderAbstract.Child.ChildBuilder(super=" + super.toString()) + ", childField=") + this.childField) + ")");
}
}
double childField;
protected @java.lang.SuppressWarnings("all") Child(final ChildBuilder<?, ?> b) {
super(b);
this.childField = b.childField;
}
}
public static @lombok.experimental.SuperBuilder class GrandChild extends Child {
public static abstract @java.lang.SuppressWarnings("all") class GrandChildBuilder<C extends GrandChild, B extends GrandChildBuilder<C, B>> extends Child.ChildBuilder<C, B> {
private @java.lang.SuppressWarnings("all") String grandChildField;
public GrandChildBuilder() {
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.SuppressWarnings("all") B grandChildField(final String grandChildField) {
this.grandChildField = grandChildField;
return self();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
return (((("SuperBuilderAbstract.GrandChild.GrandChildBuilder(super=" + super.toString()) + ", grandChildField=") + this.grandChildField) + ")");
}
}
private static final @java.lang.SuppressWarnings("all") class GrandChildBuilderImpl extends GrandChildBuilder<GrandChild, GrandChildBuilderImpl> {
private GrandChildBuilderImpl() {
super();
}
protected @java.lang.Override @java.lang.SuppressWarnings("all") GrandChildBuilderImpl self() {
return this;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") GrandChild build() {
return new GrandChild(this);
}
}
String grandChildField;
protected @java.lang.SuppressWarnings("all") GrandChild(final GrandChildBuilder<?, ?> b) {
super(b);
this.grandChildField = b.grandChildField;
}
public static @java.lang.SuppressWarnings("all") GrandChildBuilder<?, ?> builder() {
return new GrandChildBuilderImpl();
}
}
public SuperBuilderAbstract() {
super();
}
public static void test() {
GrandChild x = GrandChild.builder().grandChildField("").parentField(5).childField(2.5).build();
}
}
@@ -0,0 +1,20 @@
public class SuperBuilderAbstract {
@lombok.experimental.SuperBuilder
public static class Parent {
int parentField;
}
@lombok.experimental.SuperBuilder
public abstract static class Child extends Parent {
double childField;
}
@lombok.experimental.SuperBuilder
public static class GrandChild extends Child {
String grandChildField;
}
public static void test() {
GrandChild x = GrandChild.builder().grandChildField("").parentField(5).childField(2.5).build();
}
}