Updated serialize generator

This commit is contained in:
thomashii 2021-08-15 16:04:21 +08:00
parent 4f36170ead
commit 1f57b79c6d
11 changed files with 53 additions and 78 deletions

3
.gitignore vendored
View file

@ -74,4 +74,5 @@ logs/
*.pem *.pem
.DS_Store .DS_Store
server_log.txt server_log.txt
ormapp/ ormapp/
backup/

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/serialize.iml" filepath="$PROJECT_DIR$/.idea/serialize.iml" />
</modules>
</component>
</project>

View file

@ -1,8 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="tests in angel_serialize_generator" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true" nameIsGenerated="true">
<option name="filePath" value="$PROJECT_DIR$/angel_serialize_generator" />
<option name="scope" value="FOLDER" />
<option name="testRunnerOptions" value="-j 4" />
<method />
</configuration>
</component>

View file

@ -1,7 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="tests in enum_test.dart" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true" nameIsGenerated="true">
<option name="filePath" value="$PROJECT_DIR$/angel_serialize_generator/test/enum_test.dart" />
<option name="testRunnerOptions" value="-j4" />
<method />
</configuration>
</component>

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$/angel_serialize">
<excludeFolder url="file://$MODULE_DIR$/angel_serialize/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/angel_serialize/.pub" />
<excludeFolder url="file://$MODULE_DIR$/angel_serialize/build" />
</content>
<content url="file://$MODULE_DIR$/angel_serialize_generator">
<excludeFolder url="file://$MODULE_DIR$/angel_serialize_generator/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/angel_serialize_generator/.pub" />
<excludeFolder url="file://$MODULE_DIR$/angel_serialize_generator/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -1,5 +1,9 @@
# Change Log # Change Log
## 4.1.2
* Fixed `toMap` method generator
## 4.1.1 ## 4.1.1
* Fixed `SerializerGenerator` to recognize nullable class * Fixed `SerializerGenerator` to recognize nullable class

View file

@ -1,6 +1,6 @@
# Angel3 Serialize Generator # Angel3 Serialize Generator
[![version](https://img.shields.io/badge/pub-v4.1.1-brightgreen)](https://pub.dartlang.org/packages/angel3_serialize_generator) [![version](https://img.shields.io/badge/pub-v4.1.2-brightgreen)](https://pub.dartlang.org/packages/angel3_serialize_generator)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion) [![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)

View file

@ -30,7 +30,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
void generateClass( void generateClass(
BuildContext ctx, LibraryBuilder file, ConstantReader annotation) { BuildContext ctx, LibraryBuilder file, ConstantReader annotation) {
file.body.add(Class((clazz) { file.body.add(Class((clazz) {
log.fine('Generate Class: ${ctx.modelClassNameRecase.pascalCase}'); //log.fine('Generate Class: ${ctx.modelClassNameRecase.pascalCase}');
clazz clazz
..name = ctx.modelClassNameRecase.pascalCase ..name = ctx.modelClassNameRecase.pascalCase
..annotations.add(refer('generatedSerializable')); ..annotations.add(refer('generatedSerializable'));
@ -50,7 +50,8 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
// Generate the fields for the class // Generate the fields for the class
for (var field in ctx.fields) { for (var field in ctx.fields) {
log.fine('Generate Field: ${field.name}'); //log.fine('Generate Field: ${field.name}');
clazz.fields.add(Field((b) { clazz.fields.add(Field((b) {
b b
..name = field.name ..name = field.name
@ -106,11 +107,11 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) { BuildContext ctx, ClassBuilder clazz, LibraryBuilder file) {
clazz.constructors.add(Constructor((constructor) { clazz.constructors.add(Constructor((constructor) {
// Add all `super` params // Add all `super` params
constructor.constant = (ctx.clazz.unnamedConstructor?.isConst == true || //constructor.constant = (ctx.clazz.unnamedConstructor?.isConst == true ||
shouldBeConstant(ctx)) && // shouldBeConstant(ctx)) &&
ctx.fields.every((f) { // ctx.fields.every((f) {
return f.setter == null && f is! ShimFieldImpl; // return f.setter == null && f is! ShimFieldImpl;
}); // });
for (var param in ctx.constructorParameters) { for (var param in ctx.constructorParameters) {
//log.fine('Contructor Parameter: ${param.name}'); //log.fine('Contructor Parameter: ${param.name}');

View file

@ -8,7 +8,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
@override @override
Future<String?> generateForAnnotatedElement( Future<String?> generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) async { Element element, ConstantReader annotation, BuildStep buildStep) async {
log.fine('Running SerializerGenerator'); //log.fine('Running SerializerGenerator');
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.';
@ -39,20 +39,20 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
generateFieldsClass(ctx, b); generateFieldsClass(ctx, b);
}); });
var buf = lib.accept(DartEmitter()); var buf = lib.accept(DartEmitter(useNullSafetySyntax: true));
return buf.toString(); return buf.toString();
} }
/// Generate a serializer class. /// Generate a serializer class.
void generateClass( void generateClass(
List<int> serializers, BuildContext ctx, LibraryBuilder file) { List<int> serializers, BuildContext ctx, LibraryBuilder file) {
log.fine('Generate serailizer class'); //log.fine('Generate serializer class');
// Generate canonical codecs, etc. // Generate canonical codecs, etc.
var pascal = ctx.modelClassNameRecase.pascalCase.replaceAll('?', ''); var pascal = ctx.modelClassNameRecase.pascalCase.replaceAll('?', '');
var camel = ctx.modelClassNameRecase.camelCase.replaceAll('?', ''); var camel = ctx.modelClassNameRecase.camelCase.replaceAll('?', '');
log.fine('Pascal = $pascal, camel = $camel'); //log.fine('Pascal = $pascal, camel = $camel');
if (ctx.constructorParameters.isEmpty) { if (ctx.constructorParameters.isEmpty) {
file.body.add(Code(''' file.body.add(Code('''
@ -112,6 +112,11 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
void generateToMapMethod( void generateToMapMethod(
ClassBuilder clazz, BuildContext ctx, LibraryBuilder file) { ClassBuilder clazz, BuildContext ctx, LibraryBuilder file) {
var originalClassName = ctx.originalClassName;
if (originalClassName == null) {
log.warning('Unable to generate toMap(), classname is null');
return;
}
clazz.methods.add(Method((method) { clazz.methods.add(Method((method) {
method method
..static = true ..static = true
@ -120,7 +125,9 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
..requiredParameters.add(Parameter((b) { ..requiredParameters.add(Parameter((b) {
b b
..name = 'model' ..name = 'model'
..type = refer(ctx.originalClassName!); ..type = TypeReference((b) => b
..symbol = '$originalClassName'
..isNullable = true);
})); }));
var buf = StringBuffer(); var buf = StringBuffer();
@ -159,9 +166,9 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
return '${rc.pascalCase.replaceAll('?', '')}Serializer.toMap($value)'; return '${rc.pascalCase.replaceAll('?', '')}Serializer.toMap($value)';
} }
if (ctx.fieldInfo[field.name]?.serializer != null) { var fieldNameSerializer = ctx.fieldInfo[field.name]?.serializer;
var name = if (fieldNameSerializer != null) {
MirrorSystem.getName(ctx.fieldInfo[field.name]!.serializer!); var name = MirrorSystem.getName(fieldNameSerializer);
serializedRepresentation = '$name(model.${field.name})'; serializedRepresentation = '$name(model.${field.name})';
} }
@ -184,8 +191,7 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
var m = serializerToMap(rc, 'm'); var m = serializerToMap(rc, 'm');
serializedRepresentation = ''' serializedRepresentation = '''
model.${field.name} model.${field.name}
?.map((m) => $m) ?.map((m) => $m).toList()''';
?.toList()''';
} else if (isMapToModelType(type)) { } else if (isMapToModelType(type)) {
var rc = ReCase( var rc = ReCase(
type.typeArguments[1].getDisplayString(withNullability: true)); type.typeArguments[1].getDisplayString(withNullability: true));
@ -215,7 +221,7 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
buf.write('};'); buf.write('};');
method.body = Block.of([ method.body = Block.of([
// Code('if (model == null) { return null; }'), Code('if (model == null) { return {}; }'),
Code(buf.toString()), Code(buf.toString()),
]); ]);
})); }));
@ -275,18 +281,21 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
var deserializedRepresentation = var deserializedRepresentation =
"map['$alias'] as ${typeToString(type)}"; "map['$alias'] as ${typeToString(type)}";
String? defaultValue = 'null'; var defaultValue = 'null';
var existingDefault = ctx.defaults[field.name]; var existingDefault = ctx.defaults[field.name];
if (existingDefault != null) { if (existingDefault != null) {
defaultValue = dartObjectToString(existingDefault); var d = dartObjectToString(existingDefault);
if (d != null) {
defaultValue = d;
}
deserializedRepresentation = deserializedRepresentation =
'$deserializedRepresentation ?? $defaultValue'; '$deserializedRepresentation ?? $defaultValue';
} }
if (ctx.fieldInfo[field.name]?.deserializer != null) { var fieldNameDeserializer = ctx.fieldInfo[field.name]?.deserializer;
var name = if (fieldNameDeserializer != null) {
MirrorSystem.getName(ctx.fieldInfo[field.name]!.deserializer!); var name = MirrorSystem.getName(fieldNameDeserializer);
deserializedRepresentation = "$name(map['$alias'])"; deserializedRepresentation = "$name(map['$alias'])";
} else if (dateTimeTypeChecker.isAssignableFromType(type)) { } else if (dateTimeTypeChecker.isAssignableFromType(type)) {
deserializedRepresentation = "map['$alias'] != null ? " deserializedRepresentation = "map['$alias'] != null ? "
@ -302,6 +311,9 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
' : $defaultValue'; ' : $defaultValue';
} else if (type is InterfaceType) { } else if (type is InterfaceType) {
if (isListOfModelType(type)) { if (isListOfModelType(type)) {
if (defaultValue == 'null') {
defaultValue = '[]';
}
var rc = ReCase( var rc = ReCase(
type.typeArguments[0].getDisplayString(withNullability: true)); type.typeArguments[0].getDisplayString(withNullability: true));
deserializedRepresentation = "map['$alias'] is Iterable" deserializedRepresentation = "map['$alias'] is Iterable"
@ -310,8 +322,13 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
'.map(${rc.pascalCase.replaceAll('?', '')}Serializer.fromMap))' '.map(${rc.pascalCase.replaceAll('?', '')}Serializer.fromMap))'
' : $defaultValue'; ' : $defaultValue';
} else if (isMapToModelType(type)) { } else if (isMapToModelType(type)) {
if (defaultValue == 'null') {
defaultValue = '{}';
}
var rc = ReCase( var rc = ReCase(
type.typeArguments[1].getDisplayString(withNullability: true)); type.typeArguments[1].getDisplayString(withNullability: true));
deserializedRepresentation = ''' deserializedRepresentation = '''
map['$alias'] is Map map['$alias'] is Map
? Map.unmodifiable((map['$alias'] as Map).keys.fold({}, (out, key) { ? Map.unmodifiable((map['$alias'] as Map).keys.fold({}, (out, key) {
@ -335,7 +352,7 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
.isAssignableFromType(type) && .isAssignableFromType(type) &&
type.typeArguments.length == 1) { type.typeArguments.length == 1) {
var arg = convertTypeReference(type.typeArguments[0]) var arg = convertTypeReference(type.typeArguments[0])
.accept(DartEmitter()); .accept(DartEmitter(useNullSafetySyntax: true));
deserializedRepresentation = ''' deserializedRepresentation = '''
map['$alias'] is Iterable map['$alias'] is Iterable
? (map['$alias'] as Iterable).cast<$arg>().toList() ? (map['$alias'] as Iterable).cast<$arg>().toList()
@ -345,9 +362,9 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
.isAssignableFromType(type) && .isAssignableFromType(type) &&
type.typeArguments.length == 2) { type.typeArguments.length == 2) {
var key = convertTypeReference(type.typeArguments[0]) var key = convertTypeReference(type.typeArguments[0])
.accept(DartEmitter()); .accept(DartEmitter(useNullSafetySyntax: true));
var value = convertTypeReference(type.typeArguments[1]) var value = convertTypeReference(type.typeArguments[1])
.accept(DartEmitter()); .accept(DartEmitter(useNullSafetySyntax: true));
deserializedRepresentation = ''' deserializedRepresentation = '''
map['$alias'] is Map map['$alias'] is Map
? (map['$alias'] as Map).cast<$key, $value>() ? (map['$alias'] as Map).cast<$key, $value>()
@ -382,7 +399,7 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
} }
void generateFieldsClass(BuildContext ctx, LibraryBuilder file) { void generateFieldsClass(BuildContext ctx, LibraryBuilder file) {
log.fine('Generate serializer fields'); //log.fine('Generate serializer fields');
file.body.add(Class((clazz) { file.body.add(Class((clazz) {
clazz clazz

View file

@ -1,5 +1,5 @@
name: angel3_serialize_generator name: angel3_serialize_generator
version: 4.1.1 version: 4.1.2
description: Angel3 model serialization generators, designed for use with Angel. Combine with angel_serialize for flexible modeling. description: Angel3 model serialization generators, designed for use with Angel. Combine with angel_serialize for flexible modeling.
homepage: https://angel3-framework.web.app/ homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/serialize/angel_serialize_generator repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/serialize/angel_serialize_generator