diff --git a/packages/dynamite/dynamite/lib/src/builder/built_object_serializer.dart b/packages/dynamite/dynamite/lib/src/builder/built_object_serializer.dart index 50fb2e9bbd9..2204341fede 100644 --- a/packages/dynamite/dynamite/lib/src/builder/built_object_serializer.dart +++ b/packages/dynamite/dynamite/lib/src/builder/built_object_serializer.dart @@ -5,6 +5,7 @@ import 'package:dynamite/src/helpers/dart_helpers.dart'; import 'package:dynamite/src/helpers/dynamite.dart'; import 'package:dynamite/src/models/openapi.dart' as openapi; import 'package:dynamite/src/models/type_result.dart'; +import 'package:source_helper/source_helper.dart'; Spec buildBuiltClassSerializer( final State state, @@ -38,7 +39,7 @@ Spec buildBuiltClassSerializer( ..lambda = true ..returns = refer('String') ..annotations.add(refer('override')) - ..body = Code("r'$identifier'"), + ..body = Code(escapeDartString(identifier)), ), Method((final b) { b diff --git a/packages/dynamite/dynamite/lib/src/builder/client.dart b/packages/dynamite/dynamite/lib/src/builder/client.dart index 294a3185083..e22a6709d6c 100644 --- a/packages/dynamite/dynamite/lib/src/builder/client.dart +++ b/packages/dynamite/dynamite/lib/src/builder/client.dart @@ -11,6 +11,7 @@ import 'package:dynamite/src/helpers/pattern_check.dart'; import 'package:dynamite/src/models/openapi.dart' as openapi; import 'package:dynamite/src/models/type_result.dart'; import 'package:intersperse/intersperse.dart'; +import 'package:source_helper/source_helper.dart'; import 'package:uri/uri.dart'; Iterable generateClients( @@ -472,15 +473,18 @@ String buildParameterSerialization( final $default = parameter.schema?.$default; var defaultValueCode = $default?.value; if ($default != null && $default.isString) { - defaultValueCode = "'${$default.asString}'"; + defaultValueCode = escapeDartString($default.asString); } final dartName = toDartName(parameter.name); final serializedName = '\$$dartName'; - - final buffer = StringBuffer()..write('var $serializedName = ${result.serialize(dartName)};'); + final buffer = StringBuffer(); if ($default != null) { - buffer.writeln('$serializedName ??= $defaultValueCode;'); + buffer + ..write('var $serializedName = ${result.serialize(dartName)};') + ..writeln('$serializedName ??= $defaultValueCode;'); + } else { + buffer.write('final $serializedName = ${result.serialize(dartName)};'); } if (parameter.schema != null) { diff --git a/packages/dynamite/dynamite/lib/src/builder/generate_ofs.dart b/packages/dynamite/dynamite/lib/src/builder/generate_ofs.dart index fd506fb4485..a1560577226 100644 --- a/packages/dynamite/dynamite/lib/src/builder/generate_ofs.dart +++ b/packages/dynamite/dynamite/lib/src/builder/generate_ofs.dart @@ -187,7 +187,7 @@ Iterable generateSomeOf( ..type = MethodType.getter ..name = 'wireName' ..lambda = true - ..body = Code("r'$identifier'"), + ..body = Code(escapeDartString(identifier)), ), Method((final b) { b diff --git a/packages/dynamite/dynamite/lib/src/builder/resolve_enum.dart b/packages/dynamite/dynamite/lib/src/builder/resolve_enum.dart index 6b9d26c242d..d7980076ce5 100644 --- a/packages/dynamite/dynamite/lib/src/builder/resolve_enum.dart +++ b/packages/dynamite/dynamite/lib/src/builder/resolve_enum.dart @@ -6,6 +6,7 @@ import 'package:dynamite/src/helpers/built_value.dart'; import 'package:dynamite/src/helpers/dart_helpers.dart'; import 'package:dynamite/src/models/openapi.dart' as openapi; import 'package:dynamite/src/models/type_result.dart'; +import 'package:source_helper/source_helper.dart'; TypeResult resolveEnum( final openapi.OpenAPI spec, @@ -22,7 +23,7 @@ TypeResult resolveEnum( final dartName = toDartName(name); var value = jsonEncode(enumValue.value); if (enumValue.isString) { - value = 'r$value'; + value = escapeDartString(enumValue.asString); } values.add((dartName: dartName, value: value, name: name)); @@ -62,7 +63,7 @@ TypeResult resolveEnum( if (enumValue.name != enumValue.dartName) { b.annotations.add( refer('BuiltValueEnumConst').call([], { - 'wireName': refer("r'${enumValue.name}'"), + 'wireName': refer(escapeDartString(enumValue.name)), }), ); } @@ -169,7 +170,7 @@ TypeResult resolveEnum( ..type = MethodType.getter ..returns = refer('String') ..annotations.add(refer('override')) - ..body = Code("r'$identifier'"), + ..body = Code(escapeDartString(identifier)), ), Method((final b) { b diff --git a/packages/dynamite/dynamite/lib/src/builder/resolve_mime_type.dart b/packages/dynamite/dynamite/lib/src/builder/resolve_mime_type.dart index 983296047d8..46149af9f37 100644 --- a/packages/dynamite/dynamite/lib/src/builder/resolve_mime_type.dart +++ b/packages/dynamite/dynamite/lib/src/builder/resolve_mime_type.dart @@ -92,7 +92,7 @@ Iterable resolveMimeTypeEncode( if (dartParameterNullable) { yield 'if ($parameterName != null) {'; } - yield '_body = utf8.encode(${result.encode(parameterName, mimeType: mimeType)}) as Uint8List;'; + yield '_body = utf8.encode(${result.encode(parameterName, mimeType: mimeType)});'; if (dartParameterNullable) { yield '}'; } diff --git a/packages/dynamite/dynamite/lib/src/builder/serializer.dart b/packages/dynamite/dynamite/lib/src/builder/serializer.dart index 6b7bcf847f0..e9b77ea7b6d 100644 --- a/packages/dynamite/dynamite/lib/src/builder/serializer.dart +++ b/packages/dynamite/dynamite/lib/src/builder/serializer.dart @@ -13,12 +13,16 @@ List buildSerializer(final State state) => [ final serializers = state.resolvedTypes.map((final type) => type.serializers).expand((final element) => element).toSet(); - final bodyBuilder = StringBuffer() - ..writeln('(Serializers().toBuilder()') - ..writeAll(serializers, '\n') - ..writeln(').build()'); + if (serializers.isEmpty) { + b.assignment = const Code('Serializers()'); + } else { + final bodyBuilder = StringBuffer() + ..writeln('(Serializers().toBuilder()') + ..writeAll(serializers, '\n') + ..writeln(').build()'); - b.assignment = Code(bodyBuilder.toString()); + b.assignment = Code(bodyBuilder.toString()); + } }), Field((final b) { b diff --git a/packages/dynamite/dynamite/lib/src/helpers/built_value.dart b/packages/dynamite/dynamite/lib/src/helpers/built_value.dart index 854e163e32e..a6216df7048 100644 --- a/packages/dynamite/dynamite/lib/src/helpers/built_value.dart +++ b/packages/dynamite/dynamite/lib/src/helpers/built_value.dart @@ -100,6 +100,10 @@ Method get toJsonMethod => Method( ..body = const Code('jsonSerializers.serializeWith(serializer, this)! as Map'), ); +/// Builds the serializer getter for a built class. +/// +/// If the serializer [isCustom] the getter is annotated to signal this to the built_value_generator. +/// It is assumed that custom serializers have a const constructor. Method buildSerializer(final String className, {final bool isCustom = false}) => Method((final b) { b ..name = 'serializer' @@ -107,7 +111,7 @@ Method buildSerializer(final String className, {final bool isCustom = false}) => ..lambda = true ..static = true ..body = Code( - isCustom ? '_\$${className}Serializer()' : '_\$${toCamelCase(className)}Serializer', + isCustom ? 'const _\$${className}Serializer()' : '_\$${toCamelCase(className)}Serializer', ) ..type = MethodType.getter; if (isCustom) { diff --git a/packages/dynamite/dynamite/lib/src/helpers/type_result.dart b/packages/dynamite/dynamite/lib/src/helpers/type_result.dart index 1c12844cc9f..0f8f0247b2e 100644 --- a/packages/dynamite/dynamite/lib/src/helpers/type_result.dart +++ b/packages/dynamite/dynamite/lib/src/helpers/type_result.dart @@ -1,12 +1,13 @@ import 'package:dynamite/src/helpers/dart_helpers.dart'; import 'package:dynamite/src/models/type_result.dart'; +import 'package:source_helper/source_helper.dart'; /// Escapes a [value] using the type specific syntax from [result]. /// /// Use [forceString] to ensure the returned value is a `String`. String valueToEscapedValue(final TypeResult result, final String value, {final bool forceString = false}) { if ((result is TypeResultBase && result.name == 'String') || forceString) { - return "'$value'"; + return escapeDartString(value); } if (result is TypeResultList) { return 'const <${result.subType.name}>$value'; 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 2c8302a859c..cb846f32f1b 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/base.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/base.dart @@ -34,7 +34,7 @@ class TypeResultBase extends TypeResult { case 'Uint8List': return object; case 'String': - return '(utf8.encode($object) as Uint8List)'; + return 'utf8.encode($object)'; default: throw Exception('"$mimeType" can only be Uint8List or String'); } diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart b/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart index a9cf509c342..0608e2060d8 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart @@ -121,7 +121,7 @@ class TypeResultAnyOf extends TypeResultSomeOf { @override String deserialize(final String object, [final String? serializerName]) => - '(${super.deserialize(object, serializerName)}..validateAnyOf())'; + '(${super.deserialize(object, serializerName)})..validateAnyOf()'; @override bool operator ==(final Object other) => @@ -143,7 +143,7 @@ class TypeResultOneOf extends TypeResultSomeOf { @override String deserialize(final String object, [final String? serializerName]) => - '(${super.deserialize(object, serializerName)}..validateOneOf())'; + '(${super.deserialize(object, serializerName)})..validateOneOf()'; @override bool operator ==(final Object other) => 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 8c202ce84cd..41454c8f979 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 @@ -58,10 +58,12 @@ sealed class TypeResult { } @nonVirtual - String get fullType { + String get fullType => 'const $_fullType'; + + String get _fullType { if (generics.isNotEmpty) { final buffer = StringBuffer('FullType($className, [') - ..writeAll(generics.map((final c) => c.fullType), ', ') + ..writeAll(generics.map((final c) => c._fullType), ', ') ..write('])'); return buffer.toString(); @@ -96,7 +98,7 @@ sealed class TypeResult { /// The serialized result is an [Object]? @mustCallSuper String serialize(final String object, [final String? serializerName]) => - '${serializerName ?? 'jsonSerializers'}.serialize($object, specifiedType: const $fullType)'; + '${serializerName ?? 'jsonSerializers'}.serialize($object, specifiedType: $fullType)'; /// Deserializes the variable named [object]. /// @@ -107,13 +109,13 @@ sealed class TypeResult { ..write(serializerName ?? 'jsonSerializers') ..write('.deserialize(') ..write(object) - ..write(', specifiedType: const $fullType)'); + ..write(', specifiedType: $fullType)'); if (!nullable) { buffer.write('!'); } - return '($buffer as $name)'; + return '$buffer as $name'; } /// Decodes 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 ad4af14c304..b67ce870268 100644 --- a/packages/dynamite/dynamite/test/type_result_test.dart +++ b/packages/dynamite/dynamite/test/type_result_test.dart @@ -9,10 +9,10 @@ void main() { final type = TypeResultList('BuiltList', subType); expect(type.name, 'BuiltList'); - expect(type.fullType, 'FullType(BuiltList, [FullType(String)])'); + expect(type.fullType, 'const FullType(BuiltList, [FullType(String)])'); expect( type.serializers.toList(), - const ['..addBuilderFactory(FullType(BuiltList, [FullType(String)]), ListBuilder.new)'], + const ['..addBuilderFactory(const FullType(BuiltList, [FullType(String)]), ListBuilder.new)'], ); expect( type.serialize('value'), @@ -20,7 +20,7 @@ void main() { ); expect( type.deserialize('value'), - '(jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltList, [FullType(String)]))! as BuiltList)', + 'jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltList, [FullType(String)]))! as BuiltList', ); }); @@ -30,12 +30,12 @@ void main() { type = TypeResultList('BuiltList', type); expect(type.name, 'BuiltList>'); - expect(type.fullType, 'FullType(BuiltList, [FullType(BuiltList, [FullType(String)])])'); + expect(type.fullType, 'const 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)', + '..addBuilderFactory(const FullType(BuiltList, [FullType(String)]), ListBuilder.new)', + '..addBuilderFactory(const FullType(BuiltList, [FullType(BuiltList, [FullType(String)])]), ListBuilder>.new)', ], ); expect( @@ -44,7 +44,7 @@ void main() { ); expect( type.deserialize('value'), - '(jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltList, [FullType(BuiltList, [FullType(String)])]))! as BuiltList>)', + 'jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltList, [FullType(BuiltList, [FullType(String)])]))! as BuiltList>', ); }); @@ -66,11 +66,11 @@ void main() { final type = TypeResultMap('BuiltMap', subType); expect(type.name, 'BuiltMap'); - expect(type.fullType, 'FullType(BuiltMap, [FullType(String), FullType(int)])'); + expect(type.fullType, 'const FullType(BuiltMap, [FullType(String), FullType(int)])'); expect( type.serializers.toList(), const [ - '..addBuilderFactory(FullType(BuiltMap, [FullType(String), FullType(int)]), MapBuilder.new)', + '..addBuilderFactory(const FullType(BuiltMap, [FullType(String), FullType(int)]), MapBuilder.new)', ], ); expect( @@ -79,7 +79,7 @@ void main() { ); expect( type.deserialize('value'), - '(jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(int)]))! as BuiltMap)', + 'jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(int)]))! as BuiltMap', ); }); @@ -91,13 +91,13 @@ void main() { expect(type.name, 'BuiltMap>'); expect( type.fullType, - 'FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])])', + 'const 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)', + '..addBuilderFactory(const FullType(BuiltMap, [FullType(String), FullType(int)]), MapBuilder.new)', + '..addBuilderFactory(const FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])]), MapBuilder>.new)', ], ); expect( @@ -106,7 +106,7 @@ void main() { ); expect( type.deserialize('value'), - '(jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])]))! as BuiltMap>)', + 'jsonSerializers.deserialize(value, specifiedType: const FullType(BuiltMap, [FullType(String), FullType(BuiltMap, [FullType(String), FullType(int)])]))! as BuiltMap>', ); }); @@ -128,11 +128,11 @@ void main() { final type = TypeResultObject('CustomType', generics: BuiltList([subType])); expect(type.name, 'CustomType'); - expect(type.fullType, 'FullType(CustomType, [FullType(String)])'); + expect(type.fullType, 'const FullType(CustomType, [FullType(String)])'); expect( type.serializers.toList(), const [ - '..addBuilderFactory(FullType(CustomType, [FullType(String)]), CustomTypeBuilder.new)', + '..addBuilderFactory(const FullType(CustomType, [FullType(String)]), CustomTypeBuilder.new)', '..add(CustomType.serializer)', ], ); @@ -142,7 +142,7 @@ void main() { ); expect( type.deserialize('value'), - '(jsonSerializers.deserialize(value, specifiedType: const FullType(CustomType, [FullType(String)]))! as CustomType)', + 'jsonSerializers.deserialize(value, specifiedType: const FullType(CustomType, [FullType(String)]))! as CustomType', ); }); @@ -151,9 +151,9 @@ void main() { final type = TypeResultObject('ContentString', generics: BuiltList([subType])); expect(type.name, 'ContentString'); - expect(type.fullType, 'FullType(ContentString, [FullType(int)])'); + expect(type.fullType, 'const FullType(ContentString, [FullType(int)])'); expect(type.serializers.toList(), const [ - '..addBuilderFactory(FullType(ContentString, [FullType(int)]), ContentStringBuilder.new)', + '..addBuilderFactory(const FullType(ContentString, [FullType(int)]), ContentStringBuilder.new)', '..add(ContentString.serializer)', ]); expect( @@ -162,7 +162,7 @@ void main() { ); expect( type.deserialize('value'), - '(jsonSerializers.deserialize(value, specifiedType: const FullType(ContentString, [FullType(int)]))! as ContentString)', + 'jsonSerializers.deserialize(value, specifiedType: const FullType(ContentString, [FullType(int)]))! as ContentString', ); }); @@ -183,7 +183,7 @@ void main() { final type = TypeResultBase('String'); expect(type.name, 'String'); - expect(type.fullType, 'FullType(String)'); + expect(type.fullType, 'const FullType(String)'); expect(type.serializers.toList(), const []); expect( type.serialize('value'), @@ -191,7 +191,7 @@ void main() { ); expect( type.deserialize('value'), - '(jsonSerializers.deserialize(value, specifiedType: const FullType(String))! as String)', + 'jsonSerializers.deserialize(value, specifiedType: const FullType(String))! as String', ); }); diff --git a/packages/dynamite/dynamite_end_to_end_test/lib/nested_ofs.openapi.dart b/packages/dynamite/dynamite_end_to_end_test/lib/nested_ofs.openapi.dart index c43f04ee14b..2010fb8c57d 100644 --- a/packages/dynamite/dynamite_end_to_end_test/lib/nested_ofs.openapi.dart +++ b/packages/dynamite/dynamite_end_to_end_test/lib/nested_ofs.openapi.dart @@ -380,8 +380,8 @@ class _$8da5087c0b3f2cce06998d453af8ad19Serializer implements PrimitiveSerialize } catch (_) {} BaseAnyOf? baseAnyOf; try { - baseAnyOf = - ((serializers.deserialize(data, specifiedType: const FullType(BaseAnyOf))! as BaseAnyOf)..validateAnyOf()); + baseAnyOf = (serializers.deserialize(data, specifiedType: const FullType(BaseAnyOf))! as BaseAnyOf) + ..validateAnyOf(); } catch (_) {} BaseNestedOneOf3? baseNestedOneOf3; try { @@ -488,8 +488,8 @@ class _$523892e2348458a2bdb28f9f942dca37Serializer implements PrimitiveSerialize } catch (_) {} BaseOneOf? baseOneOf; try { - baseOneOf = - ((serializers.deserialize(data, specifiedType: const FullType(BaseOneOf))! as BaseOneOf)..validateOneOf()); + baseOneOf = (serializers.deserialize(data, specifiedType: const FullType(BaseOneOf))! as BaseOneOf) + ..validateOneOf(); } catch (_) {} int? $int; try { diff --git a/packages/dynamite/dynamite_end_to_end_test/lib/request_body.openapi.dart b/packages/dynamite/dynamite_end_to_end_test/lib/request_body.openapi.dart index aade09e6820..b3a01b5a908 100644 --- a/packages/dynamite/dynamite_end_to_end_test/lib/request_body.openapi.dart +++ b/packages/dynamite/dynamite_end_to_end_test/lib/request_body.openapi.dart @@ -134,7 +134,7 @@ class $Client extends DynamiteClient { // coverage:ignore-start @visibleForTesting -final Serializers serializers = Serializers().toBuilder().build(); +final Serializers serializers = Serializers(); @visibleForTesting final Serializers jsonSerializers = (serializers.toBuilder() ..add(DynamiteDoubleSerializer()) diff --git a/packages/dynamite/dynamite_end_to_end_test/lib/responses.openapi.dart b/packages/dynamite/dynamite_end_to_end_test/lib/responses.openapi.dart index c622d844206..f2213a4507c 100644 --- a/packages/dynamite/dynamite_end_to_end_test/lib/responses.openapi.dart +++ b/packages/dynamite/dynamite_end_to_end_test/lib/responses.openapi.dart @@ -219,7 +219,7 @@ class $Client extends DynamiteClient { // coverage:ignore-start @visibleForTesting -final Serializers serializers = Serializers().toBuilder().build(); +final Serializers serializers = Serializers(); @visibleForTesting final Serializers jsonSerializers = (serializers.toBuilder() ..add(DynamiteDoubleSerializer()) diff --git a/packages/nextcloud/lib/src/api/core.openapi.dart b/packages/nextcloud/lib/src/api/core.openapi.dart index e28de117028..67ef0e7a067 100644 --- a/packages/nextcloud/lib/src/api/core.openapi.dart +++ b/packages/nextcloud/lib/src/api/core.openapi.dart @@ -11273,17 +11273,17 @@ class _$3dc1754764311166375258bea55197c8Serializer implements PrimitiveSerialize } catch (_) {} SharebymailCapabilities? sharebymailCapabilities; try { - sharebymailCapabilities = ((serializers.deserialize(data, specifiedType: const FullType(SharebymailCapabilities))! + sharebymailCapabilities = (serializers.deserialize(data, specifiedType: const FullType(SharebymailCapabilities))! as SharebymailCapabilities) - ..validateOneOf()); + ..validateOneOf(); } catch (_) {} SpreedPublicCapabilities? spreedPublicCapabilities; try { - spreedPublicCapabilities = ((serializers.deserialize( + spreedPublicCapabilities = (serializers.deserialize( data, specifiedType: const FullType(SpreedPublicCapabilities), )! as SpreedPublicCapabilities) - ..validateOneOf()); + ..validateOneOf(); } catch (_) {} ThemingPublicCapabilities? themingPublicCapabilities; try {