mirror of https://github.com/AMT-Cheif/drift.git
Fix nnbd generation around type converters (#968)
This commit is contained in:
parent
a749f38e2b
commit
5db10342b0
|
@ -289,8 +289,8 @@ class ConfigTable extends Table with TableInfo<ConfigTable, Config> {
|
||||||
return ConfigTable(_db, alias);
|
return ConfigTable(_db, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeConverter<SyncType?, int?> $converter0 = const SyncTypeConverter();
|
static TypeConverter<SyncType, int> $converter0 = const SyncTypeConverter();
|
||||||
static TypeConverter<SyncType?, int?> $converter1 =
|
static TypeConverter<SyncType?, int> $converter1 =
|
||||||
const EnumIndexConverter<SyncType>(SyncType.values);
|
const EnumIndexConverter<SyncType>(SyncType.values);
|
||||||
@override
|
@override
|
||||||
bool get dontWriteConstraints => true;
|
bool get dontWriteConstraints => true;
|
||||||
|
@ -1614,7 +1614,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
||||||
readsFrom: {config}).map(config.mapFromRow);
|
readsFrom: {config}).map(config.mapFromRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
Selectable<String> typeConverterVar(SyncType? var1, List<SyncType?> var2) {
|
Selectable<String> typeConverterVar(SyncType var1, List<SyncType?> var2) {
|
||||||
var $arrayStartIndex = 2;
|
var $arrayStartIndex = 2;
|
||||||
final expandedvar2 = $expandVar($arrayStartIndex, var2.length);
|
final expandedvar2 = $expandVar($arrayStartIndex, var2.length);
|
||||||
$arrayStartIndex += var2.length;
|
$arrayStartIndex += var2.length;
|
||||||
|
@ -1623,7 +1623,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
||||||
variables: [
|
variables: [
|
||||||
Variable<int>(ConfigTable.$converter0.mapToSql(var1)!),
|
Variable<int>(ConfigTable.$converter0.mapToSql(var1)!),
|
||||||
for (var $ in var2)
|
for (var $ in var2)
|
||||||
Variable<int>(ConfigTable.$converter1.mapToSql($)!)
|
Variable<int?>(ConfigTable.$converter1.mapToSql($)!)
|
||||||
],
|
],
|
||||||
readsFrom: {
|
readsFrom: {
|
||||||
config
|
config
|
||||||
|
|
|
@ -558,7 +558,7 @@ class $CategoriesTable extends Categories
|
||||||
return $CategoriesTable(_db, alias);
|
return $CategoriesTable(_db, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeConverter<CategoryPriority, int?> $converter0 =
|
static TypeConverter<CategoryPriority, int> $converter0 =
|
||||||
const EnumIndexConverter<CategoryPriority>(CategoryPriority.values);
|
const EnumIndexConverter<CategoryPriority>(CategoryPriority.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1316,7 +1316,7 @@ class $TableWithoutPKTable extends TableWithoutPK
|
||||||
return $TableWithoutPKTable(_db, alias);
|
return $TableWithoutPKTable(_db, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeConverter<MyCustomObject, String?> $converter0 =
|
static TypeConverter<MyCustomObject, String> $converter0 =
|
||||||
const CustomConverter();
|
const CustomConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import 'package:moor_generator/src/model/used_type_converter.dart';
|
||||||
import 'package:moor_generator/src/utils/names.dart';
|
import 'package:moor_generator/src/utils/names.dart';
|
||||||
import 'package:moor_generator/src/utils/string_escaper.dart';
|
import 'package:moor_generator/src/utils/string_escaper.dart';
|
||||||
import 'package:moor_generator/src/utils/type_converter_hint.dart';
|
import 'package:moor_generator/src/utils/type_converter_hint.dart';
|
||||||
|
import 'package:moor_generator/src/utils/type_utils.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
@ -217,8 +218,11 @@ class CreateTableReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
final interfaceType = type as InterfaceType;
|
final interfaceType = type as InterfaceType;
|
||||||
// TypeConverter declares a "D mapToDart(S fromDb);". We need to know D
|
final asTypeConverter = interfaceType.allSupertypes.firstWhere(
|
||||||
final typeInDart = interfaceType.getMethod('mapToDart').returnType;
|
(type) => isFromMoor(type) && type.element.name == 'TypeConverter');
|
||||||
|
|
||||||
|
// TypeConverter<D, S>, where D is the type in Dart
|
||||||
|
final typeInDart = asTypeConverter.typeArguments.first;
|
||||||
|
|
||||||
return UsedTypeConverter(
|
return UsedTypeConverter(
|
||||||
expression: code, mappedType: typeInDart, sqlType: sqlType);
|
expression: code, mappedType: typeInDart, sqlType: sqlType);
|
||||||
|
|
|
@ -17,6 +17,11 @@ abstract class HasType {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension OperationOnTypes on HasType {
|
extension OperationOnTypes on HasType {
|
||||||
|
/// Whether this type is nullable in Dart
|
||||||
|
bool get nullableInDart {
|
||||||
|
return nullable || typeConverter?.hasNullableDartType == true;
|
||||||
|
}
|
||||||
|
|
||||||
/// the Dart type of this column that can be handled by moors type mapping.
|
/// the Dart type of this column that can be handled by moors type mapping.
|
||||||
/// Basically the same as [dartTypeCode], minus custom types and nullability.
|
/// Basically the same as [dartTypeCode], minus custom types and nullability.
|
||||||
String get variableTypeName => dartTypeNames[type];
|
String get variableTypeName => dartTypeNames[type];
|
||||||
|
@ -30,7 +35,7 @@ extension OperationOnTypes on HasType {
|
||||||
/// This is the same as [dartTypeCode] but without custom types.
|
/// This is the same as [dartTypeCode] but without custom types.
|
||||||
String variableTypeCode(
|
String variableTypeCode(
|
||||||
[GenerationOptions options = const GenerationOptions()]) {
|
[GenerationOptions options = const GenerationOptions()]) {
|
||||||
final hasSuffix = nullable && options.nnbd;
|
final hasSuffix = nullableInDart && options.nnbd;
|
||||||
return hasSuffix ? '$variableTypeName?' : variableTypeName;
|
return hasSuffix ? '$variableTypeName?' : variableTypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +44,10 @@ extension OperationOnTypes on HasType {
|
||||||
/// [int].
|
/// [int].
|
||||||
String dartTypeCode([GenerationOptions options = const GenerationOptions()]) {
|
String dartTypeCode([GenerationOptions options = const GenerationOptions()]) {
|
||||||
if (typeConverter != null) {
|
if (typeConverter != null) {
|
||||||
return typeConverter.mappedType?.codeString(options);
|
final needsSuffix = nullable && !typeConverter.hasNullableDartType;
|
||||||
|
final baseType = typeConverter.mappedType.codeString(options);
|
||||||
|
|
||||||
|
return needsSuffix ? '$baseType?' : baseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return variableTypeCode(options);
|
return variableTypeCode(options);
|
||||||
|
|
|
@ -37,6 +37,9 @@ class UsedTypeConverter {
|
||||||
@required this.sqlType,
|
@required this.sqlType,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bool get hasNullableDartType =>
|
||||||
|
mappedType.nullabilitySuffix == NullabilitySuffix.question;
|
||||||
|
|
||||||
factory UsedTypeConverter.forEnumColumn(DartType enumType, bool nullable) {
|
factory UsedTypeConverter.forEnumColumn(DartType enumType, bool nullable) {
|
||||||
if (enumType.element is! ClassElement) {
|
if (enumType.element is! ClassElement) {
|
||||||
throw InvalidTypeForEnumConverterException('Not a class', enumType);
|
throw InvalidTypeForEnumConverterException('Not a class', enumType);
|
||||||
|
@ -61,7 +64,7 @@ class UsedTypeConverter {
|
||||||
|
|
||||||
/// A suitable typename to store an instance of the type converter used here.
|
/// A suitable typename to store an instance of the type converter used here.
|
||||||
String converterNameInCode(GenerationOptions options) {
|
String converterNameInCode(GenerationOptions options) {
|
||||||
final sqlDartType = options.nullableType(dartTypeNames[sqlType]);
|
final sqlDartType = dartTypeNames[sqlType];
|
||||||
return 'TypeConverter<${mappedType.codeString(options)}, $sqlDartType>';
|
return 'TypeConverter<${mappedType.codeString(options)}, $sqlDartType>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,15 +176,17 @@ class DataClassWriter {
|
||||||
for (var i = 0; i < table.columns.length; i++) {
|
for (var i = 0; i < table.columns.length; i++) {
|
||||||
final column = table.columns[i];
|
final column = table.columns[i];
|
||||||
final last = i == table.columns.length - 1;
|
final last = i == table.columns.length - 1;
|
||||||
|
final isNullable = column.nullableInDart;
|
||||||
|
|
||||||
final typeName = column.dartTypeCode(scope.generationOptions);
|
final typeName = column.dartTypeCode(scope.generationOptions);
|
||||||
if (wrapNullableInValue && column.nullable) {
|
if (wrapNullableInValue && isNullable) {
|
||||||
_buffer
|
_buffer
|
||||||
..write('Value<$typeName> ${column.dartGetterName} ')
|
..write('Value<$typeName> ${column.dartGetterName} ')
|
||||||
..write('= const Value.absent()');
|
..write('= const Value.absent()');
|
||||||
} else if (!column.nullable && scope.generationOptions.nnbd) {
|
} else if (!isNullable && scope.generationOptions.nnbd) {
|
||||||
// We always write nullable types in the copyWith constructor, since all
|
// We always use nullable parameters in copyWith, since all parameters
|
||||||
// parameters are optional.
|
// are optional. The !isNullable check is there to avoid a duplicate
|
||||||
|
// question mark in the type name.
|
||||||
_buffer.write('$typeName? ${column.dartGetterName}');
|
_buffer.write('$typeName? ${column.dartGetterName}');
|
||||||
} else {
|
} else {
|
||||||
_buffer.write('$typeName ${column.dartGetterName}');
|
_buffer.write('$typeName ${column.dartGetterName}');
|
||||||
|
|
Loading…
Reference in New Issue