diff --git a/value-fixture/src/org/immutables/fixture/builder/ForLambdaBuilder.java b/value-fixture/src/org/immutables/fixture/builder/ForLambdaBuilder.java new file mode 100644 index 000000000..da1abd00b --- /dev/null +++ b/value-fixture/src/org/immutables/fixture/builder/ForLambdaBuilder.java @@ -0,0 +1,12 @@ +package org.immutables.fixture.builder; + +import org.immutables.fixture.builder.attribute_builders.FirstPartyImmutable; +import org.immutables.fixture.builder.attribute_builders.ThirdPartyImmutable; +import org.immutables.value.Value; + +@Value.Immutable +@Value.Style(attributeBuilderDetection = true) +public interface ForLambdaBuilder { + FirstPartyImmutable firstPartyImmutable(); + ThirdPartyImmutable thirdPartyImmutable(); +} diff --git a/value-fixture/test/org/immutables/fixture/builder/AttributeBuilderTest.java b/value-fixture/test/org/immutables/fixture/builder/AttributeBuilderTest.java index 3cfbb9fbc..39facb945 100644 --- a/value-fixture/test/org/immutables/fixture/builder/AttributeBuilderTest.java +++ b/value-fixture/test/org/immutables/fixture/builder/AttributeBuilderTest.java @@ -58,6 +58,17 @@ public void toBuilderSandwich() { check(instance.a()).is(2); } + @Test + public void lambdaBuilder() { + ForLambdaBuilder l = ImmutableForLambdaBuilder.builder() + .firstPartyImmutable(b -> b.value("X")) + .thirdPartyImmutable(b -> b.setValue("Y")) + .build(); + + check(l.firstPartyImmutable().value()).is("X"); + check(l.thirdPartyImmutable().getValue()).is("Y"); + } + @Test public void basicApiForVanillaParent() { assertBasicApi(ImmutableVanillaAttributeBuilderParent.class, diff --git a/value-processor/src/org/immutables/value/processor/Immutables.generator b/value-processor/src/org/immutables/value/processor/Immutables.generator index 0a1e8ac94..595b25580 100644 --- a/value-processor/src/org/immutables/value/processor/Immutables.generator +++ b/value-processor/src/org/immutables/value/processor/Immutables.generator @@ -1787,6 +1787,24 @@ checkNotIsSet([v.names.isSet](), "[v.names.raw]"); } [if v.isAttributeBuilder] + /** + * Initialized [sourceDocRef v] using lambda (consumer) which receives builder instance for the attribute value. + * + * Once called, the attribute builder field is set to a new instance of the builder. + * If called more than once, returns the same builder instance. + */ + [eachLine v.builderAttributeAnnotation] + [deprecation v] + [builderInitAccess v]final [builderReturnType type] [v.names.init](java.util.function.Consumer<[attributeBuilderBuilderType v.getAttributeBuilderDescriptor]> consumer) { + if (this.[v.name] == null) { + this.[v.name] = [createAttributeBuilder v.getAttributeBuilderDescriptor]; + } + [nondefaultSetInBuilder v] + [mandatorySetInBuilder v] + consumer.accept(this.[v.name]); + return [builderReturnThis type]; + } + /** * Returns a builder for [sourceDocRef v]. * @@ -2101,6 +2119,24 @@ checkNotIsSet([v.names.isSet](), "[v.names.raw]"); } [if v.isAttributeBuilder] + /** + * Initialized [sourceDocRef v] using lambda (consumer) which receives builder instance for the attribute value. + * + * Once called, the attribute builder field is set to a new instance of the builder. + * If called more than once, returns the same builder instance. + */ + [eachLine v.builderAttributeAnnotation] + [deprecation v] + [builderInitAccess v]final [builderReturnType type] [v.names.init](java.util.function.Consumer<[attributeBuilderBuilderType v.getAttributeBuilderDescriptor]> consumer) { + if (this.[v.name] == null) { + this.[v.name] = [createAttributeBuilder v.getAttributeBuilderDescriptor]; + } + [nondefaultSetInBuilder v] + [mandatorySetInBuilder v] + consumer.accept(this.[v.name]); + return [builderReturnThis type]; + } + /** * Returns a builder for [sourceDocRef v]. *