Randgalt / record-builder

Record builder generator for Java records
Apache License 2.0
758 stars 55 forks source link

aa027af causes compile errors #129

Open mads-b opened 2 years ago

mads-b commented 2 years ago

Hello, The aforementioned commit is preventing me from upgrading from v33 to v34. The issue:

I have a quite simple record which should create a builder:

public record CombinedFields(
    @JsonValue String combinedField,
    List<CombinedFieldsLine> lines) implements CombinedFieldsBuilder.Bean {}

But now, the generated builder contains a setter with an undefined method (shim?)

    /**
     * Re-create the internally allocated {@code List<CombinedFields.CombinedFieldsLine>} for {@code lines} by copying the argument
     */
    @Generated("io.soabase.recordbuilder.core.RecordBuilder")
    public CombinedFieldsBuilder setLines(
            Collection<? extends CombinedFields.CombinedFieldsLine> lines) {
        this.lines = __list(lines);
        return this;
    }

It's this __list method that does not exist. Is this a bug or something I need to change in my configuration?

Randgalt commented 2 years ago

Can you please post the entire source for CombinedFields so we can have a complete test case? In particular, we need to know the RecordBuilder.Options being used.

mads-b commented 2 years ago

Hi, my Options follows. I made this custom annotation for it to avoid repetition

@RecordBuilder.Template(options = @RecordBuilder.Options(
    enableWither = false,
    enableGetters = false,
    addConcreteSettersForOptional = true,
    addSingleItemCollectionBuilders = true,
    booleanPrefix = "is",
    getterPrefix = "get",
    setterPrefix = "set",
    beanClassName = "Bean"))
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@Inherited
public @interface RecordStyle {

}
Randgalt commented 2 years ago

It seems this was only tested when useImmutableCollections=true was also used. What do you think about addSingleItemCollectionBuilders = true also implying useImmutableCollections=true?

freelon commented 2 years ago

Sidenote: the JavaDoc for the setter methods also mentions the creation of a copy of the collection instead of just setting it: * Re-create the internally allocated {@code Set<T>} for {@code mySet} by copying the argument That should be adjusted as well if useImmutableCollections = false.

Randgalt commented 2 years ago

@tmichel any thoughts on this?

Randgalt commented 2 years ago

@tmichel are you around? I'd appreciate your thoughts on this issue.

tmichel commented 2 years ago

I feel that one setting implying another is really not intuitive. If possible any combination of options should work. Although I believe the implementation complexity comes from the interaction of features.

I believe when the addSingleItemCollectionBuilders is true the builder should maintain its own collection instance. The setter method breaks encapsulation in this case so maybe remove the option to overwrite the collection and only allow adding and clearing items. Then even the performance characteristics are clearer.

Basically instead of builder.setLines(...) only allow builder.clearLines().addLines(iterable).

I know that this is a breaking change in the API so this might not be so straightforward to introduce. I could see that if addSingleItemCollectionBuilders causes this many issues then it could be deprecated and a different option be introduced so that single collection builders and simple setters generate two distinct builder APIs. I guess the option could be useSingleItemCollectionBuilders.

useImmutableCollections should only affect whether the final collection during the build is an immutable copy of the internal collection or not.

Randgalt commented 2 years ago

Hey folks - please review https://github.com/Randgalt/record-builder/pull/130