Updated serialize generator
This commit is contained in:
parent
4f36170ead
commit
1f57b79c6d
11 changed files with 53 additions and 78 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -74,4 +74,5 @@ logs/
|
||||||
*.pem
|
*.pem
|
||||||
.DS_Store
|
.DS_Store
|
||||||
server_log.txt
|
server_log.txt
|
||||||
ormapp/
|
ormapp/
|
||||||
|
backup/
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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}');
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue