diff --git a/angel_serialize/lib/angel_serialize.dart b/angel_serialize/lib/angel_serialize.dart index 7b2d6ce3..77824ef0 100644 --- a/angel_serialize/lib/angel_serialize.dart +++ b/angel_serialize/lib/angel_serialize.dart @@ -28,6 +28,9 @@ const Serializable serializable = const Serializable(); /// The supported serialization types. abstract class Serializers { + /// All supported serialization types. + static const List all = const [map, json]; + /// Enable `fromMap` and `toMap` methods on the model class. static const int map = 0; diff --git a/angel_serialize_generator/lib/angel_serialize_generator.dart b/angel_serialize_generator/lib/angel_serialize_generator.dart index 8287cfae..9305efde 100644 --- a/angel_serialize_generator/lib/angel_serialize_generator.dart +++ b/angel_serialize_generator/lib/angel_serialize_generator.dart @@ -10,6 +10,7 @@ import 'package:source_gen/source_gen.dart' hide LibraryBuilder; import 'build_context.dart'; import 'context.dart'; part 'model.dart'; +part 'serialize.dart'; /// Converts a [DartType] to a [TypeReference]. TypeReference convertTypeReference(DartType t) { diff --git a/angel_serialize_generator/lib/serialize.dart b/angel_serialize_generator/lib/serialize.dart new file mode 100644 index 00000000..e02d4f95 --- /dev/null +++ b/angel_serialize_generator/lib/serialize.dart @@ -0,0 +1,42 @@ +part of angel_serialize_generator; + +class SerializerGenerator extends GeneratorForAnnotation { + final bool autoSnakeCaseNames; + + const SerializerGenerator({this.autoSnakeCaseNames: true}); + + @override + Future generateForAnnotatedElement( + Element element, ConstantReader annotation, BuildStep buildStep) async { + if (element.kind != ElementKind.CLASS) + throw 'Only classes can be annotated with a @Serializable() annotation.'; + + var ctx = await buildContext(element, annotation, buildStep, + await buildStep.resolver, true, autoSnakeCaseNames != false); + + var serializers = annotation.peek('serializers')?.listValue ?? []; + + if (serializers.isEmpty) return null; + + // Check if any serializer is recognized + if (!serializers.any((s) => Serializers.all.contains(s.toIntValue()))) { + return null; + } + + var lib = new File((b) { + generateClass(ctx, b); + }); + + var buf = lib.accept(new DartEmitter()); + return buf.toString(); + } + + /// Generate a serializer class. + void generateClass(BuildContext ctx, FileBuilder file) { + file.body.add(new Class((clazz) { + clazz + ..name = '${ctx.modelClassNameRecase.pascalCase}Serializer' + ..abstract = true; + })); + } +} diff --git a/angel_serialize_generator/test/models/author.serializer.g.dart b/angel_serialize_generator/test/models/author.serializer.g.dart new file mode 100644 index 00000000..cda3d0a7 --- /dev/null +++ b/angel_serialize_generator/test/models/author.serializer.g.dart @@ -0,0 +1,11 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of angel_serialize.test.models.author; + +// ************************************************************************** +// Generator: SerializerGenerator +// ************************************************************************** + +abstract class AuthorSerializer {} + +abstract class LibrarySerializer {} diff --git a/angel_serialize_generator/test/models/book.serializer.g.dart b/angel_serialize_generator/test/models/book.serializer.g.dart new file mode 100644 index 00000000..013834df --- /dev/null +++ b/angel_serialize_generator/test/models/book.serializer.g.dart @@ -0,0 +1,9 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of angel_serialize.test.models.book; + +// ************************************************************************** +// Generator: SerializerGenerator +// ************************************************************************** + +class BookSerializer extends _Book {} diff --git a/angel_serialize_generator/tool/actions.dart b/angel_serialize_generator/tool/actions.dart index cb9bbb3f..e4db08eb 100644 --- a/angel_serialize_generator/tool/actions.dart +++ b/angel_serialize_generator/tool/actions.dart @@ -3,18 +3,27 @@ import 'package:source_gen/source_gen.dart'; import 'package:angel_serialize_generator/angel_serialize_generator.dart'; final List actions = [ - new BuildAction( - new PartBuilder([const JsonModelGenerator()]), - 'angel_serialize_generator', - inputs: const [ - 'test/models/book.dart', - ], - ), - new BuildAction( - new PartBuilder([const JsonModelGenerator()]), - 'angel_serialize_generator', - inputs: const [ - 'test/models/author.dart', - ], - ), + jsonModel(const ['test/models/book.dart']), + jsonModel(const ['test/models/author.dart']), + angelSerialize(const ['test/models/book.dart']), + angelSerialize(const ['test/models/author.dart']), ]; + +BuildAction jsonModel(List inputs) { + return new BuildAction( + new PartBuilder([const JsonModelGenerator()]), + 'angel_serialize_generator', + inputs: inputs, + ); +} + +BuildAction angelSerialize(List inputs) { + return new BuildAction( + new PartBuilder( + [const SerializerGenerator()], + generatedExtension: '.serializer.g.dart', + ), + 'angel_serialize_generator', + inputs: inputs, + ); +}