From 9c003572183ed11b2e49241db5e257a3208f7778 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sat, 2 Sep 2023 20:32:47 +0200 Subject: [PATCH] refactor(dynamite): further use source_gen Signed-off-by: Nikolas Rimikis --- .../dynamite/lib/src/builder/client.dart | 4 +- .../dynamite/lib/src/builder/imports.dart | 24 +++++++++ .../dynamite/lib/src/builder/serializer.dart | 39 +++++++++------ .../dynamite/lib/src/openapi_builder.dart | 49 +++++++++---------- 4 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 packages/dynamite/dynamite/lib/src/builder/imports.dart diff --git a/packages/dynamite/dynamite/lib/src/builder/client.dart b/packages/dynamite/dynamite/lib/src/builder/client.dart index ef8b05e9..3cd92687 100644 --- a/packages/dynamite/dynamite/lib/src/builder/client.dart +++ b/packages/dynamite/dynamite/lib/src/builder/client.dart @@ -11,7 +11,7 @@ import 'package:dynamite/src/models/path_item.dart'; import 'package:dynamite/src/models/schema.dart'; import 'package:dynamite/src/type_result/type_result.dart'; -List generateDynamiteOverrides(final State state) => [ +List generateDynamiteOverrides(final State state) => [ Class( (final b) => b ..name = '${state.classPrefix}Response' @@ -112,6 +112,8 @@ Iterable generateClients( final OpenAPI spec, final State state, ) sync* { + yield* generateDynamiteOverrides(state); + final tags = generateTags(spec); yield buildRootClient(spec, state, tags); diff --git a/packages/dynamite/dynamite/lib/src/builder/imports.dart b/packages/dynamite/dynamite/lib/src/builder/imports.dart new file mode 100644 index 00000000..c847f0d2 --- /dev/null +++ b/packages/dynamite/dynamite/lib/src/builder/imports.dart @@ -0,0 +1,24 @@ +import 'package:build/build.dart'; +import 'package:code_builder/code_builder.dart'; +import 'package:path/path.dart' as p; + +List generateImports(final AssetId outputId) => [ + const Code('// ignore_for_file: camel_case_types'), + const Code('// ignore_for_file: public_member_api_docs'), + Directive.import('dart:convert'), + Directive.import('dart:typed_data'), + const Code(''), + Directive.import('package:built_collection/built_collection.dart'), + Directive.import('package:built_value/built_value.dart'), + Directive.import('package:built_value/json_object.dart'), + Directive.import('package:built_value/serializer.dart'), + Directive.import('package:built_value/standard_json_plugin.dart'), + Directive.import('package:dynamite_runtime/content_string.dart'), + Directive.import('package:dynamite_runtime/http_client.dart'), + Directive.import('package:universal_io/io.dart'), + const Code(''), + Directive.export('package:dynamite_runtime/http_client.dart'), + const Code(''), + Directive.part(p.basename(outputId.changeExtension('.g.dart').path)), + const Code(''), + ]; diff --git a/packages/dynamite/dynamite/lib/src/builder/serializer.dart b/packages/dynamite/dynamite/lib/src/builder/serializer.dart index a4034a3e..bbd4d7ed 100644 --- a/packages/dynamite/dynamite/lib/src/builder/serializer.dart +++ b/packages/dynamite/dynamite/lib/src/builder/serializer.dart @@ -1,21 +1,32 @@ +import 'package:code_builder/code_builder.dart'; import 'package:dynamite/src/builder/state.dart'; -List buildSerializer(final State state) { +List buildSerializer(final State state) { if (state.resolvedTypes.isNotEmpty) { return [ - '// coverage:ignore-start', - 'final Serializers _serializers = (Serializers().toBuilder()', - ...state.resolvedTypes.map((final type) => type.serializers).expand((final element) => element).toSet(), - ').build();', - '', - 'Serializers get ${state.variablePrefix}Serializers => _serializers;', - '', - 'final Serializers _jsonSerializers = (_serializers.toBuilder()..addPlugin(StandardJsonPlugin())..addPlugin(const ContentStringPlugin())).build();', - '', - 'T deserialize${state.classPrefix}(final Object data) => _serializers.deserialize(data, specifiedType: FullType(T))! as T;', - '', - 'Object? serialize${state.classPrefix}(final T data) => _serializers.serialize(data, specifiedType: FullType(T));', - '// coverage:ignore-end', + const Code('// coverage:ignore-start'), + const Code('final Serializers _serializers = (Serializers().toBuilder()'), + ...state.resolvedTypes + .map((final type) => type.serializers) + .expand((final element) => element) + .toSet() + .map(Code.new), + const Code(').build();'), + const Code(''), + Code('Serializers get ${state.variablePrefix}Serializers => _serializers;'), + const Code(''), + const Code( + 'final Serializers _jsonSerializers = (_serializers.toBuilder()..addPlugin(StandardJsonPlugin())..addPlugin(const ContentStringPlugin())).build();', + ), + const Code(''), + Code( + 'T deserialize${state.classPrefix}(final Object data) => _serializers.deserialize(data, specifiedType: FullType(T))! as T;', + ), + const Code(''), + Code( + 'Object? serialize${state.classPrefix}(final T data) => _serializers.serialize(data, specifiedType: FullType(T));', + ), + const Code('// coverage:ignore-end'), ]; } diff --git a/packages/dynamite/dynamite/lib/src/openapi_builder.dart b/packages/dynamite/dynamite/lib/src/openapi_builder.dart index f9adc855..49804951 100644 --- a/packages/dynamite/dynamite/lib/src/openapi_builder.dart +++ b/packages/dynamite/dynamite/lib/src/openapi_builder.dart @@ -1,16 +1,17 @@ import 'dart:convert'; import 'package:build/build.dart'; +import 'package:built_collection/built_collection.dart'; import 'package:code_builder/code_builder.dart'; import 'package:dart_style/dart_style.dart'; import 'package:dynamite/src/builder/client.dart'; +import 'package:dynamite/src/builder/imports.dart'; import 'package:dynamite/src/builder/resolve_type.dart'; import 'package:dynamite/src/builder/serializer.dart'; import 'package:dynamite/src/builder/state.dart'; import 'package:dynamite/src/helpers/dart_helpers.dart'; import 'package:dynamite/src/models/open_api.dart'; import 'package:dynamite/src/type_result/type_result.dart'; -import 'package:path/path.dart' as p; class OpenAPIBuilder implements Builder { @override @@ -42,34 +43,21 @@ class OpenAPIBuilder implements Builder { final state = State(spec.info.title); - final output = [ - '// ignore_for_file: camel_case_types', - '// ignore_for_file: public_member_api_docs', - "import 'dart:convert';", - "import 'dart:typed_data';", - '', - "import 'package:built_collection/built_collection.dart';", - "import 'package:built_value/built_value.dart';", - "import 'package:built_value/json_object.dart';", - "import 'package:built_value/serializer.dart';", - "import 'package:built_value/standard_json_plugin.dart';", - "import 'package:dynamite_runtime/content_string.dart';", - "import 'package:dynamite_runtime/http_client.dart';", - "import 'package:universal_io/io.dart';", - '', - "export 'package:dynamite_runtime/http_client.dart';", - '', - "part '${p.basename(outputId.changeExtension('.g.dart').path)}';", - '', - ...generateDynamiteOverrides(state).map((final e) => e.accept(emitter).toString()), - ...generateClients(spec, state).map((final e) => e.accept(emitter).toString()), - ]; + final output = ListBuilder() + ..addAll(generateImports(outputId)) + ..addAll(generateClients(spec, state)); if (spec.components?.schemas != null) { for (final schema in spec.components!.schemas!.entries) { final identifier = toDartName(schema.key, uppercaseFirstCharacter: true); if (schema.value.type == null && schema.value.ref == null && schema.value.ofs == null) { - output.add('typedef $identifier = dynamic;'); + output.add( + TypeDef( + (final b) => b + ..name = identifier + ..definition = refer('dynamic'), + ), + ); } else { final result = resolveType( spec, @@ -78,14 +66,20 @@ class OpenAPIBuilder implements Builder { schema.value, ); if (result is TypeResultBase) { - output.add('typedef $identifier = ${result.name};'); + output.add( + TypeDef( + (final b) => b + ..name = identifier + ..definition = refer(result.name), + ), + ); } } } } output - ..addAll(state.output.map((final e) => e.accept(emitter).toString())) + ..addAll(state.output) ..addAll(buildSerializer(state)); final patterns = [ @@ -102,7 +96,8 @@ class OpenAPIBuilder implements Builder { r'static BuiltSet<.*> get values => _\$.*Values;', ), ]; - var outputString = output.join('\n'); + + var outputString = output.build().map((final e) => e.accept(emitter)).join('\n'); for (final pattern in patterns) { outputString = outputString.replaceAllMapped( pattern,