toBuilder for SuperBuilder

921 views
Skip to first unread message

Jan Rieke

unread,
Sep 12, 2018, 9:45:02 AM9/12/18
to Project Lombok
I recently investigated how we could add toBuilder support for SuperBuilder. Here is what I came up with:

    public static class Parent {
       
private int field1;

       
public static abstract class ParentBuilder<C extends Parent, B extends ParentBuilder<C, B>> {
           
private int field1;
           
protected B $fillValuesFrom(final C instance) {
               
ParentBuilderImpl.$fillValuesFromInto(instance, this);
               
return self();
           
}
       
}

       
private static final class ParentBuilderImpl extends ParentBuilder<Parent, ParentBuilderImpl> {
           
private static void $fillValuesFromInto(Parent instance, ParentBuilder<?,?> b) {
                b
.field1(instance.field1);
           
}
       
}

       
public ParentBuilder<?, ?> toBuilder() {
           
return new ParentBuilderImpl().$fillValuesFrom(this);
       
}
   
}

   
public static class Child extends Parent {
       
private double field2;

       
public static abstract class ChildBuilder<C extends Child, B extends ChildBuilder<C, B>> extends Parent.ParentBuilder<C, B> {
           
private double field2;
           
protected B $fillValuesFrom(final C instance) {
               
super.$fillValuesFrom(instance);
               
ChildBuilderImpl.$fillValuesFromInto(instance, this);
               
return self();
           
}
       
}

       
private static final class ChildBuilderImpl extends ChildBuilder<Child, ChildBuilderImpl> {
           
private static void $fillValuesFromInto(Parent instance, ParentBuilder<?,?> b) {
                b
.field2(instance.field2);
           
}
       
}

       
public ChildBuilder<?, ?> toBuilder() {
           
return new ChildBuilderImpl().$fillValuesFrom(this);
       
}
   
}

It's a bit ugly, because I need a method within both builder classes. The reason for that construction is that you cannot access instance.field1 from the abstract builder's $fillValuesFrom(), because C technically is an intersection class, which is not a nested class of the annotated type any more.
However, there are no type cast or other warnings on the code.
Could you live with that construction? Any other ideas?

Reinier Zwitserloot

unread,
Sep 12, 2018, 8:57:44 PM9/12/18
to Project Lombok
Well, it's further than I got :)

Given that toBuilder is an optional thing, and given that I thought it wasn't possible _AT ALL_, I think this is going to have to be it. Perhaps a bunch of linters are going to choke on this but, hey, the fix to that is always to tell the linter tool not to lint lombok code.

Jan Rieke

unread,
Sep 20, 2018, 5:45:45 AM9/20/18
to Project Lombok
Just to let you know: I'm currently working on a PR. It works quite good already, just some things to fix when there are generics on the annotated class.

Reinier Zwitserloot

unread,
Sep 21, 2018, 10:21:56 AM9/21/18
to Project Lombok
Sounds good. We're close to another lombok release. Let's try to wait for this one. Unless that's a little too much pressure and you'd prefer it if we go ahead and start releasing without it.

Jan Rieke

unread,
Sep 24, 2018, 10:55:44 AM9/24/18
to Project Lombok

Reinier Zwitserloot

unread,
Oct 2, 2018, 8:33:17 AM10/2/18
to Project Lombok
Thanks. I think this + doublechecks on JDK11 support and then we push out a version. Hopefulyl we can get to it next monday.

Reinier Zwitserloot

unread,
Oct 8, 2018, 10:11:12 PM10/8/18
to Project Lombok
an earlier update to @Builder+@Singular to allow the collection to be 'null', whilst having toBuilder still work, is turning into this gigantic clusterball of a project.

I'm many hours in and nowhere near done, unfortunately.

Jan Rieke

unread,
Oct 9, 2018, 7:11:34 AM10/9/18
to Project Lombok
Just let me know if I can assist somewhere.
Reply all
Reply to author
Forward
0 new messages