From 52f3bbf91e2038089bcd0fce05ae1d0d8afe5638 Mon Sep 17 00:00:00 2001 From: Eric Schneller Date: Mon, 17 Sep 2018 20:07:08 +0200 Subject: [PATCH] Initiate Dartson instance instead of create a new class + further refactorings Previously the generator created a completely new implementation of Dartson defining the generic types and passing the map of entities in the super constructor call. This is no longer necessary and removed. --- changelog.md | 1 + lib/src/generator/entity_generator.dart | 24 ++++++++--------- lib/src/generator/entity_type_helper.dart | 16 +++++++----- lib/src/generator/generator.dart | 24 +++++++---------- lib/src/generator/serializer_generator.dart | 27 +++++++++++--------- lib/src/generator/transformer_generator.dart | 2 ++ test/src/serializer.g.dart | 18 +++++-------- 7 files changed, 55 insertions(+), 57 deletions(-) diff --git a/changelog.md b/changelog.md index 3664e66..1988152 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ **Breaking changes** - `DateTimeParser` is deprecated. The default is now the `json_serializable` implementation and it's no longer necessary to register a transformer at all. +- Generator no longer create `_Dartson$impl` class instance and instead calls `Dartson` constructor directly ## 1.0.0-alpha+2 (09/17/2018) diff --git a/lib/src/generator/entity_generator.dart b/lib/src/generator/entity_generator.dart index 1775346..0c47d13 100644 --- a/lib/src/generator/entity_generator.dart +++ b/lib/src/generator/entity_generator.dart @@ -34,12 +34,12 @@ class EntityGenerator { ]); String build(DartEmitter emitter) => (StringBuffer() - ..write(_buildEncoder(_element).accept(emitter)) - ..write(_buildDecoder(_element).accept(emitter)) + ..write(_buildEncoder().accept(emitter)) + ..write(_buildDecoder().accept(emitter)) ..writeAll(_fieldContexts.expand((f) => f.members).toSet())) .toString(); - Method _buildEncoder(ClassElement classElement) { + Method _buildEncoder() { final obj = refer('obj'); final block = BlockBuilder() ..statements.add(Code('if (object == null) { return null; }')) @@ -56,20 +56,20 @@ class EntityGenerator { _fieldContexts.add(fieldContext); block.addExpression(obj - .index(literalString(fieldProperty.name ?? field.name)) - .assign(CodeExpression(Code( - fieldContext.serialize(field.type, 'object.${field.name}'))))); + .index(literalString(fieldProperty.name ?? field.displayName)) + .assign(CodeExpression(Code(fieldContext.serialize( + field.type, 'object.${field.displayName}'))))); } block.addExpression(obj.returned); return Method((b) => b - ..name = encodeMethod(classElement) + ..name = encodeMethod(_element) ..returns = refer('Map') ..requiredParameters.addAll([ Parameter((pb) => pb ..name = 'object' - ..type = refer(classElement.displayName)), + ..type = refer(_element.displayName)), Parameter((pb) => pb ..name = 'inst' ..type = refer('Dartson', dartsonPackage)) @@ -77,11 +77,11 @@ class EntityGenerator { ..body = block.build()); } - Method _buildDecoder(ClassElement classElement) { + Method _buildDecoder() { final block = BlockBuilder() ..statements.add(Code('if (data == null) { return null; }')) ..addExpression( - refer(classElement.displayName).newInstance([]).assignFinal('obj')); + refer(_element.displayName).newInstance([]).assignFinal('obj')); for (var field in _fields) { final fieldProperty = propertyAnnotation(field); @@ -99,8 +99,8 @@ class EntityGenerator { block.addExpression(refer('obj').returned); return Method((b) => b - ..name = decodeMethod(classElement) - ..returns = refer(classElement.displayName) + ..name = decodeMethod(_element) + ..returns = refer(_element.displayName) ..requiredParameters.addAll([ Parameter((pb) => pb ..name = 'data' diff --git a/lib/src/generator/entity_type_helper.dart b/lib/src/generator/entity_type_helper.dart index db088a0..9eefe19 100644 --- a/lib/src/generator/entity_type_helper.dart +++ b/lib/src/generator/entity_type_helper.dart @@ -4,29 +4,33 @@ import 'package:json_serializable/type_helper.dart'; import 'identifier.dart'; +/// Helper which looks up if a [DartType] exists within a list of [_entities] +/// and returns the code for the proper calls to encode/decode method. The list +/// of entities is provided by the generator based on entities, transformers +/// and replacements. class EntityTypeHelper implements TypeHelper { - final Map entities; - EntityTypeHelper(this.entities); + final Map _entities; + EntityTypeHelper(this._entities); @override String deserialize( DartType targetType, String expression, DeserializeContext context) { final target = targetType.element as ClassElement; - if (!entities.containsKey(target)) { + if (!_entities.containsKey(target)) { return null; } - return '${decodeMethod(entities[target])}($expression, inst)'; + return '${decodeMethod(_entities[target])}($expression, inst)'; } @override String serialize( DartType targetType, String expression, SerializeContext context) { final target = targetType.element as ClassElement; - if (!entities.containsKey(target)) { + if (!_entities.containsKey(target)) { return null; } - return '${encodeMethod(entities[target])}($expression, inst)'; + return '${encodeMethod(_entities[target])}($expression, inst)'; } } diff --git a/lib/src/generator/generator.dart b/lib/src/generator/generator.dart index 8e22e7b..6bbed23 100644 --- a/lib/src/generator/generator.dart +++ b/lib/src/generator/generator.dart @@ -10,7 +10,6 @@ import '../annotations.dart'; import 'entity_type_helper.dart'; import 'entity_generator.dart'; import 'generator_settings.dart'; -import 'identifier.dart'; import 'transformer_generator.dart'; import 'serializer_generator.dart'; @@ -19,24 +18,19 @@ class SerializerGenerator extends GeneratorForAnnotation { FutureOr generateForAnnotatedElement( Element element, ConstantReader annotation, BuildStep buildStep) { final settings = GeneratorSettings.fromConstant(annotation); - final trans = TransformerGenerator(settings.transformers); - final entityHelper = EntityTypeHelper(settings.entities); + final transformers = TransformerGenerator(settings.transformers); + final entities = EntityTypeHelper(settings.entities); final emitter = DartEmitter(); - final str = StringBuffer(); + final buffer = StringBuffer(); - str.write(trans.build(emitter)); - str.writeAll(settings.entities.values - .map((e) => EntityGenerator(e, trans, entityHelper).build(emitter))); + buffer.write(transformers.build(emitter)); + buffer.writeAll(settings.entities.values + .map((e) => EntityGenerator(e, transformers, entities).build(emitter))); - str.write( - DartsonGenerator(settings.entities.values.toSet()).build(emitter)); - str.write(refer(implementationIdentifier) - .newInstance([]) - .assignFinal('_${element.name}$serializerIdentifier') - .statement - .accept(emitter)); + buffer.write(DartsonGenerator(settings.entities.values.toSet(), element) + .build(emitter)); - return DartFormatter().format(str.toString()); + return DartFormatter().format(buffer.toString()); } } diff --git a/lib/src/generator/serializer_generator.dart b/lib/src/generator/serializer_generator.dart index 0a29d5e..e0230c4 100644 --- a/lib/src/generator/serializer_generator.dart +++ b/lib/src/generator/serializer_generator.dart @@ -3,10 +3,18 @@ import 'package:code_builder/code_builder.dart'; import 'identifier.dart'; +/// Generator which initiates the [Dartson] instance passing the map of +/// entities and assigning it to the serializer value adding `$dartson` suffix. +/// +/// **Output:** +/// +/// final _serializer$dartson = new Dartson>({/*...*/}); +/// class DartsonGenerator { - final Set objects; + final Set _objects; + final Element _element; - DartsonGenerator(this.objects); + DartsonGenerator(this._objects, this._element); String build(DartEmitter emitter) => _buildDartson().accept(emitter).toString(); @@ -14,7 +22,7 @@ class DartsonGenerator { Spec _buildDartson() { final mapValues = {}; - objects.forEach((t) => mapValues[refer(t.displayName)] = + _objects.forEach((t) => mapValues[refer(t.displayName)] = refer('DartsonEntity', dartsonPackage).constInstance([ refer(encodeMethod(t)), refer(decodeMethod(t)), @@ -25,14 +33,9 @@ class DartsonGenerator { final lookupMap = literalMap(mapValues, refer('Type', 'dart:core'), refer('DartsonEntity', dartsonPackage)); - String dartsonTypeArguments = 'Map'; - - final constr = Constructor( - (mb) => mb..initializers.add(refer('super').call([lookupMap]).code)); - - return Class((cb) => cb - ..name = implementationIdentifier - ..extend = refer('Dartson<$dartsonTypeArguments>', dartsonPackage) - ..constructors.add(constr)); + return refer('Dartson>', dartsonPackage) + .newInstance([lookupMap]) + .assignFinal('_${_element.displayName}$serializerIdentifier') + .statement; } } diff --git a/lib/src/generator/transformer_generator.dart b/lib/src/generator/transformer_generator.dart index c3fb225..515c32c 100644 --- a/lib/src/generator/transformer_generator.dart +++ b/lib/src/generator/transformer_generator.dart @@ -5,6 +5,8 @@ import 'package:json_serializable/type_helper.dart'; import '../exceptions.dart'; +/// Helper which looks up if a [DartType] has a [TypeTransformer] implementation +/// defined and calls the encode/decode method on the [TypeTransformer]. class TransformerGenerator implements TypeHelper { final Iterable _transformers; final Map _transformerRef = {}; diff --git a/test/src/serializer.g.dart b/test/src/serializer.g.dart index 036898a..ba1bb24 100644 --- a/test/src/serializer.g.dart +++ b/test/src/serializer.g.dart @@ -126,15 +126,9 @@ MyImpl _MyImpl$decoder(Map data, Dartson inst) { return obj; } -class _Dartson$impl extends Dartson> { - _Dartson$impl() - : super({ - MyClass: - const DartsonEntity(_MyClass$encoder, _MyClass$decoder), - SubClass: const DartsonEntity( - _SubClass$encoder, _SubClass$decoder), - MyImpl: const DartsonEntity(_MyImpl$encoder, _MyImpl$decoder) - }); -} - -final _serializer$dartson = new _Dartson$impl(); +final _serializer$dartson = + new Dartson>({ + MyClass: const DartsonEntity(_MyClass$encoder, _MyClass$decoder), + SubClass: const DartsonEntity(_SubClass$encoder, _SubClass$decoder), + MyImpl: const DartsonEntity(_MyImpl$encoder, _MyImpl$decoder) +});