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:code_builder/code_builder.dart';
import 'package:code_builder/dart/core.dart';
import 'package:source_gen/src/annotation.dart';
import 'package:source_gen/source_gen.dart';
import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
import 'build_context.dart';
import 'context.dart';
class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
final bool autoSnakeCaseNames;
final bool autoIdAndDateFields;
const JsonModelGenerator(
{this.autoSnakeCaseNames: true, this.autoIdAndDateFields: true});
@override
Future<String> generateForAnnotatedElement(
Element element, Serializable annotation, BuildStep buildStep) async {
Element element, ConstantReader reader, BuildStep buildStep) async {
if (element.kind != ElementKind.CLASS)
throw 'Only classes can be annotated with a @Serializable() annotation.';
var ctx = buildContext(
element,
annotation,
serializable,
buildStep,
await buildStep.resolver,
autoSnakeCaseNames != false,
@ -73,6 +73,12 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
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
else {
value = reference(field.name);
@ -126,8 +132,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
fromJsonClassName = genericClass.displayName;
} else {
// If it has a serializable annotation, act accordingly.
if (genericClass.metadata
.any((ann) => matchAnnotation(Serializable, ann))) {
if (serializableTypeChecker.firstAnnotationOf(genericClass) != null) {
fromJsonClassName = genericClass.displayName.substring(1);
hasFromJson = true;
}
@ -166,8 +171,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
fromJsonClassName = type.displayName;
} else {
// If it has a serializable annotation, act accordingly.
if (genericClass.metadata
.any((ann) => matchAnnotation(Serializable, ann))) {
if (serializableTypeChecker.firstAnnotationOf(genericClass) != null) {
fromJsonClassName = type.displayName.substring(1);
hasFromJson = true;
}
@ -202,8 +206,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
fromJsonClassName = targetType.displayName;
} else {
// If it has a serializable annotation, act accordingly.
if (genericClass.metadata
.any((ann) => matchAnnotation(Serializable, ann))) {
if (serializableTypeChecker.firstAnnotationOf(genericClass) != null) {
fromJsonClassName = targetType.displayName.substring(1);
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;
});
fromJson

View file

@ -5,10 +5,16 @@ import 'package:angel_serialize/angel_serialize.dart';
import 'package:build/build.dart';
import 'package:path/path.dart' as p;
import 'package:recase/recase.dart';
import 'package:source_gen/src/annotation.dart';
import 'src/find_annotation.dart';
import 'package:source_gen/source_gen.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...
BuildContext buildContext(
ClassElement clazz,
@ -28,12 +34,15 @@ BuildContext buildContext(
if (field.getter != null && field.setter != null) {
fieldNames.add(field.name);
// Skip if annotated with @exclude
var excludeAnnotation = field.metadata.firstWhere(
(ann) => matchAnnotation(Exclude, ann),
orElse: () => null);
var excludeAnnotation = excludeTypeChecker.firstAnnotationOf(field);
if (excludeAnnotation != null) continue;
// 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) {
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
version: 1.0.0-alpha+1
version: 1.0.0-alpha+2
description: Model serialization generators, designed for use with Angel.
author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/serialize
@ -7,11 +7,10 @@ environment:
sdk: ">=1.19.0"
dependencies:
angel_serialize: ^1.0.0-alpha
build: ^0.9.0
code_builder: ^1.0.0
id: ^1.0.0
recase: ^1.0.0
source_gen: ^0.6.0
source_gen: ^0.7.0
dev_dependencies:
angel_framework: ^1.0.0
build_runner: ^0.3.0

View file

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

View file

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