Merge pull request #1682 from westito/type-converter-workaround

TypeConverter not existent type argument class workaround
This commit is contained in:
Simon Binder 2022-02-14 22:15:57 +01:00 committed by GitHub
commit 101db403c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 80 additions and 13 deletions

View File

@ -129,12 +129,12 @@ void _checkType(ParameterElement element, MoorColumn column, Step step) {
return;
}
DartType expectedDartType;
DriftDartType expectedDartType;
if (column.typeConverter != null) {
expectedDartType = column.typeConverter!.mappedType;
} else {
expectedDartType = provider.typeFor(column.type);
expectedDartType = DriftDartType.of(provider.typeFor(column.type));
}
// BLOB columns should be stored in an Uint8List (or a supertype of that).
@ -146,7 +146,8 @@ void _checkType(ParameterElement element, MoorColumn column, Step step) {
type.element.name == 'Uint8List' &&
type.element.library.name == 'dart.typed_data';
if (!typesystem.isAssignableTo(expectedDartType, type) &&
if (expectedDartType.type != null &&
!typesystem.isAssignableTo(expectedDartType.type!, type) &&
!isAllowedUint8List) {
error('Parameter must accept '
'${expectedDartType.getDisplayString(withNullability: true)}');

View File

@ -70,7 +70,7 @@ class ColumnParser {
Expression? foundDefaultExpression;
Expression? clientDefaultExpression;
Expression? createdTypeConverter;
DartType? typeConverterRuntime;
DriftDartType? typeConverterRuntime;
ColumnGeneratedAs? generatedAs;
var nullable = false;
@ -247,9 +247,22 @@ class ColumnParser {
// the map method has a parameter type that resolved to the runtime
// type of the custom object
final type = remainingExpr.typeArgumentTypes!.single;
createdTypeConverter = expression;
typeConverterRuntime = type;
// If converter type argument is dynamic, the referenced
// class is not exists yet. We assume it will be generated
if (type is DynamicType ||
type is InterfaceType &&
type.typeArguments.isNotEmpty &&
type.typeArguments.single.isDynamic &&
remainingExpr.typeArguments != null) {
typeConverterRuntime = DriftDartType(
name: remainingExpr.typeArguments!.arguments[0].toSource(),
nullabilitySuffix: NullabilitySuffix.none,
);
} else {
typeConverterRuntime = DriftDartType.of(type);
}
break;
case _methodGenerated:
Expression? generatedExpression;

View File

@ -265,7 +265,9 @@ class CreateTableReader {
final typeInDart = asTypeConverter.typeArguments.first;
return UsedTypeConverter(
expression: code, mappedType: typeInDart, sqlType: sqlType);
expression: code,
mappedType: DriftDartType.of(typeInDart),
sqlType: sqlType);
}
Future<DartType?> _readDartType(String typeIdentifier) async {

View File

@ -1,3 +1,5 @@
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:drift_dev/src/model/model.dart';
import 'package:drift_dev/src/utils/type_utils.dart';
import 'package:drift_dev/writer.dart';
@ -22,6 +24,55 @@ abstract class HasType {
UsedTypeConverter? get typeConverter;
}
class DriftDartType {
final DartType? type;
final String name;
final NullabilitySuffix nullabilitySuffix;
const DriftDartType({
this.type,
required this.name,
required this.nullabilitySuffix,
});
factory DriftDartType.of(DartType type) {
return DriftDartType(
type: type,
name: type.toString(),
nullabilitySuffix: type.nullabilitySuffix,
);
}
String getDisplayString({required bool withNullability}) {
if (type != null) {
return type!.getDisplayString(withNullability: withNullability);
}
if (withNullability) {
switch (nullabilitySuffix) {
case NullabilitySuffix.question:
return '$name?';
case NullabilitySuffix.star:
return '$name*';
case NullabilitySuffix.none:
return '$name';
}
}
return '$name';
}
String codeString([GenerationOptions options = const GenerationOptions()]) {
if (type != null) {
return type!.codeString(options);
}
if (nullabilitySuffix == NullabilitySuffix.star) {
return getDisplayString(withNullability: false);
}
return getDisplayString(withNullability: options.nnbd);
}
}
extension OperationOnTypes on HasType {
/// Whether this type is nullable in Dart
bool get nullableInDart {

View File

@ -21,7 +21,7 @@ class UsedTypeConverter {
final String expression;
/// The type that will be present at runtime.
final DartType mappedType;
final DriftDartType mappedType;
/// The type that will be written to the database.
final ColumnType sqlType;
@ -56,10 +56,11 @@ class UsedTypeConverter {
return UsedTypeConverter(
expression: 'const EnumIndexConverter<$className>($className.values)',
mappedType: creatingClass.instantiate(
typeArguments: const [],
nullabilitySuffix:
nullable ? NullabilitySuffix.question : NullabilitySuffix.none),
mappedType: DriftDartType(
name: creatingClass.name,
nullabilitySuffix:
nullable ? NullabilitySuffix.question : NullabilitySuffix.none,
),
sqlType: ColumnType.integer,
);
}

View File

@ -1,7 +1,6 @@
import 'package:drift/sqlite_keywords.dart';
import 'package:drift_dev/moor_generator.dart';
import 'package:drift_dev/src/utils/string_escaper.dart';
import 'package:drift_dev/src/utils/type_utils.dart';
import 'package:drift_dev/writer.dart';
import 'package:sqlparser/sqlparser.dart';