From 59d347adbe9db890a42965ddd0a3ea2d26b49449 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Tue, 22 Nov 2022 20:05:41 +0100 Subject: [PATCH] Fix spellfix1 module with new analyzer --- drift_dev/lib/src/analysis/driver/driver.dart | 13 +++++++++- .../src/analysis/resolver/drift/table.dart | 14 ++++------- drift_dev/test/analysis/options_test.dart | 15 ++++++++++++ .../resolver/drift/virtual_table_test.dart | 24 +++++++++++++++++++ 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/drift_dev/lib/src/analysis/driver/driver.dart b/drift_dev/lib/src/analysis/driver/driver.dart index 6d3efbd7..0d46c967 100644 --- a/drift_dev/lib/src/analysis/driver/driver.dart +++ b/drift_dev/lib/src/analysis/driver/driver.dart @@ -75,6 +75,8 @@ class DriftAnalysisDriver { const DriftNativeExtension(), if (options.hasModule(SqlModule.math)) const BuiltInMathExtension(), if (options.hasModule(SqlModule.rtree)) const RTreeExtension(), + if (options.hasModule(SqlModule.spellfix1)) + const Spellfix1Extension(), ], version: options.sqliteVersion, ), @@ -175,7 +177,9 @@ class DriftAnalysisDriver { try { await resolver.resolveDiscovered(discovered); } catch (e, s) { - backend.log.warning('Could not analyze ${discovered.ownId}', e, s); + if (e is! CouldNotResolveElementException) { + backend.log.warning('Could not analyze ${discovered.ownId}', e, s); + } } } } @@ -227,3 +231,10 @@ class DriftAnalysisDriver { abstract class AnalysisResultCacheReader { Future readCacheFor(Uri uri); } + +/// Thrown by a local element resolver when an element could not be resolved and +/// a more helpful error has already been added as an analysis error for the +/// user to see. +class CouldNotResolveElementException implements Exception { + const CouldNotResolveElementException(); +} diff --git a/drift_dev/lib/src/analysis/resolver/drift/table.dart b/drift_dev/lib/src/analysis/resolver/drift/table.dart index 2a76c0c1..f845d318 100644 --- a/drift_dev/lib/src/analysis/resolver/drift/table.dart +++ b/drift_dev/lib/src/analysis/resolver/drift/table.dart @@ -1,6 +1,7 @@ import 'package:analyzer/dart/ast/ast.dart' as dart; import 'package:collection/collection.dart'; import 'package:drift/drift.dart' show DriftSqlType; +import 'package:drift_dev/src/analysis/driver/driver.dart'; import 'package:recase/recase.dart'; import 'package:sqlparser/sqlparser.dart' hide PrimaryKeyColumn, UniqueColumn; import 'package:sqlparser/sqlparser.dart' as sql; @@ -35,15 +36,10 @@ class DriftTableResolver extends LocalElementResolver { resolver.driver.options.storeDateTimeValuesAsText, ); table = reader.read(stmt); - } catch (e, s) { - resolver.driver.backend.log - .warning('Error reading table from internal statement', e, s); - reportError(DriftAnalysisError.inDriftFile( - stmt.tableNameToken ?? stmt, - 'The structure of this table could not be extracted, possibly due to a ' - 'bug in drift_dev.', - )); - rethrow; + } on CantReadSchemaException catch (e) { + reportError(DriftAnalysisError.inDriftFile(stmt.tableNameToken ?? stmt, + 'Drift was unable to analyze this table: ${e.message}')); + throw const CouldNotResolveElementException(); } final columns = []; diff --git a/drift_dev/test/analysis/options_test.dart b/drift_dev/test/analysis/options_test.dart index a804002a..edbcbbc2 100644 --- a/drift_dev/test/analysis/options_test.dart +++ b/drift_dev/test/analysis/options_test.dart @@ -3,6 +3,8 @@ import 'package:drift_dev/src/analysis/options.dart'; import 'package:sqlparser/sqlparser.dart'; import 'package:test/test.dart'; +import 'test_utils.dart'; + void main() { DriftOptions parse(String yaml) { return checkedYamlDecode(yaml, (m) => DriftOptions.fromJson(m!)); @@ -71,4 +73,17 @@ sqlite: ), ); }); + + test('reports error about table when module is not imported', () async { + final backend = TestBackend.inTest({ + 'a|lib/a.drift': 'CREATE VIRTUAL TABLE place_spellfix USING spellfix1;', + }); + + final file = await backend.analyze('package:a/a.drift'); + expect(file.analyzedElements, isEmpty); + expect(file.allErrors, [ + isDriftError(contains('Unknown module "spellfix1", did you register it?')) + .withSpan('place_spellfix'), + ]); + }); } diff --git a/drift_dev/test/analysis/resolver/drift/virtual_table_test.dart b/drift_dev/test/analysis/resolver/drift/virtual_table_test.dart index 00883ec8..2fbabea8 100644 --- a/drift_dev/test/analysis/resolver/drift/virtual_table_test.dart +++ b/drift_dev/test/analysis/resolver/drift/virtual_table_test.dart @@ -1,4 +1,6 @@ +import 'package:drift/drift.dart'; import 'package:drift_dev/src/analysis/options.dart'; +import 'package:drift_dev/src/analysis/results/table.dart'; import 'package:test/test.dart'; import '../../test_utils.dart'; @@ -68,4 +70,26 @@ SELECT rowid, highlight(example_table_search, 0, '[match]', '[match]') name, expect(result.allErrors, [isDriftError(contains('Function simple_query could not be found'))]); }); + + test('supports spellfix1 tables', () async { + final state = TestBackend.inTest( + {'a|lib/a.drift': 'CREATE VIRTUAL TABLE demo USING spellfix1;'}, + options: DriftOptions.defaults( + dialect: DialectOptions( + SqlDialect.sqlite, + SqliteAnalysisOptions( + modules: [SqlModule.spellfix1], + ), + ), + ), + ); + final file = await state.analyze('package:a/a.drift'); + state.expectNoErrors(); + + final table = file.analyzedElements.single as DriftTable; + expect( + table.columns.map((e) => e.nameInSql), + containsAll(['word', 'rank', 'distance', 'langid', 'score', 'matchlen']), + ); + }); }