From 63688c37f00856234dee0ff4b4ca6c2d458fc89e Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 11:25:05 +0100 Subject: [PATCH 01/11] add datetime support --- pkg/json/CHANGELOG.md | 4 ++++ pkg/json/lib/json.dart | 12 ++++++++++++ pkg/json/pubspec.yaml | 2 +- pkg/json/test/json_codable_test.dart | 6 ++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pkg/json/CHANGELOG.md b/pkg/json/CHANGELOG.md index cfbb0bad53f8..a7c985732d58 100644 --- a/pkg/json/CHANGELOG.md +++ b/pkg/json/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.20.3 + +- Add support for DateTime + # 0.20.2 - Fix generated code syntax error when defining fields containing the dollar sign `$` by using raw strings. diff --git a/pkg/json/lib/json.dart b/pkg/json/lib/json.dart index bcf237f7a7aa..9c9dded5fb16 100644 --- a/pkg/json/lib/json.dart +++ b/pkg/json/lib/json.dart @@ -378,6 +378,16 @@ mixin _FromJson on _Shared { ' as ', type.code, ]); + case 'DateTime': + return RawCode.fromParts([ + if (nullCheck != null) nullCheck, + await builder.resolveIdentifier(_dartCore, 'DateTime'), + '.parse(', + jsonReference, + ' as ', + introspectionData.stringCode, + ')' + ]); } } @@ -624,6 +634,8 @@ mixin _ToJson on _Shared { ]); case 'int' || 'double' || 'num' || 'String' || 'bool': return valueReference; + case 'DateTime': + return RawCode.fromParts([valueReference, '.toIso8601String()']); } } diff --git a/pkg/json/pubspec.yaml b/pkg/json/pubspec.yaml index 98a28ee251f4..e2eb306c0d6b 100644 --- a/pkg/json/pubspec.yaml +++ b/pkg/json/pubspec.yaml @@ -5,7 +5,7 @@ description: > `toJson` encoding method. repository: https://github.com/dart-lang/sdk/tree/main/pkg/json -version: 0.20.2 +version: 0.20.3 environment: sdk: ^3.6.0-edge dependencies: diff --git a/pkg/json/test/json_codable_test.dart b/pkg/json/test/json_codable_test.dart index b18c3320df33..21f332aec91c 100644 --- a/pkg/json/test/json_codable_test.dart +++ b/pkg/json/test/json_codable_test.dart @@ -16,6 +16,7 @@ void main() { 'intField': 10, 'doubleField': 12.5, 'numField': 11, + 'dateTimeField': '2024-11-11T03:42:29.108308', 'listOfSerializableField': [ {'x': 1}, ], @@ -104,6 +105,7 @@ void main() { expect(b.nullableListOfSerializableField, null); expect(b.nullableMapOfSerializableField, null); expect(b.nullableSetOfSerializableField, null); + expect(b.nullableDateTimeField, null); expect(b.toJson(), isEmpty); }); @@ -228,6 +230,8 @@ class A { final Set setOfSerializableField; final Map mapOfSerializableField; + + final DateTime dateTimeField; } @JsonCodable() @@ -247,6 +251,8 @@ class B { final Set? nullableSetOfSerializableField; final Map? nullableMapOfSerializableField; + + final DateTime? nullableDateTimeField; } @JsonCodable() From 3248cbda786e27f8b1c596d408f175dd39f29b5e Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 12:32:54 +0100 Subject: [PATCH 02/11] actually add the test --- pkg/json/test/json_codable_test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/json/test/json_codable_test.dart b/pkg/json/test/json_codable_test.dart index 21f332aec91c..7d6f83e58333 100644 --- a/pkg/json/test/json_codable_test.dart +++ b/pkg/json/test/json_codable_test.dart @@ -34,6 +34,7 @@ void main() { expect(a.intField, 10); expect(a.doubleField, 12.5); expect(a.numField, 11); + expect(a.dateTimeField, DateTime.parse('2024-11-11T03:42:29.108308')); expect(a.listOfSerializableField.single.x, 1); expect(a.setOfSerializableField.single.x, 2); expect(a.mapOfSerializableField['c']!.x, 3); From d6ec0f830a4c1d7a3b86887ddd614d196a528c9a Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 12:41:06 +0100 Subject: [PATCH 03/11] add tests --- pkg/json/test/json_codable_test.dart | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/json/test/json_codable_test.dart b/pkg/json/test/json_codable_test.dart index 7d6f83e58333..4bd6874b8fc4 100644 --- a/pkg/json/test/json_codable_test.dart +++ b/pkg/json/test/json_codable_test.dart @@ -49,6 +49,7 @@ void main() { 'nullableIntField': 9, 'nullableDoubleField': 11.5, 'nullableNumField': 11.1, + 'nullableDateTimeField': '2024-11-11T03:42:29.108308', 'nullableListOfSerializableField': [ {'x': 1}, ], @@ -66,6 +67,8 @@ void main() { expect(b.nullableIntField, 9); expect(b.nullableDoubleField, 11.5); expect(b.nullableNumField, 11.1); + expect(b.nullableDateTimeField, + DateTime.parse('2024-11-11T03:42:29.108308')); expect(b.nullableListOfSerializableField!.single.x, 1); expect(b.nullableSetOfSerializableField!.single.x, 2); expect(b.nullableMapOfSerializableField!['d']!.x, 3); @@ -80,6 +83,7 @@ void main() { 'nullableIntField': null, 'nullableDoubleField': null, 'nullableNumField': null, + 'nullableDateTimeField': null, 'nullableListOfSerializableField': null, 'nullableSetOfSerializableField': null, 'nullableMapOfSerializableField': null, @@ -89,6 +93,7 @@ void main() { expect(b.nullableIntField, null); expect(b.nullableDoubleField, null); expect(b.nullableNumField, null); + expect(b.nullableDateTimeField, null); expect(b.nullableListOfSerializableField, null); expect(b.nullableMapOfSerializableField, null); expect(b.nullableSetOfSerializableField, null); @@ -103,6 +108,7 @@ void main() { expect(b.nullableIntField, null); expect(b.nullableDoubleField, null); expect(b.nullableNumField, null); + expect(b.nullableDateTimeField, null); expect(b.nullableListOfSerializableField, null); expect(b.nullableMapOfSerializableField, null); expect(b.nullableSetOfSerializableField, null); @@ -226,13 +232,13 @@ class A { final num numField; + final DateTime dateTimeField; + final List listOfSerializableField; final Set setOfSerializableField; final Map mapOfSerializableField; - - final DateTime dateTimeField; } @JsonCodable() @@ -247,13 +253,13 @@ class B { final num? nullableNumField; + final DateTime? nullableDateTimeField; + final List? nullableListOfSerializableField; final Set? nullableSetOfSerializableField; final Map? nullableMapOfSerializableField; - - final DateTime? nullableDateTimeField; } @JsonCodable() From 549b455372c2d0cdce31e9cfc706331fb02bb9d9 Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 12:41:52 +0100 Subject: [PATCH 04/11] remove duplicate --- pkg/json/test/json_codable_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/json/test/json_codable_test.dart b/pkg/json/test/json_codable_test.dart index 4bd6874b8fc4..164d0930ae86 100644 --- a/pkg/json/test/json_codable_test.dart +++ b/pkg/json/test/json_codable_test.dart @@ -112,7 +112,6 @@ void main() { expect(b.nullableListOfSerializableField, null); expect(b.nullableMapOfSerializableField, null); expect(b.nullableSetOfSerializableField, null); - expect(b.nullableDateTimeField, null); expect(b.toJson(), isEmpty); }); From a5007b58b411f1a0aadc7c0bbca89e5a35277f17 Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 12:54:44 +0100 Subject: [PATCH 05/11] format --- pkg/json/lib/json.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/json/lib/json.dart b/pkg/json/lib/json.dart index 9c9dded5fb16..12e0fc191a09 100644 --- a/pkg/json/lib/json.dart +++ b/pkg/json/lib/json.dart @@ -383,11 +383,11 @@ mixin _FromJson on _Shared { if (nullCheck != null) nullCheck, await builder.resolveIdentifier(_dartCore, 'DateTime'), '.parse(', - jsonReference, + jsonReference, ' as ', introspectionData.stringCode, ')' - ]); + ]); } } From 4cef6e4d36f1731ce66310269d3edfd168e32d3a Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 13:01:46 +0100 Subject: [PATCH 06/11] add support to readme --- pkg/json/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/json/README.md b/pkg/json/README.md index 05cd188dffde..be0a748d7f72 100644 --- a/pkg/json/README.md +++ b/pkg/json/README.md @@ -55,6 +55,8 @@ class Manager extends User { All native JSON types are supported (`int`, `double`, `String`, `bool`, `Null`). +`DateTime` is supported. + The core collection types `List`, `Set`, and `Map` are also supported, if their elements are supported types. For elements which require more than just a cast, the type must be statically provided through a generic type argument on the From cb81afbaeab48a1e8bc3587a27432a2ce73a3d09 Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 19:42:11 +0100 Subject: [PATCH 07/11] add date time format to readme --- pkg/json/CHANGELOG.md | 2 +- pkg/json/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/json/CHANGELOG.md b/pkg/json/CHANGELOG.md index a7c985732d58..00053deb033e 100644 --- a/pkg/json/CHANGELOG.md +++ b/pkg/json/CHANGELOG.md @@ -1,6 +1,6 @@ # 0.20.3 -- Add support for DateTime +- Add support for DateTime as ISO-8601 String. # 0.20.2 diff --git a/pkg/json/README.md b/pkg/json/README.md index be0a748d7f72..e4faf93f2282 100644 --- a/pkg/json/README.md +++ b/pkg/json/README.md @@ -55,7 +55,7 @@ class Manager extends User { All native JSON types are supported (`int`, `double`, `String`, `bool`, `Null`). -`DateTime` is supported. +Supports `DateTime` as ISO-8601 String. The core collection types `List`, `Set`, and `Map` are also supported, if their elements are supported types. For elements which require more than just a cast, From 54465bee940a395ef0d11f42682b4ee513a829e9 Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 19:44:58 +0100 Subject: [PATCH 08/11] improve date time serialization comment --- pkg/json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/json/README.md b/pkg/json/README.md index e4faf93f2282..a4ccd79d2cae 100644 --- a/pkg/json/README.md +++ b/pkg/json/README.md @@ -55,7 +55,7 @@ class Manager extends User { All native JSON types are supported (`int`, `double`, `String`, `bool`, `Null`). -Supports `DateTime` as ISO-8601 String. +Supports `DateTime`, serializing it to an ISO-8601 String. The core collection types `List`, `Set`, and `Map` are also supported, if their elements are supported types. For elements which require more than just a cast, From 3f0d448d8e05c2a2d423dd01f67e3b523d19ecfb Mon Sep 17 00:00:00 2001 From: cedvdb Date: Mon, 11 Nov 2024 19:45:48 +0100 Subject: [PATCH 09/11] improve date time serialization comment --- pkg/json/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/json/CHANGELOG.md b/pkg/json/CHANGELOG.md index 00053deb033e..b78404b21bc5 100644 --- a/pkg/json/CHANGELOG.md +++ b/pkg/json/CHANGELOG.md @@ -1,6 +1,6 @@ # 0.20.3 -- Add support for DateTime as ISO-8601 String. +- Add support for DateTime, serializing it to an ISO-8601 String. # 0.20.2 From c751b49529be7591a0b5f144c3e59bd253ddc08e Mon Sep 17 00:00:00 2001 From: cedvdb Date: Thu, 21 Nov 2024 10:38:00 +0100 Subject: [PATCH 10/11] apply patch --- pkg/json/lib/json.dart | 16 ++- pkg/json/test/json_codable_test.dart | 25 +++++ update.patch | 143 +++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 update.patch diff --git a/pkg/json/lib/json.dart b/pkg/json/lib/json.dart index 12e0fc191a09..1a2f4ddfdabf 100644 --- a/pkg/json/lib/json.dart +++ b/pkg/json/lib/json.dart @@ -521,7 +521,9 @@ mixin _ToJson on _Shared { if (doNullCheck) '!', ]), builder, - introspectionData), + introspectionData, + // We already are doing the null check. + omitNullCheck: true), ';\n ', ]); if (doNullCheck) { @@ -580,12 +582,16 @@ mixin _ToJson on _Shared { } /// Returns a [Code] object which is an expression that converts an instance - /// of type [type] (referenced by [valueReference]) into a JSON map. + /// of type [rawType] (referenced by [valueReference]) into a JSON map. + /// + /// Null checks will be inserted if [rawType] is nullable, unless + /// [omitNullCheck] is `true`. Future _convertTypeToJson( TypeAnnotation rawType, Code valueReference, DefinitionBuilder builder, - _SharedIntrospectionData introspectionData) async { + _SharedIntrospectionData introspectionData, + {bool omitNullCheck = false}) async { final type = _checkNamedType(rawType, builder); if (type == null) { return RawCode.fromString( @@ -599,7 +605,7 @@ mixin _ToJson on _Shared { "throw 'Unable to serialize type ${type.code.debugString}'"); } - var nullCheck = type.isNullable + var nullCheck = type.isNullable && !omitNullCheck ? RawCode.fromParts([ valueReference, // `null` is a reserved word, we can just use it. @@ -635,7 +641,7 @@ mixin _ToJson on _Shared { case 'int' || 'double' || 'num' || 'String' || 'bool': return valueReference; case 'DateTime': - return RawCode.fromParts([valueReference, '.toIso8601String()']); + return RawCode.fromParts([if (nullCheck != null) nullCheck, valueReference, '.toIso8601String()']); } } diff --git a/pkg/json/test/json_codable_test.dart b/pkg/json/test/json_codable_test.dart index 164d0930ae86..15f48bc1ec4a 100644 --- a/pkg/json/test/json_codable_test.dart +++ b/pkg/json/test/json_codable_test.dart @@ -130,6 +130,7 @@ void main() { test('collections of nullable objects', () { var json = { + 'listOfNullableDates': [null, '2024-11-11T03:42:29.108308'], 'listOfNullableInts': [null, 1], 'listOfNullableSerializables': [ {'x': 1}, @@ -139,6 +140,10 @@ void main() { null, {'a': 1, 'b': null}, ], + 'setOfNullableDates': [ + null, + '2024-11-12T03:42:29.108308', + ], 'setOfNullableInts': [ null, 2, @@ -154,6 +159,10 @@ void main() { 'b': null, }, ], + 'mapOfNullableDates': { + 'a': '2024-11-13T03:42:29.108308', + 'b': null, + }, 'mapOfNullableInts': { 'a': 3, 'b': null, @@ -169,6 +178,8 @@ void main() { }; var e = E.fromJson(json); + expect(e.listOfNullableDates, + equals([null, DateTime.parse('2024-11-11T03:42:29.108308')])); expect(e.listOfNullableInts, equals([null, 1])); expect(e.listOfNullableSerializables.first!.x, 1); expect(e.listOfNullableSerializables[1], null); @@ -178,6 +189,8 @@ void main() { null, {'a': 1, 'b': null}, ])); + expect(e.setOfNullableDates, + equals([null, DateTime.parse('2024-11-12T03:42:29.108308')])); expect(e.setOfNullableInts, equals({null, 2})); expect(e.setOfNullableSerializables.first!.x, 2); expect(e.setOfNullableSerializables.elementAt(1), null); @@ -190,6 +203,12 @@ void main() { 'b': null, }, })); + expect( + e.mapOfNullableDates, + equals({ + 'a': DateTime.parse('2024-11-13T03:42:29.108308'), + 'b': null, + })); expect( e.mapOfNullableInts, equals({ @@ -273,18 +292,24 @@ class D extends C { @JsonCodable() class E { + final List listOfNullableDates; + final List listOfNullableInts; final List listOfNullableSerializables; final List?> listOfNullableMapsOfNullableInts; + final Set setOfNullableDates; + final Set setOfNullableInts; final Set setOfNullableSerializables; final Set?> setOfNullableMapsOfNullableInts; + final Map mapOfNullableDates; + final Map mapOfNullableInts; final Map mapOfNullableSerializables; diff --git a/update.patch b/update.patch new file mode 100644 index 000000000000..fc18d314ddc3 --- /dev/null +++ b/update.patch @@ -0,0 +1,143 @@ +diff --git a/pkg/json/lib/json.dart b/pkg/json/lib/json.dart +index 12e0fc191a0..1a2f4ddfdab 100644 +--- a/pkg/json/lib/json.dart ++++ b/pkg/json/lib/json.dart +@@ -521,7 +521,9 @@ mixin _ToJson on _Shared { + if (doNullCheck) '!', + ]), + builder, +- introspectionData), ++ introspectionData, ++ // We already are doing the null check. ++ omitNullCheck: true), + ';\n ', + ]); + if (doNullCheck) { +@@ -580,12 +582,16 @@ mixin _ToJson on _Shared { + } + + /// Returns a [Code] object which is an expression that converts an instance +- /// of type [type] (referenced by [valueReference]) into a JSON map. ++ /// of type [rawType] (referenced by [valueReference]) into a JSON map. ++ /// ++ /// Null checks will be inserted if [rawType] is nullable, unless ++ /// [omitNullCheck] is `true`. + Future _convertTypeToJson( + TypeAnnotation rawType, + Code valueReference, + DefinitionBuilder builder, +- _SharedIntrospectionData introspectionData) async { ++ _SharedIntrospectionData introspectionData, ++ {bool omitNullCheck = false}) async { + final type = _checkNamedType(rawType, builder); + if (type == null) { + return RawCode.fromString( +@@ -599,7 +605,7 @@ mixin _ToJson on _Shared { + "throw 'Unable to serialize type ${type.code.debugString}'"); + } + +- var nullCheck = type.isNullable ++ var nullCheck = type.isNullable && !omitNullCheck + ? RawCode.fromParts([ + valueReference, + // `null` is a reserved word, we can just use it. +@@ -635,7 +641,7 @@ mixin _ToJson on _Shared { + case 'int' || 'double' || 'num' || 'String' || 'bool': + return valueReference; + case 'DateTime': +- return RawCode.fromParts([valueReference, '.toIso8601String()']); ++ return RawCode.fromParts([if (nullCheck != null) nullCheck, valueReference, '.toIso8601String()']); + } + } + +diff --git a/pkg/json/test/json_codable_test.dart b/pkg/json/test/json_codable_test.dart +index 164d0930ae8..15f48bc1ec4 100644 +--- a/pkg/json/test/json_codable_test.dart ++++ b/pkg/json/test/json_codable_test.dart +@@ -130,6 +130,7 @@ void main() { + + test('collections of nullable objects', () { + var json = { ++ 'listOfNullableDates': [null, '2024-11-11T03:42:29.108308'], + 'listOfNullableInts': [null, 1], + 'listOfNullableSerializables': [ + {'x': 1}, +@@ -139,6 +140,10 @@ void main() { + null, + {'a': 1, 'b': null}, + ], ++ 'setOfNullableDates': [ ++ null, ++ '2024-11-12T03:42:29.108308', ++ ], + 'setOfNullableInts': [ + null, + 2, +@@ -154,6 +159,10 @@ void main() { + 'b': null, + }, + ], ++ 'mapOfNullableDates': { ++ 'a': '2024-11-13T03:42:29.108308', ++ 'b': null, ++ }, + 'mapOfNullableInts': { + 'a': 3, + 'b': null, +@@ -169,6 +178,8 @@ void main() { + }; + + var e = E.fromJson(json); ++ expect(e.listOfNullableDates, ++ equals([null, DateTime.parse('2024-11-11T03:42:29.108308')])); + expect(e.listOfNullableInts, equals([null, 1])); + expect(e.listOfNullableSerializables.first!.x, 1); + expect(e.listOfNullableSerializables[1], null); +@@ -178,6 +189,8 @@ void main() { + null, + {'a': 1, 'b': null}, + ])); ++ expect(e.setOfNullableDates, ++ equals([null, DateTime.parse('2024-11-12T03:42:29.108308')])); + expect(e.setOfNullableInts, equals({null, 2})); + expect(e.setOfNullableSerializables.first!.x, 2); + expect(e.setOfNullableSerializables.elementAt(1), null); +@@ -190,6 +203,12 @@ void main() { + 'b': null, + }, + })); ++ expect( ++ e.mapOfNullableDates, ++ equals({ ++ 'a': DateTime.parse('2024-11-13T03:42:29.108308'), ++ 'b': null, ++ })); + expect( + e.mapOfNullableInts, + equals({ +@@ -273,18 +292,24 @@ class D extends C { + + @JsonCodable() + class E { ++ final List listOfNullableDates; ++ + final List listOfNullableInts; + + final List listOfNullableSerializables; + + final List?> listOfNullableMapsOfNullableInts; + ++ final Set setOfNullableDates; ++ + final Set setOfNullableInts; + + final Set setOfNullableSerializables; + + final Set?> setOfNullableMapsOfNullableInts; + ++ final Map mapOfNullableDates; ++ + final Map mapOfNullableInts; + + final Map mapOfNullableSerializables; + \ No newline at end of file From 6990c3110eac09cbfebcc669889c50c4d326b1dd Mon Sep 17 00:00:00 2001 From: cedvdb Date: Thu, 21 Nov 2024 10:38:54 +0100 Subject: [PATCH 11/11] remove patch file :D --- update.patch | 143 --------------------------------------------------- 1 file changed, 143 deletions(-) delete mode 100644 update.patch diff --git a/update.patch b/update.patch deleted file mode 100644 index fc18d314ddc3..000000000000 --- a/update.patch +++ /dev/null @@ -1,143 +0,0 @@ -diff --git a/pkg/json/lib/json.dart b/pkg/json/lib/json.dart -index 12e0fc191a0..1a2f4ddfdab 100644 ---- a/pkg/json/lib/json.dart -+++ b/pkg/json/lib/json.dart -@@ -521,7 +521,9 @@ mixin _ToJson on _Shared { - if (doNullCheck) '!', - ]), - builder, -- introspectionData), -+ introspectionData, -+ // We already are doing the null check. -+ omitNullCheck: true), - ';\n ', - ]); - if (doNullCheck) { -@@ -580,12 +582,16 @@ mixin _ToJson on _Shared { - } - - /// Returns a [Code] object which is an expression that converts an instance -- /// of type [type] (referenced by [valueReference]) into a JSON map. -+ /// of type [rawType] (referenced by [valueReference]) into a JSON map. -+ /// -+ /// Null checks will be inserted if [rawType] is nullable, unless -+ /// [omitNullCheck] is `true`. - Future _convertTypeToJson( - TypeAnnotation rawType, - Code valueReference, - DefinitionBuilder builder, -- _SharedIntrospectionData introspectionData) async { -+ _SharedIntrospectionData introspectionData, -+ {bool omitNullCheck = false}) async { - final type = _checkNamedType(rawType, builder); - if (type == null) { - return RawCode.fromString( -@@ -599,7 +605,7 @@ mixin _ToJson on _Shared { - "throw 'Unable to serialize type ${type.code.debugString}'"); - } - -- var nullCheck = type.isNullable -+ var nullCheck = type.isNullable && !omitNullCheck - ? RawCode.fromParts([ - valueReference, - // `null` is a reserved word, we can just use it. -@@ -635,7 +641,7 @@ mixin _ToJson on _Shared { - case 'int' || 'double' || 'num' || 'String' || 'bool': - return valueReference; - case 'DateTime': -- return RawCode.fromParts([valueReference, '.toIso8601String()']); -+ return RawCode.fromParts([if (nullCheck != null) nullCheck, valueReference, '.toIso8601String()']); - } - } - -diff --git a/pkg/json/test/json_codable_test.dart b/pkg/json/test/json_codable_test.dart -index 164d0930ae8..15f48bc1ec4 100644 ---- a/pkg/json/test/json_codable_test.dart -+++ b/pkg/json/test/json_codable_test.dart -@@ -130,6 +130,7 @@ void main() { - - test('collections of nullable objects', () { - var json = { -+ 'listOfNullableDates': [null, '2024-11-11T03:42:29.108308'], - 'listOfNullableInts': [null, 1], - 'listOfNullableSerializables': [ - {'x': 1}, -@@ -139,6 +140,10 @@ void main() { - null, - {'a': 1, 'b': null}, - ], -+ 'setOfNullableDates': [ -+ null, -+ '2024-11-12T03:42:29.108308', -+ ], - 'setOfNullableInts': [ - null, - 2, -@@ -154,6 +159,10 @@ void main() { - 'b': null, - }, - ], -+ 'mapOfNullableDates': { -+ 'a': '2024-11-13T03:42:29.108308', -+ 'b': null, -+ }, - 'mapOfNullableInts': { - 'a': 3, - 'b': null, -@@ -169,6 +178,8 @@ void main() { - }; - - var e = E.fromJson(json); -+ expect(e.listOfNullableDates, -+ equals([null, DateTime.parse('2024-11-11T03:42:29.108308')])); - expect(e.listOfNullableInts, equals([null, 1])); - expect(e.listOfNullableSerializables.first!.x, 1); - expect(e.listOfNullableSerializables[1], null); -@@ -178,6 +189,8 @@ void main() { - null, - {'a': 1, 'b': null}, - ])); -+ expect(e.setOfNullableDates, -+ equals([null, DateTime.parse('2024-11-12T03:42:29.108308')])); - expect(e.setOfNullableInts, equals({null, 2})); - expect(e.setOfNullableSerializables.first!.x, 2); - expect(e.setOfNullableSerializables.elementAt(1), null); -@@ -190,6 +203,12 @@ void main() { - 'b': null, - }, - })); -+ expect( -+ e.mapOfNullableDates, -+ equals({ -+ 'a': DateTime.parse('2024-11-13T03:42:29.108308'), -+ 'b': null, -+ })); - expect( - e.mapOfNullableInts, - equals({ -@@ -273,18 +292,24 @@ class D extends C { - - @JsonCodable() - class E { -+ final List listOfNullableDates; -+ - final List listOfNullableInts; - - final List listOfNullableSerializables; - - final List?> listOfNullableMapsOfNullableInts; - -+ final Set setOfNullableDates; -+ - final Set setOfNullableInts; - - final Set setOfNullableSerializables; - - final Set?> setOfNullableMapsOfNullableInts; - -+ final Map mapOfNullableDates; -+ - final Map mapOfNullableInts; - - final Map mapOfNullableSerializables; - \ No newline at end of file