[BUG][DART] PATCH tri-state optional handling - #23696
Conversation
|
cc @jaumard (2018/09) @josh-burton (2019/12) @amondnet (2019/12) @sbu-WBT (2020/12) @kuhnroyal (2020/12) @agilob (2020/12) @ahmednfwela (2021/08) |
The outer Optional should never be null—only the inner value can be null. Field type should be Optional<T?>, not Optional<T?>? This fixes compilation errors when serializer tries to access .isPresent on a potentially null Optional.
|
Just want to add an independent real-world repro that confirms this fix is needed and validates the root cause. We generate a
This isn't limited to one model. It affects every generated model that has at least one optional field, since Minimal repro against a generated client: final result = standardSerializers.deserialize(
jsonDecode(jsonResponseBody),
specifiedType: const FullType(SomeGeneratedResponseModel),
);
// Bad state: No serializer for 'Optional<String?>'.Looking at the diff here, |
Summary
Adds minimal PATCH tri-state handling for
dart-diowithbuilt_valueserialization.This fixes the PATCH case where the generator needs to preserve three distinct states for nullable fields:
nullThe PR is intentionally scoped to the serialization path only to keep review risk low.
Changes
x-has-optional-propertiesoptional.dartwhenuseOptional=trueoptional.dartin generated built_value models when neededOptional.absent()object.field.isPresentnullwhen the present wrapped value isnullValidation
Validated locally with:
Build result: success.
Also validated by generating a Dart Dio sample from the built CLI jar. Generation completed successfully.
./mvnw clean package with tests enabled hit unrelated existing Kotlin Spring test failures on the local Java 25 environment, so this PR was validated through successful package build and Dart generation behavior.
How to validate
/cc @wing328 @jaumard
Summary by cubic
Fixes PATCH tri-state handling in
dart-diowithbuilt_value, covering both serialization and deserialization so optional fields support absent, present-null, and present-value without mis-serialization.Optionaland default toOptional.absent(); keep the outerOptionalnon-null (Optional<T?>, notOptional<T?>?).isPresent; writenullfor present-with-null.Optional.present(value)(includingnull), keepOptional.absent()when the key is missing; use unwrapped FullType metadata viax-unwrapped-datatype/x-unwrapped-datatype-nullable.optional.dartwhenuseOptional=trueand import it only for models withx-has-optional-properties; avoid whitespace-only template churn.Written for commit 70b3b61. Summary will update on new commits.