diff --git a/drift_dev/lib/src/analyzer/custom_row_class.dart b/drift_dev/lib/src/analyzer/custom_row_class.dart index e3670a9a..31c411d6 100644 --- a/drift_dev/lib/src/analyzer/custom_row_class.dart +++ b/drift_dev/lib/src/analyzer/custom_row_class.dart @@ -7,7 +7,7 @@ import 'package:drift_dev/src/analyzer/errors.dart'; import 'package:drift_dev/src/analyzer/runner/steps.dart'; class FoundDartClass { - final ClassElement classElement; + final InterfaceElement classElement; /// The instantiation of the [classElement], if the found type was a generic /// typedef. @@ -143,8 +143,8 @@ void _checkType(ParameterElement element, MoorColumn column, Step step) { final isAllowedUint8List = column.typeConverter == null && column.type == ColumnType.blob && type is InterfaceType && - type.element.name == 'Uint8List' && - type.element.library.name == 'dart.typed_data'; + type.element2.name == 'Uint8List' && + type.element2.library.name == 'dart.typed_data'; if (!typesystem.isAssignableTo(expectedDartType.type, type) && !isAllowedUint8List) { @@ -159,14 +159,14 @@ extension on TypeProvider { case ColumnType.integer: return intType; case ColumnType.bigInt: - return intElement.library.getType('BigInt')!.instantiate( + return intElement.library.getClass('BigInt')!.instantiate( typeArguments: const [], nullabilitySuffix: NullabilitySuffix.none); case ColumnType.text: return stringType; case ColumnType.boolean: return boolType; case ColumnType.datetime: - return intElement.library.getType('DateTime')!.instantiate( + return intElement.library.getClass('DateTime')!.instantiate( typeArguments: const [], nullabilitySuffix: NullabilitySuffix.none); case ColumnType.blob: return listType(intType); diff --git a/drift_dev/lib/src/analyzer/dart/column_parser.dart b/drift_dev/lib/src/analyzer/dart/column_parser.dart index 058f8415..b424a05b 100644 --- a/drift_dev/lib/src/analyzer/dart/column_parser.dart +++ b/drift_dev/lib/src/analyzer/dart/column_parser.dart @@ -345,7 +345,7 @@ class ColumnParser { if (foundExplicitName != null) { name = ColumnName.explicitly(foundExplicitName); } else { - name = ColumnName.implicitly(ReCase(getter.name.name).snakeCase); + name = ColumnName.implicitly(ReCase(getter.name2.lexeme).snakeCase); } final columnType = _startMethodToColumnType(foundStartMethod); @@ -424,7 +424,7 @@ class ColumnParser { getter.documentationComment?.tokens.map((t) => t.toString()).join('\n'); return MoorColumn( type: columnType, - dartGetterName: getter.name.name, + dartGetterName: getter.name2.lexeme, name: name, overriddenJsonName: _readJsonKey(element), customConstraints: foundCustomConstraint, @@ -456,9 +456,11 @@ class ColumnParser { final annotations = getter.metadata; final object = annotations.firstWhereOrNull((e) { final value = e.computeConstantValue(); - return value != null && - isFromMoor(value.type!) && - value.type!.element!.name == 'JsonKey'; + final valueType = value?.type; + + return valueType is InterfaceType && + isFromMoor(valueType) && + valueType.element2.name == 'JsonKey'; }); if (object == null) return null; diff --git a/drift_dev/lib/src/analyzer/dart/table_parser.dart b/drift_dev/lib/src/analyzer/dart/table_parser.dart index b21cf81d..10fcb60a 100644 --- a/drift_dev/lib/src/analyzer/dart/table_parser.dart +++ b/drift_dev/lib/src/analyzer/dart/table_parser.dart @@ -85,7 +85,7 @@ class TableParser { for (final annotation in element.metadata) { final computed = annotation.computeConstantValue(); - final annotationClass = computed!.type!.element!.name; + final annotationClass = computed!.type!.nameIfInterfaceType; if (annotationClass == 'DataClassName') { dataClassName = computed; @@ -124,8 +124,8 @@ class TableParser { useRowClass.getField('generateInsertable')!.toBoolValue()!; if (type is InterfaceType) { - existingClass = FoundDartClass(type.element, type.typeArguments); - name = type.element.name; + existingClass = FoundDartClass(type.element2, type.typeArguments); + name = type.element2.name; } else { base.step.reportError(ErrorInDartCode( message: 'The @UseRowClass annotation must be used with a class', @@ -309,7 +309,7 @@ class TableParser { Future> _parseColumns(ClassElement element) async { final columnNames = element.allSupertypes - .map((t) => t.element) + .map((t) => t.element2) .followedBy([element]) .expand((e) => e.fields) .where((field) => @@ -350,7 +350,7 @@ class _DataClassInformation { extension on Element { bool get isFromDefaultTable { - final parent = enclosingElement; + final parent = enclosingElement3; return parent is ClassElement && parent.name == 'Table' && diff --git a/drift_dev/lib/src/analyzer/dart/use_dao_parser.dart b/drift_dev/lib/src/analyzer/dart/use_dao_parser.dart index 483fee15..36457837 100644 --- a/drift_dev/lib/src/analyzer/dart/use_dao_parser.dart +++ b/drift_dev/lib/src/analyzer/dart/use_dao_parser.dart @@ -9,7 +9,7 @@ class UseDaoParser { /// declared by that class and the referenced tables. Future parseDao(ClassElement element, ConstantReader annotation) async { final dbType = element.allSupertypes - .firstWhereOrNull((i) => i.element.name == 'DatabaseAccessor'); + .firstWhereOrNull((i) => i.element2.name == 'DatabaseAccessor'); if (dbType == null) { step.reportError(ErrorInDartCode( diff --git a/drift_dev/lib/src/analyzer/dart/view_parser.dart b/drift_dev/lib/src/analyzer/dart/view_parser.dart index e8283ef2..3248d1e7 100644 --- a/drift_dev/lib/src/analyzer/dart/view_parser.dart +++ b/drift_dev/lib/src/analyzer/dart/view_parser.dart @@ -41,7 +41,7 @@ class ViewParser { for (final annotation in element.metadata) { final computed = annotation.computeConstantValue(); - final annotationClass = computed!.type!.element!.name; + final annotationClass = computed!.type!.nameIfInterfaceType; if (annotationClass == 'DriftView') { driftView = computed; @@ -80,8 +80,8 @@ class ViewParser { useRowClass.getField('generateInsertable')!.toBoolValue()!; if (type is InterfaceType) { - existingClass = FoundDartClass(type.element, type.typeArguments); - name = type.element.name; + existingClass = FoundDartClass(type.element2, type.typeArguments); + name = type.element2.name; } else { base.step.reportError(ErrorInDartCode( message: 'The @UseRowClass annotation must be used with a class', @@ -100,7 +100,7 @@ class ViewParser { Future _parseViewName(ClassElement element) async { for (final annotation in element.metadata) { final computed = annotation.computeConstantValue(); - final annotationClass = computed!.type!.element!.name; + final annotationClass = computed!.type!.nameIfInterfaceType; if (annotationClass == 'DriftView') { final name = computed.getField('name')?.toStringValue(); @@ -116,7 +116,7 @@ class ViewParser { Future> _parseColumns(ClassElement element) async { final columnNames = element.allSupertypes - .map((t) => t.element) + .map((t) => t.element2) .followedBy([element]) .expand((e) => e.fields) .where((field) => @@ -134,7 +134,7 @@ class ViewParser { final results = await Future.wait(fields.map((field) async { final dartType = (field.type as InterfaceType).typeArguments[0]; - final typeName = dartType.element!.name!; + final typeName = dartType.nameIfInterfaceType!; final sqlType = _dartTypeToColumnType(typeName); if (sqlType == null) { @@ -181,7 +181,7 @@ class ViewParser { Future> _parseStaticReferences( ClassElement element, List tables) async { return await Stream.fromIterable(element.allSupertypes - .map((t) => t.element) + .map((t) => t.element2) .followedBy([element]).expand((e) => e.fields)) .asyncMap((field) => _getStaticReference(field, tables)) .where((ref) => ref != null) @@ -198,7 +198,7 @@ class ViewParser { final type = tables.firstWhereOrNull( (tbl) => tbl.fromClass!.name == node.returnType.toString()); if (type != null) { - final name = node.name.toString(); + final name = node.name2.lexeme; return TableReferenceInDartView(type, name); } } diff --git a/drift_dev/lib/src/analyzer/data_class.dart b/drift_dev/lib/src/analyzer/data_class.dart index f04644e6..abe2c521 100644 --- a/drift_dev/lib/src/analyzer/data_class.dart +++ b/drift_dev/lib/src/analyzer/data_class.dart @@ -29,7 +29,7 @@ String? parseCustomParentClass(String dartTypeName, DartObject dataClassName, final extendingType = extending.toTypeValue(); if (extendingType is InterfaceType) { final superType = extendingType.allSupertypes - .any((type) => isFromMoor(type) && type.element.name == 'DataClass'); + .any((type) => isFromMoor(type) && type.element2.name == 'DataClass'); if (!superType) { base.step.reportError( ErrorInDartCode( @@ -52,10 +52,10 @@ String? parseCustomParentClass(String dartTypeName, DartObject dataClassName, return null; } - final className = extendingType.element.name; + final className = extendingType.nameIfInterfaceType; if (extendingType.typeArguments.length == 1) { - final genericType = extendingType.typeArguments[0].element?.name; - if (genericType == 'Object' || genericType == 'dynamic') { + final genericType = extendingType.typeArguments[0]; + if (genericType.isDartCoreObject || genericType.isDynamic) { return '$className<$dartTypeName>'; } else { base.step.reportError( diff --git a/drift_dev/lib/src/analyzer/moor/create_table_reader.dart b/drift_dev/lib/src/analyzer/moor/create_table_reader.dart index 8d0820fe..a467e85d 100644 --- a/drift_dev/lib/src/analyzer/moor/create_table_reader.dart +++ b/drift_dev/lib/src/analyzer/moor/create_table_reader.dart @@ -263,7 +263,7 @@ class CreateTableReader { } final asTypeConverter = type.allSupertypes.firstWhere( - (type) => isFromMoor(type) && type.element.name == 'TypeConverter'); + (type) => isFromMoor(type) && type.element2.name == 'TypeConverter'); // TypeConverter, where D is the type in Dart final typeInDart = asTypeConverter.typeArguments.first; @@ -273,7 +273,7 @@ class CreateTableReader { mappedType: DriftDartType.of(typeInDart), sqlType: sqlType, alsoAppliesToJsonConversion: - helper.isJsonAwareTypeConverter(type, type.element.library), + helper.isJsonAwareTypeConverter(type, type.element2.library), ); } diff --git a/drift_dev/lib/src/analyzer/moor/find_dart_class.dart b/drift_dev/lib/src/analyzer/moor/find_dart_class.dart index a3f388e6..22dc3045 100644 --- a/drift_dev/lib/src/analyzer/moor/find_dart_class.dart +++ b/drift_dev/lib/src/analyzer/moor/find_dart_class.dart @@ -28,7 +28,7 @@ Future findDartClass( } else if (foundElement is TypeAliasElement) { final innerType = foundElement.aliasedType; if (innerType is InterfaceType) { - return FoundDartClass(innerType.element, innerType.typeArguments); + return FoundDartClass(innerType.element2, innerType.typeArguments); } } } diff --git a/drift_dev/lib/src/analyzer/runner/steps/parse_dart.dart b/drift_dev/lib/src/analyzer/runner/steps/parse_dart.dart index 5e0365ee..795831f9 100644 --- a/drift_dev/lib/src/analyzer/runner/steps/parse_dart.dart +++ b/drift_dev/lib/src/analyzer/runner/steps/parse_dart.dart @@ -122,7 +122,7 @@ class ParseDartStep extends Step { Future> parseTables( Iterable types, Element initializedBy) { return Future.wait(types.map((type) { - if (!_tableTypeChecker.isAssignableFrom(type.element!)) { + if (!_tableTypeChecker.isAssignableFromType(type)) { reportError(ErrorInDartCode( severity: Severity.criticalError, message: 'The type $type is not a moor table', @@ -130,7 +130,7 @@ class ParseDartStep extends Step { )); return Future.value(null); } else { - return _parseTable(type.element as ClassElement); + return _parseTable((type as InterfaceType).element2 as ClassElement); } })).then((list) { // only keep tables that were resolved successfully @@ -145,7 +145,7 @@ class ParseDartStep extends Step { Future> parseViews( Iterable types, Element initializedBy, List tables) { return Future.wait(types.map((type) { - if (!_viewTypeChecker.isAssignableFrom(type.element!)) { + if (!_viewTypeChecker.isAssignableFromType(type)) { reportError(ErrorInDartCode( severity: Severity.criticalError, message: 'The type $type is not a drift view', @@ -153,7 +153,8 @@ class ParseDartStep extends Step { )); return Future.value(null); } else { - return _parseView(type.element as ClassElement, tables); + return _parseView( + (type as InterfaceType).element2 as ClassElement, tables); } })).then((list) { // only keep tables that were resolved successfully diff --git a/drift_dev/lib/src/cli/commands/migrate.dart b/drift_dev/lib/src/cli/commands/migrate.dart index 4152fa7f..4e94c739 100644 --- a/drift_dev/lib/src/cli/commands/migrate.dart +++ b/drift_dev/lib/src/cli/commands/migrate.dart @@ -413,7 +413,8 @@ class _Moor2DriftDartRewriter extends GeneralizingAstVisitor { if (type is! InterfaceType) continue; - if (type.element.library.isDartCore && type.element.name == 'pragma') { + if (type.element2.library.isDartCore && + type.element2.name == 'pragma') { final name = value.getField('name')!.toStringValue()!; if (name == 'moor2drift') { @@ -452,8 +453,8 @@ class _Moor2DriftDartRewriter extends GeneralizingAstVisitor { if (type is! InterfaceType || // note that even old moor code uses these names since UseMoor/UseDao // are type aliases to the new interfaces. - (type.element.name != 'DriftDatabase' && - type.element.name != 'DriftAccessor')) { + (type.element2.name != 'DriftDatabase' && + type.element2.name != 'DriftAccessor')) { return; } diff --git a/drift_dev/lib/src/model/base_entity.dart b/drift_dev/lib/src/model/base_entity.dart index fcdbc4da..3b3b3962 100644 --- a/drift_dev/lib/src/model/base_entity.dart +++ b/drift_dev/lib/src/model/base_entity.dart @@ -65,7 +65,7 @@ abstract class MoorEntityWithResultSet extends MoorSchemaEntity { /// Information used by the generator to generate code for a custom data class /// written by users. class ExistingRowClass { - final ClassElement targetClass; + final InterfaceElement targetClass; /// The Dart types that should be used to instantiate the [targetClass]. final List typeInstantiation; diff --git a/drift_dev/lib/src/model/used_type_converter.dart b/drift_dev/lib/src/model/used_type_converter.dart index 35f4e155..d63e0d42 100644 --- a/drift_dev/lib/src/model/used_type_converter.dart +++ b/drift_dev/lib/src/model/used_type_converter.dart @@ -3,7 +3,7 @@ import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:drift_dev/src/model/table.dart'; import 'package:drift_dev/src/utils/type_utils.dart'; -import 'package:drift_dev/src/writer/writer.dart'; +import 'package:drift_dev/writer.dart'; import 'column.dart'; import 'types.dart'; @@ -48,12 +48,12 @@ class UsedTypeConverter { mappedType.nullabilitySuffix == NullabilitySuffix.question; factory UsedTypeConverter.forEnumColumn(DartType enumType, bool nullable) { - if (enumType.element is! ClassElement) { + if (enumType is! InterfaceType) { throw InvalidTypeForEnumConverterException('Not a class', enumType); } - final creatingClass = enumType.element as ClassElement; - if (!creatingClass.isEnum) { + final creatingClass = enumType.element2; + if (creatingClass is! EnumElement) { throw InvalidTypeForEnumConverterException('Not an enum', enumType); } diff --git a/drift_dev/lib/src/utils/type_utils.dart b/drift_dev/lib/src/utils/type_utils.dart index e50bb2ad..c27d70e0 100644 --- a/drift_dev/lib/src/utils/type_utils.dart +++ b/drift_dev/lib/src/utils/type_utils.dart @@ -3,28 +3,35 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:drift_dev/src/writer/writer.dart'; bool isFromMoor(DartType type) { - final firstComponent = type.element?.library?.location?.components.first; + if (type is! InterfaceType) return false; + final firstComponent = type.element2.library.location?.components.first; if (firstComponent == null) return false; return firstComponent.contains('drift') || firstComponent.contains('moor'); } bool isColumn(DartType type) { - final name = type.element?.name ?? ''; + final name = type.nameIfInterfaceType; return isFromMoor(type) && + name != null && name.contains('Column') && !name.contains('Builder'); } bool isExpression(DartType type) { - final name = type.element?.name ?? ''; + final name = type.nameIfInterfaceType; - return isFromMoor(type) && name.startsWith('Expression'); + return name != null && isFromMoor(type) && name.startsWith('Expression'); } extension TypeUtils on DartType { + String? get nameIfInterfaceType { + final $this = this; + return $this is InterfaceType ? $this.element2.name : null; + } + String get userVisibleName => getDisplayString(withNullability: true); /// How this type should look like in generated code. diff --git a/drift_dev/pubspec.yaml b/drift_dev/pubspec.yaml index 5e08f7f2..0b25d390 100644 --- a/drift_dev/pubspec.yaml +++ b/drift_dev/pubspec.yaml @@ -30,7 +30,7 @@ dependencies: sqlparser: ^0.22.0 # Dart analysis - analyzer: "^4.1.0" + analyzer: "^4.4.0" analyzer_plugin: ^0.11.0 source_span: ^1.5.5 package_config: ^2.0.0 diff --git a/drift_dev/test/analyzer/dart/dart_test.dart b/drift_dev/test/analyzer/dart/dart_test.dart index 4c4b8177..affea4cb 100644 --- a/drift_dev/test/analyzer/dart/dart_test.dart +++ b/drift_dev/test/analyzer/dart/dart_test.dart @@ -44,7 +44,7 @@ void main() { expect(parser.returnExpressionOfMethod(node)!.toSource(), source); } - final testClass = library.getType('Test'); + final testClass = library.getClass('Test'); await _verifyReturnExpressionMatches( testClass!.getGetter('getter')!, "'foo'"); diff --git a/drift_dev/test/analyzer/dart/table_parser_test.dart b/drift_dev/test/analyzer/dart/table_parser_test.dart index e017e2f3..a6a7ad09 100644 --- a/drift_dev/test/analyzer/dart/table_parser_test.dart +++ b/drift_dev/test/analyzer/dart/table_parser_test.dart @@ -147,7 +147,7 @@ void main() { }); Future parse(String name) async { - return parser.parseTable(dartStep.library.getType(name)!); + return parser.parseTable(dartStep.library.getClass(name)!); } group('table names', () { diff --git a/drift_dev/test/analyzer/integration/dao_inheritance_test.dart b/drift_dev/test/analyzer/integration/dao_inheritance_test.dart index 80c21801..429d38c6 100644 --- a/drift_dev/test/analyzer/integration/dao_inheritance_test.dart +++ b/drift_dev/test/analyzer/integration/dao_inheritance_test.dart @@ -1,5 +1,6 @@ @Tags(['analyzer']) import 'package:drift_dev/src/analyzer/runner/results.dart'; +import 'package:drift_dev/src/utils/type_utils.dart'; import 'package:test/test.dart'; import '../utils.dart'; @@ -48,7 +49,7 @@ class ProductsDao extends BaseProductsDao with _$ProductDaoMixin { expect(file.errors.errors, isEmpty); final dao = (file.currentResult as ParsedDartFile).declaredDaos.single; - expect(dao.dbClass.element!.name, 'MyDatabase'); + expect(dao.dbClass.nameIfInterfaceType, 'MyDatabase'); state.close(); }); diff --git a/drift_dev/test/writer/mutable_classes_integration_test.dart b/drift_dev/test/writer/mutable_classes_integration_test.dart index cacb18ae..53145bde 100644 --- a/drift_dev/test/writer/mutable_classes_integration_test.dart +++ b/drift_dev/test/writer/mutable_classes_integration_test.dart @@ -88,25 +88,26 @@ class _GeneratesWithoutFinalFields extends Matcher { final definedClasses = parsed.declarations.whereType(); for (final definedClass in definedClasses) { - if (expectedWithoutFinals.contains(definedClass.name.name)) { + final definedClassName = definedClass.name2.lexeme; + if (expectedWithoutFinals.contains(definedClassName)) { for (final member in definedClass.members) { if (member is FieldDeclaration) { if (member.fields.isFinal) { matchState['desc'] = - 'Field ${member.fields.variables.first.name.name} in ' - '${definedClass.name.name} is final.'; + 'Field ${member.fields.variables.first.name2.lexeme} in ' + '$definedClassName is final.'; return false; } } else if (member is ConstructorDeclaration) { if (member.constKeyword != null) { - matchState['desc'] = 'Constructor ${member.name?.name ?? ''} in ' - '${definedClass.name.name} is constant.'; + matchState['desc'] = 'Constructor ${member.name2?.lexeme ?? ''} ' + 'in $definedClassName is constant.'; return false; } } } - remaining.remove(definedClass.name.name); + remaining.remove(definedClassName); } } diff --git a/extras/integration_tests/tests/pubspec.yaml b/extras/integration_tests/tests/pubspec.yaml index f141d3a9..550b6d83 100644 --- a/extras/integration_tests/tests/pubspec.yaml +++ b/extras/integration_tests/tests/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: dev_dependencies: build_runner: ^2.0.0 drift_dev: ^1.0.2 - json_serializable: ^5.0.0 + json_serializable: ^6.0.0 test: dependency_overrides: