+2
This commit is contained in:
parent
a5a8fdb52b
commit
759ce7c59e
7 changed files with 47 additions and 45 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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'] is Book
|
|
||||||
? data['newest_book']
|
? data['newest_book']
|
||||||
: new Book.fromJson(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;
|
||||||
|
|
|
@ -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']));
|
||||||
|
|
Loading…
Reference in a new issue