Split main lib

This commit is contained in:
Tobe O 2018-02-27 19:36:53 -05:00
parent 36b24480b2
commit 29ed032e61
7 changed files with 177 additions and 81 deletions

View file

@ -9,7 +9,6 @@ import 'package:code_builder/code_builder.dart';
import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
import 'build_context.dart';
import 'context.dart';
part 'model.dart';
/// Converts a [DartType] to a [TypeReference].
@ -21,81 +20,4 @@ TypeReference convertTypeReference(DartType t) {
b.types.addAll(t.typeArguments.map(convertTypeReference));
}
});
}
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, ConstantReader reader, BuildStep buildStep) async {
if (element.kind != ElementKind.CLASS)
throw 'Only classes can be annotated with a @Serializable() annotation.';
var ctx = await buildContext(
element,
serializable,
buildStep,
await buildStep.resolver,
autoSnakeCaseNames != false,
autoIdAndDateFields != false);
var lib = new File((b) {
generateClass(ctx, b);
});
var buf = lib.accept(new DartEmitter());
return buf.toString();
}
/// Generate an extended model class.
void generateClass(BuildContext ctx, FileBuilder file) {
file.body.add(new Class((clazz) {
clazz
..name = ctx.modelClassNameRecase.pascalCase
..extend = new Reference(ctx.originalClassName);
for (var field in ctx.fields) {
clazz.fields.add(new Field((b) {
b
..name = field.name
..modifier = FieldModifier.final$
..type = convertTypeReference(field.type);
}));
}
generateConstructor(ctx, clazz, file);
generateChangeMethod(ctx, clazz, file);
}));
}
/// Generate a constructor with named parameters.
void generateConstructor(
BuildContext ctx, ClassBuilder clazz, FileBuilder file) {
clazz.constructors.add(new Constructor((constructor) {
for (var field in ctx.fields) {
constructor.optionalParameters.add(new Parameter((b) {
b
..name = field.name
..named = true
..toThis = true;
}));
}
}));
}
/// Generate a `change` method.
void generateChangeMethod(
BuildContext ctx, ClassBuilder clazz, FileBuilder file) {
clazz.methods.add(new Method((method) {
method
..name = 'change'
..returns = ctx.modelClassType
..requiredParameters.add(new Parameter());
}));
}
}
}

View file

@ -36,7 +36,9 @@ Future<BuildContext> buildContext(
fieldNames.add(field.name);
// Skip if annotated with @exclude
var excludeAnnotation = excludeTypeChecker.firstAnnotationOf(field);
if (excludeAnnotation != null) continue;
ctx.excluded[field.name] = excludeAnnotation != null;
// Check for alias
Alias alias;
var aliasAnn = aliasTypeChecker.firstAnnotationOf(field);

View file

@ -11,6 +11,9 @@ class BuildContext {
/// A map of field names to resolved names from `@Alias()` declarations.
final Map<String, String> aliases = {};
/// A map of fields that have been marked as to be excluded from serialization.
final Map<String, bool> excluded = {};
/// A map of "synthetic" fields, i.e. `id` and `created_at` injected automatically.
final Map<String, bool> shimmed = {};

View file

@ -1,2 +1,98 @@
part of angel_serialize_generator;
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, ConstantReader reader, BuildStep buildStep) async {
if (element.kind != ElementKind.CLASS)
throw 'Only classes can be annotated with a @Serializable() annotation.';
var ctx = await buildContext(
element,
serializable,
buildStep,
await buildStep.resolver,
autoSnakeCaseNames != false,
autoIdAndDateFields != false);
var lib = new File((b) {
generateClass(ctx, b);
});
var buf = lib.accept(new DartEmitter());
return buf.toString();
}
/// Generate an extended model class.
void generateClass(BuildContext ctx, FileBuilder file) {
file.body.add(new Class((clazz) {
clazz
..name = ctx.modelClassNameRecase.pascalCase
..extend = new Reference(ctx.originalClassName);
for (var field in ctx.fields) {
clazz.fields.add(new Field((b) {
b
..name = field.name
..modifier = FieldModifier.final$
..annotations
.add(new Annotation((b) => b.code = new Code('override')))
..type = convertTypeReference(field.type);
}));
}
generateConstructor(ctx, clazz, file);
generateCopyWithMethod(ctx, clazz, file);
}));
}
/// Generate a constructor with named parameters.
void generateConstructor(
BuildContext ctx, ClassBuilder clazz, FileBuilder file) {
clazz.constructors.add(new Constructor((constructor) {
for (var field in ctx.fields) {
constructor.optionalParameters.add(new Parameter((b) {
b
..name = field.name
..named = true
..toThis = true;
}));
}
}));
}
/// Generate a `copyWith` method.
void generateCopyWithMethod(
BuildContext ctx, ClassBuilder clazz, FileBuilder file) {
clazz.methods.add(new Method((method) {
method
..name = 'copyWith'
..returns = ctx.modelClassType;
var buf = new StringBuffer('return new ${ctx.modelClassName}(');
int i = 0;
// Add named parameters
for (var field in ctx.fields) {
method.optionalParameters.add(new Parameter((b) {
b
..name = field.name
..named = true
..type = convertTypeReference(field.type);
}));
if (i++ > 0) buf.write(', ');
buf.write('${field.name}: ${field.name} ?? this.${field.name}');
}
buf.write(');');
method.body = new Code(buf.toString());
}));
}
}

View file

@ -3,6 +3,7 @@ library angel_serialize.test.models.author;
import 'package:angel_framework/common.dart';
import 'package:angel_serialize/angel_serialize.dart';
import 'book.dart';
part 'author.g.dart';
@serializable
@ -18,4 +19,4 @@ abstract class _Author extends Model {
@serializable
abstract class _Library extends Model {
Map<String, Book> collection;
}
}

View file

@ -13,32 +13,79 @@ class Author extends _Author {
this.age,
this.books,
this.newestBook,
this.secret,
this.createdAt,
this.updatedAt});
@override
final String id;
@override
final String name;
@override
final int age;
@override
final List<Book> books;
@override
final Book newestBook;
@override
final String secret;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Author copyWith(
{String id,
String name,
int age,
List<Book> books,
Book newestBook,
String secret,
DateTime createdAt,
DateTime updatedAt}) {
return new Author(
id: id ?? this.id,
name: name ?? this.name,
age: age ?? this.age,
books: books ?? this.books,
newestBook: newestBook ?? this.newestBook,
secret: secret ?? this.secret,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
}
class Library extends _Library {
Library({this.id, this.collection, this.createdAt, this.updatedAt});
@override
final String id;
@override
final Map<String, Book> collection;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Library copyWith(
{String id,
Map<String, Book> collection,
DateTime createdAt,
DateTime updatedAt}) {
return new Library(
id: id ?? this.id,
collection: collection ?? this.collection,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
}

View file

@ -16,17 +16,42 @@ class Book extends _Book {
this.createdAt,
this.updatedAt});
@override
final String id;
@override
final String author;
@override
final String title;
@override
final String description;
@override
final int pageCount;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Book copyWith(
{String id,
String author,
String title,
String description,
int pageCount,
DateTime createdAt,
DateTime updatedAt}) {
return new Book(
id: id ?? this.id,
author: author ?? this.author,
title: title ?? this.title,
description: description ?? this.description,
pageCount: pageCount ?? this.pageCount,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
}