This commit is contained in:
thosakwe 2017-09-14 20:20:36 -04:00
parent a5a8fdb52b
commit 759ce7c59e
7 changed files with 47 additions and 45 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
# Created by .ignore support plugin (hsz.mobi)

View file

@ -5,25 +5,25 @@ import 'package:angel_serialize/angel_serialize.dart';
import 'package:build/build.dart'; import 'package:build/build.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:code_builder/dart/core.dart'; import 'package:code_builder/dart/core.dart';
import 'package:source_gen/src/annotation.dart'; import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
import 'package:source_gen/source_gen.dart';
import 'build_context.dart'; import 'build_context.dart';
import 'context.dart'; import 'context.dart';
class JsonModelGenerator extends GeneratorForAnnotation<Serializable> { class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
final bool autoSnakeCaseNames; final bool autoSnakeCaseNames;
final bool autoIdAndDateFields; final bool autoIdAndDateFields;
const JsonModelGenerator( const JsonModelGenerator(
{this.autoSnakeCaseNames: true, this.autoIdAndDateFields: true}); {this.autoSnakeCaseNames: true, this.autoIdAndDateFields: true});
@override @override
Future<String> generateForAnnotatedElement( Future<String> generateForAnnotatedElement(
Element element, Serializable annotation, BuildStep buildStep) async { Element element, ConstantReader reader, BuildStep buildStep) async {
if (element.kind != ElementKind.CLASS) if (element.kind != ElementKind.CLASS)
throw 'Only classes can be annotated with a @Serializable() annotation.'; throw 'Only classes can be annotated with a @Serializable() annotation.';
var ctx = buildContext( var ctx = buildContext(
element, element,
annotation, serializable,
buildStep, buildStep,
await buildStep.resolver, await buildStep.resolver,
autoSnakeCaseNames != false, autoSnakeCaseNames != false,
@ -73,6 +73,12 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
literal(null), reference(field.name).invoke('toIso8601String', [])); literal(null), reference(field.name).invoke('toIso8601String', []));
} }
// Serialize models
else if (serializableTypeChecker.firstAnnotationOf(field.type.element) !=
null) {
value = reference(field.name).invoke('toJson', []);
}
// Anything else // Anything else
else { else {
value = reference(field.name); value = reference(field.name);
@ -126,8 +132,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
fromJsonClassName = genericClass.displayName; fromJsonClassName = genericClass.displayName;
} else { } else {
// If it has a serializable annotation, act accordingly. // If it has a serializable annotation, act accordingly.
if (genericClass.metadata if (serializableTypeChecker.firstAnnotationOf(genericClass) != null) {
.any((ann) => matchAnnotation(Serializable, ann))) {
fromJsonClassName = genericClass.displayName.substring(1); fromJsonClassName = genericClass.displayName.substring(1);
hasFromJson = true; hasFromJson = true;
} }
@ -166,8 +171,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
fromJsonClassName = type.displayName; fromJsonClassName = type.displayName;
} else { } else {
// If it has a serializable annotation, act accordingly. // If it has a serializable annotation, act accordingly.
if (genericClass.metadata if (serializableTypeChecker.firstAnnotationOf(genericClass) != null) {
.any((ann) => matchAnnotation(Serializable, ann))) {
fromJsonClassName = type.displayName.substring(1); fromJsonClassName = type.displayName.substring(1);
hasFromJson = true; hasFromJson = true;
} }
@ -202,8 +206,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
fromJsonClassName = targetType.displayName; fromJsonClassName = targetType.displayName;
} else { } else {
// If it has a serializable annotation, act accordingly. // If it has a serializable annotation, act accordingly.
if (genericClass.metadata if (serializableTypeChecker.firstAnnotationOf(genericClass) != null) {
.any((ann) => matchAnnotation(Serializable, ann))) {
fromJsonClassName = targetType.displayName.substring(1); fromJsonClassName = targetType.displayName.substring(1);
hasFromJson = true; hasFromJson = true;
} }
@ -242,6 +245,17 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
} }
} }
// Deerialize models
if (!done &&
serializableTypeChecker.firstAnnotationOf(field.type.element) !=
null) {
var typeName = field.type.name;
typeName.startsWith('_') ? typeName = typeName.substring(1) : null;
var typeBuilder = new TypeBuilder(typeName);
value = mapKey.isInstanceOf(typeBuilder).ternary(
mapKey, typeBuilder.newInstance([mapKey], constructor: 'fromJson'));
}
return out..[field.name] = value; return out..[field.name] = value;
}); });
fromJson fromJson

View file

@ -5,10 +5,16 @@ import 'package:angel_serialize/angel_serialize.dart';
import 'package:build/build.dart'; import 'package:build/build.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'package:source_gen/src/annotation.dart'; import 'package:source_gen/source_gen.dart';
import 'src/find_annotation.dart';
import 'context.dart'; import 'context.dart';
const TypeChecker aliasTypeChecker = const TypeChecker.fromRuntime(Alias);
const TypeChecker excludeTypeChecker = const TypeChecker.fromRuntime(Exclude);
const TypeChecker serializableTypeChecker =
const TypeChecker.fromRuntime(Serializable);
// TODO: Should add id, createdAt, updatedAt... // TODO: Should add id, createdAt, updatedAt...
BuildContext buildContext( BuildContext buildContext(
ClassElement clazz, ClassElement clazz,
@ -28,12 +34,15 @@ BuildContext buildContext(
if (field.getter != null && field.setter != null) { if (field.getter != null && field.setter != null) {
fieldNames.add(field.name); fieldNames.add(field.name);
// Skip if annotated with @exclude // Skip if annotated with @exclude
var excludeAnnotation = field.metadata.firstWhere( var excludeAnnotation = excludeTypeChecker.firstAnnotationOf(field);
(ann) => matchAnnotation(Exclude, ann),
orElse: () => null);
if (excludeAnnotation != null) continue; if (excludeAnnotation != null) continue;
// Check for alias // Check for alias
var alias = findAnnotation<Alias>(field, Alias); Alias alias;
var aliasAnn = aliasTypeChecker.firstAnnotationOf(field);
if (aliasAnn != null) {
alias = new Alias(aliasAnn.getField('name').toStringValue());
}
if (alias?.name?.isNotEmpty == true) { if (alias?.name?.isNotEmpty == true) {
ctx.aliases[field.name] = alias.name; ctx.aliases[field.name] = alias.name;

View file

@ -1,8 +0,0 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:source_gen/src/annotation.dart';
T findAnnotation<T>(FieldElement field, Type outType) {
var first = field.metadata
.firstWhere((ann) => matchAnnotation(outType, ann), orElse: () => null);
return first == null ? null : instantiateAnnotation(first);
}

View file

@ -1,5 +1,5 @@
name: angel_serialize_generator name: angel_serialize_generator
version: 1.0.0-alpha+1 version: 1.0.0-alpha+2
description: Model serialization generators, designed for use with Angel. description: Model serialization generators, designed for use with Angel.
author: Tobe O <thosakwe@gmail.com> author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/serialize homepage: https://github.com/angel-dart/serialize
@ -7,11 +7,10 @@ environment:
sdk: ">=1.19.0" sdk: ">=1.19.0"
dependencies: dependencies:
angel_serialize: ^1.0.0-alpha angel_serialize: ^1.0.0-alpha
build: ^0.9.0
code_builder: ^1.0.0 code_builder: ^1.0.0
id: ^1.0.0 id: ^1.0.0
recase: ^1.0.0 recase: ^1.0.0
source_gen: ^0.6.0 source_gen: ^0.7.0
dev_dependencies: dev_dependencies:
angel_framework: ^1.0.0 angel_framework: ^1.0.0
build_runner: ^0.3.0 build_runner: ^0.3.0

View file

@ -4,7 +4,6 @@ part of angel_serialize.test.models.book;
// ************************************************************************** // **************************************************************************
// Generator: JsonModelGenerator // Generator: JsonModelGenerator
// Target: abstract class _Book
// ************************************************************************** // **************************************************************************
class Book extends _Book { class Book extends _Book {
@ -74,11 +73,6 @@ class Book extends _Book {
} }
} }
// **************************************************************************
// Generator: JsonModelGenerator
// Target: abstract class _Author
// **************************************************************************
class Author extends _Author { class Author extends _Author {
@override @override
String id; String id;
@ -121,11 +115,9 @@ class Author extends _Author {
x == null ? null : (x is Book ? x : new Book.fromJson(x))) x == null ? null : (x is Book ? x : new Book.fromJson(x)))
.toList() .toList()
: null, : null,
newestBook: data['newest_book'] == null newestBook: data['newest_book'] is Book
? null ? data['newest_book']
: (data['newest_book'] is Book : new Book.fromJson(data['newest_book']),
? data['newest_book']
: new Book.fromJson(data['newest_book'])),
createdAt: data['created_at'] is DateTime createdAt: data['created_at'] is DateTime
? data['created_at'] ? data['created_at']
: (data['created_at'] is String : (data['created_at'] is String
@ -143,7 +135,7 @@ class Author extends _Author {
'name': name, 'name': name,
'age': age, 'age': age,
'books': books, 'books': books,
'newest_book': newestBook, 'newest_book': newestBook.toJson(),
'created_at': createdAt == null ? null : createdAt.toIso8601String(), 'created_at': createdAt == null ? null : createdAt.toIso8601String(),
'updated_at': updatedAt == null ? null : updatedAt.toIso8601String() 'updated_at': updatedAt == null ? null : updatedAt.toIso8601String()
}; };
@ -155,11 +147,6 @@ class Author extends _Author {
} }
} }
// **************************************************************************
// Generator: JsonModelGenerator
// Target: abstract class _Library
// **************************************************************************
class Library extends _Library { class Library extends _Library {
@override @override
String id; String id;

View file

@ -3,5 +3,5 @@ import 'package:source_gen/source_gen.dart';
import 'package:angel_serialize_generator/angel_serialize_generator.dart'; import 'package:angel_serialize_generator/angel_serialize_generator.dart';
final PhaseGroup PHASES = new PhaseGroup.singleAction( final PhaseGroup PHASES = new PhaseGroup.singleAction(
new GeneratorBuilder([const JsonModelGenerator()]), new PartBuilder([const JsonModelGenerator()]),
new InputSet('angel_serialize_generator', const ['test/models/*.dart'])); new InputSet('angel_serialize_generator', const ['test/models/*.dart']));