Load imports for Dart files too (#2433)

This commit is contained in:
Simon Binder 2023-05-23 15:58:15 +02:00
parent 2354cb43cf
commit 451bc9c930
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
8 changed files with 91 additions and 8 deletions

View File

@ -1846,9 +1846,9 @@ class AllTodosWithCategoryResult extends CustomResultSet {
mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> {
$UsersTable get users => attachedDatabase.users;
$SharedTodosTable get sharedTodos => attachedDatabase.sharedTodos;
$CategoriesTable get categories => attachedDatabase.categories;
$TodosTableTable get todosTable => attachedDatabase.todosTable;
$SharedTodosTable get sharedTodos => attachedDatabase.sharedTodos;
$TodoWithCategoryViewView get todoWithCategoryView =>
attachedDatabase.todoWithCategoryView;
Selectable<TodoEntry> todosForUser({required int user}) {

View File

@ -1,3 +1,8 @@
## 2.8.3-dev
- Allow Dart-defined tables to reference imported tables through SQL
[#2433](https://github.com/simolus3/drift/issues/2433).
## 2.8.2
- Fix generated to write qualified column references for Dart components in

View File

@ -63,8 +63,12 @@ class DriftAnalysisCache {
yield found;
for (final imported in found.imports ?? const <Uri>[]) {
if (seenUris.add(imported)) {
pending.add(knownFiles[imported]!);
// We might not have a known file for all imports of a Dart file, since
// not all imports are drift-related there.
final knownImport = knownFiles[imported];
if (seenUris.add(imported) && knownImport != null) {
pending.add(knownImport);
}
}
}

View File

@ -184,6 +184,10 @@ class DriftAnalysisDriver {
);
}
}
} else if (state is DiscoveredDartLibrary) {
for (final import in state.importDependencies) {
await prepareFileForAnalysis(import);
}
}
}

View File

@ -129,10 +129,17 @@ class DriftFileImport {
class DiscoveredDartLibrary extends DiscoveredFileState {
final LibraryElement library;
@override
final List<Uri> importDependencies;
@override
bool get isValidImport => true;
DiscoveredDartLibrary(this.library, super.locallyDefinedElements);
DiscoveredDartLibrary(
this.library,
super.locallyDefinedElements,
this.importDependencies,
);
}
class NotADartLibrary extends DiscoveredFileState {

View File

@ -46,6 +46,9 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
}
}
final tableConstraints =
await _readCustomConstraints(references, columns, element);
final table = DriftTable(
discovered.ownId,
DriftDeclaration.dartElement(element),
@ -60,7 +63,7 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
for (final uniqueKey in uniqueKeys ?? const <Set<DriftColumn>>[])
UniqueColumns(uniqueKey),
],
overrideTableConstraints: await _readCustomConstraints(columns, element),
overrideTableConstraints: tableConstraints,
withoutRowId: await _overrideWithoutRowId(element) ?? false,
);
@ -272,7 +275,7 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
return ColumnParser(this).parse(declaration, element);
}
Future<List<String>> _readCustomConstraints(
Future<List<String>> _readCustomConstraints(Set<DriftElement> references,
List<DriftColumn> localColumns, ClassElement element) async {
final customConstraints =
element.lookUpGetter('customConstraints', element.library);
@ -343,6 +346,7 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
(msg) => DriftAnalysisError.inDartAst(element, source, msg));
if (table != null) {
references.add(table);
final missingColumns = clause.columnNames
.map((e) => e.columnName)
.where((e) => !table.columnBySqlName.containsKey(e));

View File

@ -77,8 +77,11 @@ class DiscoverStep {
await finder.find();
_file.errorsDuringDiscovery.addAll(finder.errors);
_file.discovery =
DiscoveredDartLibrary(library, _checkForDuplicates(finder.found));
_file.discovery = DiscoveredDartLibrary(
library,
_checkForDuplicates(finder.found),
finder.imports,
);
break;
case '.drift':
case '.moor':
@ -153,6 +156,8 @@ class _FindDartElements extends RecursiveElementVisitor<void> {
final DiscoverStep _discoverStep;
final LibraryElement _library;
final List<Uri> imports = [];
final TypeChecker _isTable, _isView, _isTableInfo, _isDatabase, _isDao;
final List<Future<void>> _pendingWork = [];
@ -231,6 +236,18 @@ class _FindDartElements extends RecursiveElementVisitor<void> {
super.visitClassElement(element);
}
@override
void visitLibraryImportElement(LibraryImportElement element) {
final imported = element.importedLibrary;
if (imported != null && !imported.isInSdk) {
_pendingWork.add(Future(() async {
final uri = await _discoverStep._driver.backend.uriOfDart(imported);
imports.add(uri);
}));
}
}
String _defaultNameForTableOrView(ClassElement definingElement) {
return _discoverStep._driver.options.caseFromDartToSql
.apply(definingElement.name);

View File

@ -364,6 +364,48 @@ class WithConstraints extends Table {
]);
});
test('can resolve references from import', () async {
final backend = TestBackend.inTest({
'a|lib/topic.dart': '''
import 'package:drift/drift.dart';
import 'language.dart';
class Topics extends Table {
IntColumn get id => integer()();
TextColumn get langCode => text()();
}
''',
'a|lib/video.dart': '''
import 'package:drift/drift.dart';
import 'topic.dart';
class Videos extends Table {
IntColumn get id => integer()();
IntColumn get topicId => integer()();
TextColumn get topicLang => text()();
@override
List<String> get customConstraints => [
'FOREIGN KEY (topic_id, topic_lang) REFERENCES topics (id, lang_code)',
];
}
''',
});
final state = await backend.analyze('package:a/video.dart');
backend.expectNoErrors();
final table = state.analyzedElements.single as DriftTable;
expect(
table.references,
contains(isA<DriftTable>()
.having((e) => e.schemaName, 'schemaName', 'topics')));
});
test('supports autoIncrement on int64 columns', () async {
final backend = TestBackend.inTest({
'a|lib/a.dart': '''