From 49abaec6d125ef8bd019b750dc99bf1cc2ae40d7 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sun, 12 Nov 2023 17:37:37 +0100 Subject: [PATCH] fix(dynamite,nextcloud): fix generics in nested built_collection build factories Signed-off-by: Nikolas Rimikis --- .../lib/src/models/type_result/base.dart | 3 - .../lib/src/models/type_result/enum.dart | 3 - .../lib/src/models/type_result/list.dart | 4 +- .../lib/src/models/type_result/map.dart | 4 +- .../lib/src/models/type_result/object.dart | 6 -- .../src/models/type_result/type_result.dart | 28 +++-- .../dynamite/test/type_result_test.dart | 101 ++++++++++++++++++ .../lib/src/api/dashboard.openapi.dart | 2 +- .../lib/src/api/files_sharing.openapi.dart | 2 +- .../lib/src/api/provisioning_api.openapi.dart | 2 +- .../nextcloud/lib/src/api/spreed.openapi.dart | 8 +- 11 files changed, 132 insertions(+), 31 deletions(-) diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/base.dart b/packages/dynamite/dynamite/lib/src/models/type_result/base.dart index eba4205f..215f0a4c 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/base.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/base.dart @@ -14,9 +14,6 @@ class TypeResultBase extends TypeResult { @override String? get _serializer => null; - @override - String serialize(final String object) => object; - @override String encode( final String object, { diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/enum.dart b/packages/dynamite/dynamite/lib/src/models/type_result/enum.dart index 9a86f29f..ee552d68 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/enum.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/enum.dart @@ -14,9 +14,6 @@ class TypeResultEnum extends TypeResult { @override String? get _builderFactory => null; - @override - String? get _serializer => '..add($className.serializer)'; - @override String encode( final String object, { diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/list.dart b/packages/dynamite/dynamite/lib/src/models/type_result/list.dart index 69a8e9ed..52c27e2b 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/list.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/list.dart @@ -7,13 +7,11 @@ class TypeResultList extends TypeResult { final TypeResult subType, { super.nullable, super.isTypeDef, + super.builderName = 'ListBuilder', }) : super(generics: [subType]); TypeResult get subType => generics.first; - @override - String? get _builderFactory => '..addBuilderFactory($fullType, ListBuilder<${subType.className}>.new)'; - @override String? get _serializer => null; diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/map.dart b/packages/dynamite/dynamite/lib/src/models/type_result/map.dart index 73646080..8cb01a22 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/map.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/map.dart @@ -7,13 +7,11 @@ class TypeResultMap extends TypeResult { final TypeResult subType, { super.nullable, super.isTypeDef, + super.builderName = 'MapBuilder', }) : super(generics: [TypeResultBase('String'), subType]); TypeResult get subType => generics[1]; - @override - String? get _builderFactory => '..addBuilderFactory($fullType, MapBuilder.new)'; - @override String? get _serializer => null; diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/object.dart b/packages/dynamite/dynamite/lib/src/models/type_result/object.dart index e3d28c57..40e5ed66 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/object.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/object.dart @@ -14,12 +14,6 @@ class TypeResultObject extends TypeResult { 'Use TypeResultBase instead', ); - @override - String? get _builderFactory => '..addBuilderFactory($fullType, $name.new)'; - - @override - String? get _serializer => '..add($className.serializer)'; - @override String encode( final String object, { diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/type_result.dart b/packages/dynamite/dynamite/lib/src/models/type_result/type_result.dart index c7f96eee..5d7bd916 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/type_result.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/type_result.dart @@ -1,4 +1,3 @@ -import 'package:intersperse/intersperse.dart'; import 'package:meta/meta.dart'; part 'base.dart'; @@ -14,20 +13,24 @@ sealed class TypeResult { this.generics = const [], this.nullable = false, this.isTypeDef = false, - }) : assert(!className.contains('<'), 'Specify generics in the generics parameter.'), + final String? builderName, + }) : builderName = builderName ?? className, + assert(!className.contains('<'), 'Specify generics in the generics parameter.'), assert(!className.contains('?'), 'Nullability should not be specified in the type.'); final String className; + final String builderName; final List generics; final bool nullable; /// Whether this type should be represented as a typedef. final bool isTypeDef; + @nonVirtual String get name { if (generics.isNotEmpty) { final buffer = StringBuffer('$className<') - ..writeAll(generics.map((final c) => c.name).intersperse(', ')) + ..writeAll(generics.map((final c) => c.name), ', ') ..write('>'); return buffer.toString(); } @@ -35,10 +38,23 @@ sealed class TypeResult { return className; } + @nonVirtual + String get builder { + if (generics.isNotEmpty) { + final buffer = StringBuffer('$builderName<') + ..writeAll(generics.map((final c) => c.name), ', ') + ..write('>'); + return buffer.toString(); + } + + return builderName; + } + + @nonVirtual String get fullType { if (generics.isNotEmpty) { final buffer = StringBuffer('FullType($className, [') - ..writeAll(generics.map((final c) => c.fullType).intersperse(', ')) + ..writeAll(generics.map((final c) => c.fullType), ', ') ..write('])'); return buffer.toString(); @@ -64,9 +80,9 @@ sealed class TypeResult { } } - String? get _serializer; + String? get _serializer => '..add($className.serializer)'; - String? get _builderFactory; + String? get _builderFactory => '..addBuilderFactory($fullType, $builder.new)'; /// Serializes the variable named [object]. /// diff --git a/packages/dynamite/dynamite/test/type_result_test.dart b/packages/dynamite/dynamite/test/type_result_test.dart index e8147142..539616d9 100644 --- a/packages/dynamite/dynamite/test/type_result_test.dart +++ b/packages/dynamite/dynamite/test/type_result_test.dart @@ -9,6 +9,42 @@ void main() { expect(type.name, 'BuiltList'); expect(type.fullType, 'FullType(BuiltList, [FullType(String)])'); + expect( + type.serializers.toList(), + const ['..addBuilderFactory(FullType(BuiltList, [FullType(String)]), ListBuilder.new)'], + ); + expect( + type.serialize('value'), + '_jsonSerializers.serialize(value, specifiedType: const FullType(BuiltList, [FullType(String)]))', + ); + expect( + type.deserialize('value'), + '(_jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltList, [FullType(String)]))! as BuiltList)', + ); + }); + + test('Nested list', () { + final subType = TypeResultBase('String'); + var type = TypeResultList('BuiltList', subType); + type = TypeResultList('BuiltList', type); + + expect(type.name, 'BuiltList>'); + expect(type.fullType, 'FullType(BuiltList, [FullType(BuiltList, [FullType(String)])])'); + expect( + type.serializers.toList(), + const [ + '..addBuilderFactory(FullType(BuiltList, [FullType(String)]), ListBuilder.new)', + '..addBuilderFactory(FullType(BuiltList, [FullType(BuiltList, [FullType(String)])]), ListBuilder>.new)', + ], + ); + expect( + type.serialize('value'), + '_jsonSerializers.serialize(value, specifiedType: const FullType(BuiltList, [FullType(BuiltList, [FullType(String)])]))', + ); + expect( + type.deserialize('value'), + '(_jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltList, [FullType(BuiltList, [FullType(String)])]))! as BuiltList>)', + ); }); }); @@ -19,6 +55,47 @@ void main() { expect(type.name, 'BuiltMap'); expect(type.fullType, 'FullType(BuiltMap, [FullType(String), FullType(int)])'); + expect( + type.serializers.toList(), + const [ + '..addBuilderFactory(FullType(BuiltMap, [FullType(String), FullType(int)]), MapBuilder.new)', + ], + ); + expect( + type.serialize('value'), + '_jsonSerializers.serialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(int)]))', + ); + expect( + type.deserialize('value'), + '(_jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(int)]))! as BuiltMap)', + ); + }); + + test('Nested map', () { + final subType = TypeResultBase('int'); + var type = TypeResultMap('BuiltMap', subType); + type = TypeResultMap('BuiltMap', type); + + expect(type.name, 'BuiltMap>'); + expect( + type.fullType, + 'FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])])', + ); + expect( + type.serializers.toList(), + const [ + '..addBuilderFactory(FullType(BuiltMap, [FullType(String), FullType(int)]), MapBuilder.new)', + '..addBuilderFactory(FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])]), MapBuilder>.new)', + ], + ); + expect( + type.serialize('value'), + '_jsonSerializers.serialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])]))', + ); + expect( + type.deserialize('value'), + '(_jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])]))! as BuiltMap>)', + ); }); }); @@ -29,6 +106,21 @@ void main() { expect(type.name, 'CustomType'); expect(type.fullType, 'FullType(CustomType, [FullType(String)])'); + expect( + type.serializers.toList(), + const [ + '..addBuilderFactory(FullType(CustomType, [FullType(String)]), CustomType.new)', + '..add(CustomType.serializer)', + ], + ); + expect( + type.serialize('value'), + '_jsonSerializers.serialize(value, specifiedType: const FullType(CustomType, [FullType(String)]))', + ); + expect( + type.deserialize('value'), + '(_jsonSerializers.deserialize(value, specifiedType: const FullType(CustomType, [FullType(String)]))! as CustomType)', + ); }); }); @@ -38,6 +130,15 @@ void main() { expect(type.name, 'String'); expect(type.fullType, 'FullType(String)'); + expect(type.serializers.toList(), const []); + expect( + type.serialize('value'), + '_jsonSerializers.serialize(value, specifiedType: const FullType(String))', + ); + expect( + type.deserialize('value'), + '(_jsonSerializers.deserialize(value, specifiedType: const FullType(String))! as String)', + ); }); }); } diff --git a/packages/nextcloud/lib/src/api/dashboard.openapi.dart b/packages/nextcloud/lib/src/api/dashboard.openapi.dart index f0abf030..cfda1e1c 100644 --- a/packages/nextcloud/lib/src/api/dashboard.openapi.dart +++ b/packages/nextcloud/lib/src/api/dashboard.openapi.dart @@ -738,7 +738,7 @@ final Serializers _serializers = (Serializers().toBuilder() FullType(String), FullType(BuiltList, [FullType(WidgetItem)]), ]), - MapBuilder.new, + MapBuilder>.new, ) ..addBuilderFactory( const FullType(DashboardApiGetWidgetItemsV2ResponseApplicationJson), diff --git a/packages/nextcloud/lib/src/api/files_sharing.openapi.dart b/packages/nextcloud/lib/src/api/files_sharing.openapi.dart index aaa3a8a9..f611df23 100644 --- a/packages/nextcloud/lib/src/api/files_sharing.openapi.dart +++ b/packages/nextcloud/lib/src/api/files_sharing.openapi.dart @@ -5186,7 +5186,7 @@ final Serializers _serializers = (Serializers().toBuilder() const FullType(BuiltList, [ FullType(BuiltMap, [FullType(String), FullType(JsonObject)]), ]), - ListBuilder.new, + ListBuilder>.new, ) ..addBuilderFactory( const FullType(ShareapiGetSharesResponseApplicationJson), diff --git a/packages/nextcloud/lib/src/api/provisioning_api.openapi.dart b/packages/nextcloud/lib/src/api/provisioning_api.openapi.dart index ba713001..7582bcc6 100644 --- a/packages/nextcloud/lib/src/api/provisioning_api.openapi.dart +++ b/packages/nextcloud/lib/src/api/provisioning_api.openapi.dart @@ -9148,7 +9148,7 @@ final Serializers _serializers = (Serializers().toBuilder() FullType(String), FullType(BuiltList, [FullType(String)]), ]), - MapBuilder.new, + MapBuilder>.new, ) ..addBuilderFactory( const FullType(ContentString, [ diff --git a/packages/nextcloud/lib/src/api/spreed.openapi.dart b/packages/nextcloud/lib/src/api/spreed.openapi.dart index 2ec15a3f..512bcb77 100644 --- a/packages/nextcloud/lib/src/api/spreed.openapi.dart +++ b/packages/nextcloud/lib/src/api/spreed.openapi.dart @@ -23659,7 +23659,7 @@ final Serializers _serializers = (Serializers().toBuilder() FullType(String), FullType(BuiltMap, [FullType(String), FullType(JsonObject)]), ]), - MapBuilder.new, + MapBuilder>.new, ) ..addBuilderFactory(const FullType(BuiltMap, [FullType(String), FullType(int)]), MapBuilder.new) ..addBuilderFactory(const FullType(BuiltList, [FullType(JsonObject)]), ListBuilder.new) @@ -24136,7 +24136,7 @@ final Serializers _serializers = (Serializers().toBuilder() FullType(String), FullType(BuiltList, [FullType(ChatMessage)]), ]), - MapBuilder.new, + MapBuilder>.new, ) ..add(FederationAcceptShareApiVersion.serializer) ..addBuilderFactory( @@ -24258,7 +24258,7 @@ final Serializers _serializers = (Serializers().toBuilder() const FullType(BuiltList, [ FullType(BuiltMap, [FullType(String), FullType(JsonObject)]), ]), - ListBuilder.new, + ListBuilder>.new, ) ..addBuilderFactory(const FullType(MatterbridgeProcessState), MatterbridgeProcessState.new) ..add(MatterbridgeProcessState.serializer) @@ -24411,7 +24411,7 @@ final Serializers _serializers = (Serializers().toBuilder() FullType(String), FullType(BuiltList, [FullType(Reaction)]), ]), - MapBuilder.new, + MapBuilder>.new, ) ..add(ReactionReactApiVersion.serializer) ..addBuilderFactory(