Skip to content
This repository has been archived by the owner on Dec 15, 2023. It is now read-only.

Commit

Permalink
Initiate Dartson instance instead of create a new class + further ref…
Browse files Browse the repository at this point in the history
…actorings

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.
  • Loading branch information
eredo committed Sep 17, 2018
1 parent bd5b656 commit 52f3bbf
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 57 deletions.
1 change: 1 addition & 0 deletions changelog.md
Expand Up @@ -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)

Expand Down
24 changes: 12 additions & 12 deletions lib/src/generator/entity_generator.dart
Expand Up @@ -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; }'))
Expand All @@ -56,32 +56,32 @@ 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<String, dynamic>')
..requiredParameters.addAll([
Parameter((pb) => pb
..name = 'object'
..type = refer(classElement.displayName)),
..type = refer(_element.displayName)),
Parameter((pb) => pb
..name = 'inst'
..type = refer('Dartson', dartsonPackage))
])
..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);
Expand All @@ -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'
Expand Down
16 changes: 10 additions & 6 deletions lib/src/generator/entity_type_helper.dart
Expand Up @@ -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<ClassElement, ClassElement> entities;
EntityTypeHelper(this.entities);
final Map<ClassElement, ClassElement> _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)';
}
}
24 changes: 9 additions & 15 deletions lib/src/generator/generator.dart
Expand Up @@ -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';

Expand All @@ -19,24 +18,19 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializer> {
FutureOr<String> 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());
}
}
27 changes: 15 additions & 12 deletions lib/src/generator/serializer_generator.dart
Expand Up @@ -3,18 +3,26 @@ 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<Map<String, dynamic>>({/*...*/});
///
class DartsonGenerator {
final Set<ClassElement> objects;
final Set<ClassElement> _objects;
final Element _element;

DartsonGenerator(this.objects);
DartsonGenerator(this._objects, this._element);

String build(DartEmitter emitter) =>
_buildDartson().accept(emitter).toString();

Spec _buildDartson() {
final mapValues = <Object, Object>{};

objects.forEach((t) => mapValues[refer(t.displayName)] =
_objects.forEach((t) => mapValues[refer(t.displayName)] =
refer('DartsonEntity', dartsonPackage).constInstance([
refer(encodeMethod(t)),
refer(decodeMethod(t)),
Expand All @@ -25,14 +33,9 @@ class DartsonGenerator {
final lookupMap = literalMap(mapValues, refer('Type', 'dart:core'),
refer('DartsonEntity', dartsonPackage));

String dartsonTypeArguments = 'Map<String, dynamic>';

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<Map<String, dynamic>>', dartsonPackage)
.newInstance([lookupMap])
.assignFinal('_${_element.displayName}$serializerIdentifier')
.statement;
}
}
2 changes: 2 additions & 0 deletions lib/src/generator/transformer_generator.dart
Expand Up @@ -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<ClassElement> _transformers;
final Map<DartType, _Transformer> _transformerRef = {};
Expand Down
18 changes: 6 additions & 12 deletions test/src/serializer.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 52f3bbf

Please sign in to comment.