Updated serialize generator

This commit is contained in:
thomashii 2021-08-17 12:52:08 +08:00
parent 6f15e76d65
commit b8024e8120
5 changed files with 66 additions and 15 deletions

View file

@ -1,4 +1,3 @@
import 'dart:convert';
import 'package:intl/intl.dart' show DateFormat; import 'package:intl/intl.dart' show DateFormat;
import 'query.dart'; import 'query.dart';

View file

@ -2,7 +2,13 @@
## 4.1.2 ## 4.1.2
* Fixed `toMap` method generator * Fixed `toMap` method generation
* Fixed `fromMape` method generation
* Updated generator to add `const []` to `List` type args in the contructor
* Updated generator to product non nullable aware code
* Removed redudant null checking in the generated code
* Refactored away nullable code
* Added logging to facilitate tracing the code generation via `-verbose` flag
## 4.1.1 ## 4.1.1
@ -34,6 +40,7 @@
## 4.0.0 ## 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD * Migrated to support Dart SDK 2.12.x NNBD
* Importing `Optional` package is required for the ORM model
## 3.0.0 ## 3.0.0

View file

@ -155,6 +155,16 @@ bool isModelClass(DartType? t) {
} }
} }
bool isListType(DartType t) {
return const TypeChecker.fromRuntime(List).isAssignableFromType(t) &&
!const TypeChecker.fromRuntime(Uint8List).isAssignableFromType(t);
}
bool isMapType(DartType t) {
return const TypeChecker.fromRuntime(Map).isAssignableFromType(t) &&
!const TypeChecker.fromRuntime(Uint8List).isAssignableFromType(t);
}
bool isListOrMapType(DartType t) { bool isListOrMapType(DartType t) {
return (const TypeChecker.fromRuntime(List).isAssignableFromType(t) || return (const TypeChecker.fromRuntime(List).isAssignableFromType(t) ||
const TypeChecker.fromRuntime(Map).isAssignableFromType(t)) && const TypeChecker.fromRuntime(Map).isAssignableFromType(t)) &&

View file

@ -120,6 +120,7 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
..type = convertTypeReference(param.type))); ..type = convertTypeReference(param.type)));
} }
// Generate intializers
for (var field in ctx.fields) { for (var field in ctx.fields) {
if (!shouldBeConstant(ctx) && isListOrMapType(field.type)) { if (!shouldBeConstant(ctx) && isListOrMapType(field.type)) {
var typeName = const TypeChecker.fromRuntime(List) var typeName = const TypeChecker.fromRuntime(List)
@ -133,11 +134,17 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
defaultValue = dartObjectToString(existingDefault); defaultValue = dartObjectToString(existingDefault);
} }
if (field.type.nullabilitySuffix != NullabilitySuffix.question) {
constructor.initializers.add(Code(''' constructor.initializers.add(Code('''
this.${field.name} = ${field.name} =
$typeName.unmodifiable(${field.name})'''));
} else {
constructor.initializers.add(Code('''
${field.name} =
$typeName.unmodifiable(${field.name} ?? $defaultValue)''')); $typeName.unmodifiable(${field.name} ?? $defaultValue)'''));
} }
} }
}
// Generate the parameters for the constructor // Generate the parameters for the constructor
for (var field in ctx.fields) { for (var field in ctx.fields) {
@ -152,18 +159,30 @@ class JsonModelGenerator extends GeneratorForAnnotation<Serializable> {
var existingDefault = ctx.defaults[field.name]; var existingDefault = ctx.defaults[field.name];
if (existingDefault != null) { if (existingDefault != null) {
b.defaultTo = Code(dartObjectToString(existingDefault)!); var d = dartObjectToString(existingDefault);
if (d != null) {
b.defaultTo = Code(d);
}
} }
//log.fine(
// 'Constructor => ${field.name} ${field.type.nullabilitySuffix}');
if (!isListOrMapType(field.type)) { if (!isListOrMapType(field.type)) {
b.toThis = true; b.toThis = true;
} else if (!b.toThis) { } else if (isListType(field.type)) {
if (!b.toThis) {
b.type = convertTypeReference(field.type); b.type = convertTypeReference(field.type);
} }
b.defaultTo = Code('const []');
} else if (!b.toThis) {
b.type = convertTypeReference(field.type);
} else {
log.fine('Contructor: ${field.name} pass through');
}
if (ctx.requiredFields.containsKey(field.name) && if ((ctx.requiredFields.containsKey(field.name) ||
b.defaultTo == null || field.type.nullabilitySuffix != NullabilitySuffix.question) &&
(field.type.nullabilitySuffix != NullabilitySuffix.question)) { b.defaultTo == null) {
//b.annotations.add(CodeExpression(Code('required'))); //b.annotations.add(CodeExpression(Code('required')));
b.required = true; b.required = true;
} }

View file

@ -52,7 +52,7 @@ class SerializerGenerator extends GeneratorForAnnotation<Serializable> {
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.info('Generating ${pascal}Serializer');
if (ctx.constructorParameters.isEmpty) { if (ctx.constructorParameters.isEmpty) {
file.body.add(Code(''' file.body.add(Code('''
@ -189,9 +189,14 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
if (name.startsWith('_')) name = name.substring(1); if (name.startsWith('_')) name = name.substring(1);
var rc = ReCase(name); var rc = ReCase(name);
var m = serializerToMap(rc, 'm'); var m = serializerToMap(rc, 'm');
serializedRepresentation = '''
model.${field.name} var question =
?.map((m) => $m).toList()'''; (field.type.nullabilitySuffix == NullabilitySuffix.question)
? '?'
: '';
serializedRepresentation =
'model.${field.name}$question.map((m) => $m).toList()';
log.fine('serializedRepresentation => $serializedRepresentation');
} 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));
@ -201,10 +206,15 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
${serializerToMap(rc, 'model.${field.name}[key]')}; ${serializerToMap(rc, 'model.${field.name}[key]')};
})'''; })''';
} else if (type.element.isEnum) { } else if (type.element.isEnum) {
var convert =
(field.type.nullabilitySuffix == NullabilitySuffix.question)
? '!'
: '';
serializedRepresentation = ''' serializedRepresentation = '''
model.${field.name} == null ? model.${field.name} != null ?
null ${type.getDisplayString(withNullability: false)}.values.indexOf(model.${field.name}$convert)
: ${type.getDisplayString(withNullability: true)}.values.indexOf(model.${field.name}) : null
'''; ''';
} else if (const TypeChecker.fromRuntime(Uint8List) } else if (const TypeChecker.fromRuntime(Uint8List)
.isAssignableFromType(type)) { .isAssignableFromType(type)) {
@ -280,6 +290,12 @@ class ${pascal}Decoder extends Converter<Map, $pascal> {
var deserializedRepresentation = var deserializedRepresentation =
"map['$alias'] as ${typeToString(type)}"; "map['$alias'] as ${typeToString(type)}";
if (type.nullabilitySuffix == NullabilitySuffix.question) {
deserializedRepresentation += '?';
}
//log.fine(
// 'deserializedRepresentation => $deserializedRepresentation, type => $type, nullcheck => ${type.nullabilitySuffix}');
var defaultValue = 'null'; var defaultValue = 'null';
var existingDefault = ctx.defaults[field.name]; var existingDefault = ctx.defaults[field.name];