Add type checks to parent class option

This commit is contained in:
westito 2022-02-14 10:03:46 +01:00
parent 4c2e74d5e0
commit 46ca0462bf
4 changed files with 54 additions and 13 deletions

View File

@ -76,7 +76,8 @@ class TableParser {
if (dataClassName != null) {
name = dataClassName.getField('name')!.toStringValue()!;
customParentClass = parseCustomParentClass(dataClassName, element, base);
customParentClass =
parseCustomParentClass(name, dataClassName, element, base);
} else {
name = dataClassNameForClassName(element.name);
}

View File

@ -36,7 +36,7 @@ class ViewParser {
_DataClassInformation _readDataClassInformation(
List<MoorColumn> columns, ClassElement element) {
DartObject? useRowClass;
String? dataClassName;
DartObject? driftView;
String? customParentClass;
for (final annotation in element.metadata) {
@ -44,14 +44,13 @@ class ViewParser {
final annotationClass = computed!.type!.element!.name;
if (annotationClass == 'DriftView') {
dataClassName = computed.getField('dataClassName')?.toStringValue();
customParentClass = parseCustomParentClass(computed, element, base);
driftView = computed;
} else if (annotationClass == 'UseRowClass') {
useRowClass = computed;
}
}
if (dataClassName != null && useRowClass != null) {
if (driftView != null && useRowClass != null) {
base.step.reportError(ErrorInDartCode(
message: "A table can't be annotated with both @DataClassName and "
'@UseRowClass',
@ -63,7 +62,15 @@ class ViewParser {
String? constructorInExistingClass;
bool? generateInsertable;
var name = dataClassName ?? dataClassNameForClassName(element.name);
var name = dataClassNameForClassName(element.name);
if (driftView != null) {
final dataClassName =
driftView.getField('dataClassName')?.toStringValue();
name = dataClassName ?? dataClassNameForClassName(element.name);
customParentClass =
parseCustomParentClass(name, driftView, element, base);
}
if (useRowClass != null) {
final type = useRowClass.getField('type')!.toTypeValue();

View File

@ -3,6 +3,7 @@ import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:drift_dev/src/analyzer/dart/parser.dart';
import 'package:drift_dev/src/analyzer/errors.dart';
import 'package:drift_dev/src/utils/type_utils.dart';
String dataClassNameForClassName(String tableName) {
// This implementation is very primitive at the moment. The basic idea is
@ -21,19 +22,53 @@ String dataClassNameForClassName(String tableName) {
return '${tableName}Data';
}
String? parseCustomParentClass(
DartObject dataClassName, ClassElement element, MoorDartParser base) {
String? parseCustomParentClass(String dartTypeName, DartObject dataClassName,
ClassElement element, MoorDartParser base) {
final extending = dataClassName.getField('extending');
if (extending != null && !extending.isNull) {
final extendingType = extending.toTypeValue();
if (extendingType is InterfaceType) {
final superType = extendingType.allSupertypes
.any((type) => isFromMoor(type) && type.element.name == 'DataClass');
if (!superType) {
base.step.reportError(
ErrorInDartCode(
message: 'Parameter `extending` in @DataClassName must be subtype '
'of DataClass',
affectedElement: element,
),
);
return null;
}
if (extendingType.typeArguments.length > 1) {
base.step.reportError(
ErrorInDartCode(
message: 'Parameter `extending` in @DataClassName must have zero or'
' one type parameter',
affectedElement: element,
),
);
return null;
}
final className = extendingType.element.name;
if (extendingType.typeArguments.length == 1) {
final genericType = extendingType.typeArguments[0].element?.name;
if (genericType == 'dynamic') {
return '$className<dynamic>';
if (genericType == 'Object') {
return '$className<$dartTypeName>';
} else {
base.step.reportError(
ErrorInDartCode(
message: 'Parameter `extending` in @DataClassName can only have '
'`Object` as type parameter: `YourType<Object>`',
affectedElement: element,
),
);
return null;
}
}
return className;
} else {
base.step.reportError(

View File

@ -24,9 +24,7 @@ class DataClassWriter {
: 'driftRuntimeOptions';
void write() {
final customParent = table.customParentClass
?.replaceFirst('<dynamic>', '<${table.dartTypeName}>');
final parentClass = customParent ?? 'DataClass';
final parentClass = table.customParentClass ?? 'DataClass';
_buffer.write('class ${table.dartTypeName} extends $parentClass ');
if (isInsertable) {