projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.81k stars 2.37k forks source link

[BUG] @SuperBuilder does not check if build method is already defined in abstract Builder #3418

Open irnbrux opened 1 year ago

irnbrux commented 1 year ago

The @SuperBuilder does not check if build method is already defined in abstract Builder

This code does not compile because @SuperBuilder adds another public abstract C build(); into the Builder:

import lombok.experimental.SuperBuilder;
@SuperBuilder
public class SomeClass {
    public static abstract class SomeClassBuilder<C extends SomeClass, B extends SomeClassBuilder<C,B>> {
        public C build() {
            //do something, just example
            return null; 
        }
    }
}

Compiler error:

method build() is already defined in class SomeClassBuilder

Here is the corresponding delombok code:

public class SomeClass {

    public static abstract class SomeClassBuilder<C extends SomeClass, B extends SomeClassBuilder<C, B>> {
        public C build() {
            //do something
            return (C) new SomeClass(this);
        }

        protected abstract B self();

        public abstract C build();        // <----- added by @SuperBuilder

        @Override
        public String toString() {
            return "SomeClass.SomeClassBuilder()";
        }
    }

    private static final class SomeClassBuilderImpl extends SomeClass.SomeClassBuilder<SomeClass, SomeClass.SomeClassBuilderImpl> {
        private SomeClassBuilderImpl() { }
        @Override
        protected SomeClass.SomeClassBuilderImpl self() {
            return this;
        }
        @Override
        public SomeClass build() {
            return new SomeClass(this);
        }
    }
    protected SomeClass(final SomeClass.SomeClassBuilder<?, ?> b) {
    }
    public static SomeClass.SomeClassBuilder<?, ?> builder() {
        return new SomeClass.SomeClassBuilderImpl();
    }
}

The expected result is, that @SuperBuilder does not add build() method to Builder in case another method with name "build()" is already present. Ideally also a warning can be raised in order to make aware of the fact a build() method is already present.

lombok: 1.18.26 openjdk version "14.0.2" 2020-07-14 OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)

Thanks.

Cheers Brian

janrieke commented 1 year ago

So what's the requirement here? You want access to the builder's fields before calling the constructor, and that's not possible because they are private? But why can't you do that in your constructor?

I'm asking because your suggested solution won't work: Your custom build method in the abstract class will never be called, even if you could add it.