diff --git a/README.md b/README.md
index d6cbf1e..1ad8d2d 100644
--- a/README.md
+++ b/README.md
@@ -124,6 +124,15 @@ preventing issues that arise from improperly constructed objects.
public class Car {
```
+Another `ConstructorPolicy` that also enforces all the parameters to be set, but less strictly is
+`ENFORCED_ALLOW_NULLS`. By using this policy, you enforce all variables to be set,
+but you can also set them to null, which is not allowed when using `ENFORCED`.
+
+```java
+@Buildable(constructorPolicy = ENFORCED_ALLOW_NULLS)
+public class Car {
+```
+
### Mandatory Fields
Fields can be designated as mandatory;
diff --git a/annotations/src/main/java/io/jonasg/bob/Buildable.java b/annotations/src/main/java/io/jonasg/bob/Buildable.java
index 4cb23f2..b802194 100644
--- a/annotations/src/main/java/io/jonasg/bob/Buildable.java
+++ b/annotations/src/main/java/io/jonasg/bob/Buildable.java
@@ -59,7 +59,11 @@
* fields. Alternatively,
* setting this to {@link ConstructorPolicy#ENFORCED} requires all fields to be
* explicitly set, otherwise,
- * the builder throws an exception.
+ * the builder throws an exception.
+ * Setting it to {@link ConstructorPolicy#ENFORCED_ALLOW_NULLS} requires all
+ * fields
+ * to be explicitly set, otherwise the builder throws an exception. But by using
+ * this policy, null can also be set.
*
*
* @return the constructor policy used by the builder
diff --git a/annotations/src/main/java/io/jonasg/bob/ConstructorPolicy.java b/annotations/src/main/java/io/jonasg/bob/ConstructorPolicy.java
index d8b14b8..4d61759 100644
--- a/annotations/src/main/java/io/jonasg/bob/ConstructorPolicy.java
+++ b/annotations/src/main/java/io/jonasg/bob/ConstructorPolicy.java
@@ -23,6 +23,17 @@ public enum ConstructorPolicy {
*/
ENFORCED,
+ /**
+ * Requires all fields
+ * to be explicitly set with a concrete value or {@code null} in the
+ * constructor.
+ * If any field is not set, the builder will throw an exception.
+ * The main difference with {@link ConstructorPolicy#ENFORCED} is that fields
+ * are considered
+ * to be set to, even if set explicitly to {@code null}
+ */
+ ENFORCED_ALLOW_NULLS,
+
/**
* Allows the object to be constructed even if not all constructor parameters
* have
diff --git a/annotations/src/main/java/io/jonasg/bob/NotNullableRequiredField.java b/annotations/src/main/java/io/jonasg/bob/NotNullableRequiredField.java
new file mode 100644
index 0000000..cf1e3e9
--- /dev/null
+++ b/annotations/src/main/java/io/jonasg/bob/NotNullableRequiredField.java
@@ -0,0 +1,36 @@
+package io.jonasg.bob;
+
+/**
+ * Container Object for a required field and its value that cannot be set as null
+ *
+ * @param
+ * the type of the required field its value
+ */
+@SuppressWarnings("unused")
+public final class NotNullableRequiredField implements RequiredField {
+
+ private T fieldValue;
+
+ private final String fieldName;
+
+ private final String typeName;
+
+ NotNullableRequiredField(T fieldValue, String fieldName, String typeName) {
+ this.fieldValue = fieldValue;
+ this.fieldName = fieldName;
+ this.typeName = typeName;
+ }
+
+ @Override
+ public void set(T value) {
+ this.fieldValue = value;
+ }
+
+ @Override
+ public T orElseThrow() {
+ if (fieldValue == null) {
+ throw new MandatoryFieldMissingException(fieldName, typeName);
+ }
+ return fieldValue;
+ }
+}
diff --git a/annotations/src/main/java/io/jonasg/bob/NullableRequiredField.java b/annotations/src/main/java/io/jonasg/bob/NullableRequiredField.java
new file mode 100644
index 0000000..86191e9
--- /dev/null
+++ b/annotations/src/main/java/io/jonasg/bob/NullableRequiredField.java
@@ -0,0 +1,39 @@
+package io.jonasg.bob;
+
+/**
+ * Container Object for a required field and its value that can be set as null
+ *
+ * @param
+ * the type of the required field its value
+ */
+@SuppressWarnings("unused")
+public class NullableRequiredField implements RequiredField {
+
+ private T fieldValue;
+
+ private boolean fieldSet;
+
+ private final String fieldName;
+
+ private final String typeName;
+
+ public NullableRequiredField(T fieldValue, String fieldName, String typeName) {
+ this.fieldValue = fieldValue;
+ this.fieldName = fieldName;
+ this.typeName = typeName;
+ }
+
+ @Override
+ public void set(T value) {
+ this.fieldValue = value;
+ fieldSet = true;
+ }
+
+ @Override
+ public T orElseThrow() {
+ if (!fieldSet && fieldValue == null) {
+ throw new MandatoryFieldMissingException(fieldName, typeName);
+ }
+ return fieldValue;
+ }
+}
diff --git a/annotations/src/main/java/io/jonasg/bob/RequiredField.java b/annotations/src/main/java/io/jonasg/bob/RequiredField.java
index ce42415..cb19e5e 100644
--- a/annotations/src/main/java/io/jonasg/bob/RequiredField.java
+++ b/annotations/src/main/java/io/jonasg/bob/RequiredField.java
@@ -1,38 +1,17 @@
package io.jonasg.bob;
-/**
- * Container Object for a required field and its value
- *
- * @param
- * the type of the required field its value
- */
-@SuppressWarnings("unused")
-public final class RequiredField {
+public interface RequiredField {
- private T fieldValue;
-
- private final String fieldName;
-
- private final String typeName;
-
- private RequiredField(T fieldValue, String fieldName, String typeName) {
- this.fieldValue = fieldValue;
- this.fieldName = fieldName;
- this.typeName = typeName;
+ static RequiredField notNullableOfNameWithinType(String fieldName, String typeName) {
+ return new NotNullableRequiredField<>(null, fieldName, typeName);
}
- public static RequiredField ofNameWithinType(String fieldName, String typeName) {
- return new RequiredField<>(null, fieldName, typeName);
+ static RequiredField nullableOfNameWithinType(String fieldName, String typeName) {
+ return new NullableRequiredField<>(null, fieldName, typeName);
}
- public void set(T value) {
- this.fieldValue = value;
- }
+ void set(T value);
+
+ T orElseThrow();
- public T orElseThrow() {
- if (fieldValue == null) {
- throw new MandatoryFieldMissingException(fieldName, typeName);
- }
- return fieldValue;
- }
}
diff --git a/annotations/src/test/java/io/jonasg/bob/RequiredFieldTest.java b/annotations/src/test/java/io/jonasg/bob/RequiredFieldTest.java
index 995db90..27502da 100644
--- a/annotations/src/test/java/io/jonasg/bob/RequiredFieldTest.java
+++ b/annotations/src/test/java/io/jonasg/bob/RequiredFieldTest.java
@@ -2,36 +2,101 @@
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
class RequiredFieldTest {
- @Test
- void throwIllegalBuildExceptionWhenFieldValueIsNotSet() {
- // given
- RequiredField nameField = RequiredField.ofNameWithinType("name", "Person");
+ @Nested
+ class NotNullableRequiredFieldTest {
- // when
- ThrowingCallable whenOrElseThrowIsCalled = nameField::orElseThrow;
+ @Test
+ void throwIllegalBuildExceptionWhenFieldValueIsNotSet() {
+ // given
+ RequiredField nameField = RequiredField.notNullableOfNameWithinType("name", "Person");
- // then
- Assertions.assertThatThrownBy(whenOrElseThrowIsCalled)
- .isInstanceOf(MandatoryFieldMissingException.class)
- .hasMessage("Mandatory field (name) not set when building type (Person)");
- }
+ // when
+ ThrowingCallable whenOrElseThrowIsCalled = nameField::orElseThrow;
+
+ // then
+ Assertions.assertThatThrownBy(whenOrElseThrowIsCalled)
+ .isInstanceOf(MandatoryFieldMissingException.class)
+ .hasMessage("Mandatory field (name) not set when building type (Person)");
+ }
+
+ @Test
+ void returnFieldValue() {
+ // given
+ RequiredField nameField = RequiredField.notNullableOfNameWithinType("name", "Person");
+ nameField.set("John");
+
+ // when
+ String value = nameField.orElseThrow();
- @Test
- void returnFieldValue() {
- // given
- RequiredField nameField = RequiredField.ofNameWithinType("name", "Person");
- nameField.set("John");
+ // then
+ Assertions.assertThat(value)
+ .isEqualTo("John");
+ }
- // when
- String value = nameField.orElseThrow();
+ @Test
+ void returnFieldValueWhenSetToNull() {
+ // given
+ RequiredField nameField = RequiredField.notNullableOfNameWithinType("name", "Person");
+ nameField.set(null);
- // then
- Assertions.assertThat(value)
- .isEqualTo("John");
+ // when
+ ThrowingCallable whenOrElseThrowIsCalled = nameField::orElseThrow;
+
+ // then
+ Assertions.assertThatThrownBy(whenOrElseThrowIsCalled)
+ .isInstanceOf(MandatoryFieldMissingException.class)
+ .hasMessage("Mandatory field (name) not set when building type (Person)");
+ }
}
+ @Nested
+ class NullableRequiredFieldTest {
+
+ @Test
+ void throwIllegalBuildExceptionWhenFieldValueIsNotSet() {
+ // given
+ RequiredField nameField = RequiredField.nullableOfNameWithinType("name", "Person");
+
+ // when
+ ThrowingCallable whenOrElseThrowIsCalled = nameField::orElseThrow;
+
+ // then
+ Assertions.assertThatThrownBy(whenOrElseThrowIsCalled)
+ .isInstanceOf(MandatoryFieldMissingException.class)
+ .hasMessage("Mandatory field (name) not set when building type (Person)");
+ }
+
+ @Test
+ void returnFieldValue() {
+ // given
+ RequiredField nameField = RequiredField.nullableOfNameWithinType("name", "Person");
+ nameField.set("John");
+
+ // when
+ String value = nameField.orElseThrow();
+
+ // then
+ Assertions.assertThat(value)
+ .isEqualTo("John");
+ }
+
+ @Test
+ void returnFieldValueWhenSetToNull() {
+ // given
+ RequiredField nameField = RequiredField.nullableOfNameWithinType("name", "Person");
+ nameField.set(null);
+
+ // when
+ String value = nameField.orElseThrow();
+
+ // then
+ Assertions.assertThat(value)
+ .isEqualTo(null);
+ }
+ }
}
diff --git a/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java b/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java
index 6d6043e..89642e4 100644
--- a/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java
+++ b/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java
@@ -116,12 +116,16 @@ private List generateSetters() {
}
protected MethodSpec generateSetterForField(BuildableField field) {
+
var builder = MethodSpec.methodBuilder(setterName(field.fieldName()))
.addModifiers(Modifier.PUBLIC)
.returns(builderType())
.addParameter(TypeName.get(field.type()), field.fieldName());
- if (field.isConstructorArgument() && isEnforcedConstructorPolicy() || field.isMandatory()) {
+ if (field.isConstructorArgument() && isAnEnforcedConstructorPolicy() || field.isMandatory()) {
builder.addStatement("this.$L.set($L)", field.fieldName(), field.fieldName());
+ if (isEnforcedAllowNullsConstructorPolicy()) {
+ builder.addStatement("this.fieldSet = true");
+ }
} else {
builder.addStatement("this.$L = $L", field.fieldName(), field.fieldName());
}
@@ -129,24 +133,41 @@ protected MethodSpec generateSetterForField(BuildableField field) {
.build();
}
+ private boolean isAnEnforcedConstructorPolicy() {
+ return this.buildable.constructorPolicy().equals(ConstructorPolicy.ENFORCED) ||
+ this.buildable.constructorPolicy().equals(ConstructorPolicy.ENFORCED_ALLOW_NULLS);
+ }
+
private boolean isEnforcedConstructorPolicy() {
return this.buildable.constructorPolicy().equals(ConstructorPolicy.ENFORCED);
}
+ private boolean isEnforcedAllowNullsConstructorPolicy() {
+ return this.buildable.constructorPolicy().equals(ConstructorPolicy.ENFORCED_ALLOW_NULLS);
+ }
+
private List generateFields() {
- return buildableFields.stream()
+ var fieldSpecs = new ArrayList<>(buildableFields.stream()
.map(this::generateField)
- .toList();
+ .toList());
+
+ if (isEnforcedAllowNullsConstructorPolicy()) {
+ fieldSpecs.add(FieldSpec.builder(TypeName.BOOLEAN, "fieldSet", Modifier.PRIVATE).build());
+ }
+ return fieldSpecs;
}
protected FieldSpec generateField(BuildableField field) {
- if ((field.isConstructorArgument() && isEnforcedConstructorPolicy()) || field.isMandatory()) {
+ if (field.isConstructorArgument() && isAnEnforcedConstructorPolicy() || field.isMandatory()) {
+ String methodName = this.buildable.constructorPolicy().equals(ConstructorPolicy.ENFORCED)
+ ? "notNullableOfNameWithinType"
+ : "nullableOfNameWithinType";
return FieldSpec
.builder(ParameterizedTypeName.get(ClassName.get(RequiredField.class),
TypeName.get(boxedType(field.type()))), field.fieldName(), Modifier.PRIVATE,
Modifier.FINAL)
- .initializer("$T.ofNameWithinType(\"" + field.fieldName() + "\", \""
- + this.typeDefinition.typeName() + "\")", RequiredField.class)
+ .initializer("$T.$L(\"" + field.fieldName() + "\", \""
+ + this.typeDefinition.typeName() + "\")", RequiredField.class, methodName)
.build();
} else {
return FieldSpec.builder(TypeName.get(field.type()), field.fieldName(), Modifier.PRIVATE)
@@ -189,7 +210,7 @@ protected String toConstructorCallingStatement(ConstructorDefinition constructor
return constructorDefinition.parameters().stream()
.map(param -> this.buildableFields.stream().anyMatch(f -> Objects.equals(f.fieldName(), param.name()))
? String.format("%s%s", param.name(),
- buildable.constructorPolicy().equals(ConstructorPolicy.ENFORCED) ? ".orElseThrow()"
+ isAnEnforcedConstructorPolicy() ? ".orElseThrow()"
: "")
: defaultForType(param.type()))
.collect(Collectors.joining(", "));
@@ -209,7 +230,7 @@ private void createConstructorAndSetterAwareBuildMethod(Builder builder) {
}
protected CodeBlock generateFieldAssignment(BuildableField field) {
- if (field.isConstructorArgument() && isEnforcedConstructorPolicy() || field.isMandatory()) {
+ if (field.isConstructorArgument() && isAnEnforcedConstructorPolicy() || field.isMandatory()) {
return CodeBlock.builder()
.addStatement("instance.$L(this.$L.orElseThrow())",
setterName(field.setterMethodName().orElseThrow()), field.fieldName())
diff --git a/processor/src/test/java/io/jonasg/bob/BobFeaturesTests.java b/processor/src/test/java/io/jonasg/bob/BobFeaturesTests.java
index 6f86da8..bf26eae 100644
--- a/processor/src/test/java/io/jonasg/bob/BobFeaturesTests.java
+++ b/processor/src/test/java/io/jonasg/bob/BobFeaturesTests.java
@@ -259,6 +259,26 @@ void constructorParametersAreEnforcedWhenConstructorPolicyIsEnforced() {
.executeTest();
}
+ @Test
+ void constructorParametersAreEnforcedAndNullableWhenConstructorPolicyIsEnforcedAllowNulls() {
+ Cute.blackBoxTest()
+ .given()
+ .processors(List.of(BuildableProcessor.class))
+ .andSourceFiles(
+ "/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java")
+ .whenCompiled()
+ .thenExpectThat()
+ .compilationSucceeds()
+ .andThat()
+ .generatedSourceFile(
+ "io.jonasg.bob.test.builder.ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder")
+ .matches(
+ CuteApi.ExpectedFileObjectMatcherKind.BINARY,
+ JavaFileObjectUtils.readFromResource(
+ "/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java"))
+ .executeTest();
+ }
+
@Test
void markThroughTopLevelAnnotationThatIndividualFieldsAsMandatoryWhenInPermissiveMode() {
Cute.blackBoxTest()
diff --git a/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced.java b/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced.java
index df7ec44..20df0ca 100644
--- a/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced.java
+++ b/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced.java
@@ -6,9 +6,9 @@
import java.lang.String;
public final class ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedBuilder {
- private final RequiredField make = RequiredField.ofNameWithinType("make", "ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced");
+ private final RequiredField make = RequiredField.notNullableOfNameWithinType("make", "ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced");
- private final RequiredField year = RequiredField.ofNameWithinType("year", "ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced");
+ private final RequiredField year = RequiredField.notNullableOfNameWithinType("year", "ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforced");
private double engineSize;
diff --git a/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java b/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java
new file mode 100644
index 0000000..a5a0218
--- /dev/null
+++ b/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java
@@ -0,0 +1,52 @@
+package io.jonasg.bob.test;
+
+import io.jonasg.bob.Buildable;
+import io.jonasg.bob.ConstructorPolicy;
+import java.lang.String;
+import java.lang.Integer;
+
+@Buildable(constructorPolicy = ConstructorPolicy.ENFORCED_ALLOW_NULLS)
+public class ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls {
+ private String make;
+
+ private int year;
+
+ private double engineSize;
+
+ private boolean isElectric;
+
+ private float fuelEfficiency;
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls() {
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls(String make, int year) {
+ this.make = make;
+ this.year = year;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls setEngineSize(double engineSize) {
+ this.engineSize = engineSize;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls setIsElectric(boolean isElectric) {
+ isElectric = isElectric;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls setFuelEfficiency(float fuelEfficiency) {
+ this.fuelEfficiency = fuelEfficiency;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls setMake(String make) {
+ this.make = make;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls setYear(int year) {
+ this.year = year;
+ return this;
+ }
+}
diff --git a/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java b/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java
new file mode 100644
index 0000000..e4df25b
--- /dev/null
+++ b/processor/src/test/resources/tests/successful-compilation/ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls/Expected_ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls.java
@@ -0,0 +1,63 @@
+package io.jonasg.bob.test.builder;
+
+import io.jonasg.bob.RequiredField;
+import io.jonasg.bob.test.ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls;
+import java.lang.Integer;
+import java.lang.String;
+
+public final class ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder {
+ private final RequiredField make = RequiredField.nullableOfNameWithinType("make", "ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls");
+
+ private final RequiredField year = RequiredField.nullableOfNameWithinType("year", "ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls");
+
+ private double engineSize;
+
+ private boolean isElectric;
+
+ private float fuelEfficiency;
+
+ private boolean fieldSet;
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder() {
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder make(
+ String make) {
+ this.make.set(make);
+ this.fieldSet = true;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder year(
+ int year) {
+ this.year.set(year);
+ this.fieldSet = true;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder engineSize(
+ double engineSize) {
+ this.engineSize = engineSize;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder isElectric(
+ boolean isElectric) {
+ this.isElectric = isElectric;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNullsBuilder fuelEfficiency(
+ float fuelEfficiency) {
+ this.fuelEfficiency = fuelEfficiency;
+ return this;
+ }
+
+ public ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls build() {
+ var instance = new ConstructorParametersAreEnforcedWhenConstructorPolicyIsEnforcedAllowNulls(make.orElseThrow(), year.orElseThrow());
+ instance.setEngineSize(this.engineSize);
+ instance.setIsElectric(this.isElectric);
+ instance.setFuelEfficiency(this.fuelEfficiency);
+ return instance;
+ }
+}
diff --git a/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java b/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java
index 1b0c64f..8adbb58 100644
--- a/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java
+++ b/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java
@@ -9,11 +9,11 @@
public final class MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveModeBuilder {
private String make;
- private final RequiredField year = RequiredField.ofNameWithinType("year", "MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
+ private final RequiredField year = RequiredField.nullableOfNameWithinType("year", "MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
private double engineSize;
- private final RequiredField fuelEfficiency = RequiredField.ofNameWithinType("fuelEfficiency", "MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
+ private final RequiredField fuelEfficiency = RequiredField.nullableOfNameWithinType("fuelEfficiency", "MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
public MarkFieldAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveModeBuilder() {
}
diff --git a/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java b/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java
index 92942d6..c417003 100644
--- a/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java
+++ b/processor/src/test/resources/tests/successful-compilation/MarkIndividualFieldsAsMandatory/Expected_MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode.java
@@ -9,11 +9,11 @@
public final class MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveModeBuilder {
private String make;
- private final RequiredField year = RequiredField.ofNameWithinType("year", "MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
+ private final RequiredField year = RequiredField.nullableOfNameWithinType("year", "MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
private double engineSize;
- private final RequiredField fuelEfficiency = RequiredField.ofNameWithinType("fuelEfficiency", "MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
+ private final RequiredField fuelEfficiency = RequiredField.nullableOfNameWithinType("fuelEfficiency", "MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveMode");
public MarkThroughTopLevelAnnotationThatIndividualFieldsAreMandatoryWhenInPermissiveModeBuilder(
) {