diff --git a/moor_generator/lib/src/analyzer/moor/entity_handler.dart b/moor_generator/lib/src/analyzer/moor/entity_handler.dart index 512c4c98..43d7fd5f 100644 --- a/moor_generator/lib/src/analyzer/moor/entity_handler.dart +++ b/moor_generator/lib/src/analyzer/moor/entity_handler.dart @@ -2,9 +2,7 @@ import 'package:moor_generator/moor_generator.dart'; import 'package:moor_generator/src/analyzer/errors.dart'; import 'package:moor_generator/src/analyzer/runner/results.dart'; import 'package:moor_generator/src/analyzer/runner/steps.dart'; -import 'package:moor_generator/src/analyzer/sql_queries/lints/linter.dart'; import 'package:moor_generator/src/analyzer/sql_queries/query_analyzer.dart'; -import 'package:moor_generator/src/model/view.dart'; import 'package:sqlparser/sqlparser.dart'; import 'package:sqlparser/utils/find_referenced_tables.dart'; @@ -20,15 +18,16 @@ class EntityHandler extends BaseAnalyzer { AnalyzeMoorStep step, this.file, List availableTables, - List availableViews, - ) : super(availableTables, availableViews, step) { + ) : + // we'll analyze views later, so pass an empty list for now. Otherwise + // the incomplete views would be added to the engine. + super(availableTables, const [], step) { _referenceResolver = _ReferenceResolvingVisitor(this); } final Map _triggers = {}; final Map _tables = {}; final Map _indexes = {}; - final Map _views = {}; _ReferenceResolvingVisitor _referenceResolver; @@ -61,23 +60,13 @@ class EntityHandler extends BaseAnalyzer { _lint(node, 'special @create table'); entity.references.addAll(_findTables(node.statement)); - } else if (entity is MoorView) { - final node = - _handleMoorDeclaration(entity, _views) as CreateViewStatement; - _lint(node, node.viewName); - entity.references.addAll(_findTables(node.query)); - entity.references.addAll(_findViews(node.query)); } } } void _lint(AstNode node, String displayName) { final context = engine.analyzeNode(node, file.parseResult.sql); - context.errors.forEach(report); - - final linter = Linter(context, mapper); - linter.reportLints(); - reportLints(linter.lints, name: displayName); + lintContext(context, displayName); } Iterable _findTables(AstNode node) { @@ -86,12 +75,6 @@ class EntityHandler extends BaseAnalyzer { return tablesFinder.foundTables.map(mapper.tableToMoor); } - Iterable _findViews(AstNode node) { - final tablesFinder = ReferencedTablesVisitor(); - node.acceptWithoutArg(tablesFinder); - return tablesFinder.foundViews.map(mapper.viewToMoor); - } - Iterable _findUpdatedTables(AstNode node) { final finder = UpdatedTablesVisitor(); node.acceptWithoutArg(finder); diff --git a/moor_generator/lib/src/analyzer/runner/steps/analyze_moor.dart b/moor_generator/lib/src/analyzer/runner/steps/analyze_moor.dart index 44eb469a..1463be28 100644 --- a/moor_generator/lib/src/analyzer/runner/steps/analyze_moor.dart +++ b/moor_generator/lib/src/analyzer/runner/steps/analyze_moor.dart @@ -22,7 +22,7 @@ class AnalyzeMoorStep extends AnalyzingStep { .followedBy(parseResult.declaredViews) .toList(); - EntityHandler(this, parseResult, availableTables, availableViews).handle(); + EntityHandler(this, parseResult, availableTables).handle(); ViewAnalyzer(this, availableTables, availableViews).resolve(); diff --git a/moor_generator/lib/src/analyzer/sql_queries/query_analyzer.dart b/moor_generator/lib/src/analyzer/sql_queries/query_analyzer.dart index b7fe2ca8..c0df20d2 100644 --- a/moor_generator/lib/src/analyzer/sql_queries/query_analyzer.dart +++ b/moor_generator/lib/src/analyzer/sql_queries/query_analyzer.dart @@ -4,6 +4,7 @@ import 'package:moor_generator/moor_generator.dart'; import 'package:moor_generator/src/analyzer/errors.dart'; import 'package:moor_generator/src/analyzer/runner/file_graph.dart'; import 'package:moor_generator/src/analyzer/runner/steps.dart'; +import 'package:moor_generator/src/analyzer/sql_queries/lints/linter.dart'; import 'package:moor_generator/src/model/sql_query.dart'; import 'package:moor_generator/src/analyzer/sql_queries/query_handler.dart'; import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart'; @@ -35,6 +36,16 @@ abstract class BaseAnalyzer { return _engine; } + @protected + void lintContext(AnalysisContext context, String displayName) { + context.errors.forEach(report); + + // Additional, moor-specific analysis + final linter = Linter(context, mapper); + linter.reportLints(); + reportLints(linter.lints, name: displayName); + } + @protected void report(AnalysisError error, {String Function() msg, Severity severity}) { if (step.file.type == FileType.moor) { diff --git a/moor_generator/lib/src/analyzer/view/view_analyzer.dart b/moor_generator/lib/src/analyzer/view/view_analyzer.dart index e31f5a62..399815c7 100644 --- a/moor_generator/lib/src/analyzer/view/view_analyzer.dart +++ b/moor_generator/lib/src/analyzer/view/view_analyzer.dart @@ -5,8 +5,12 @@ import 'package:moor_generator/src/model/view.dart'; import 'package:sqlparser/sqlparser.dart'; class ViewAnalyzer extends BaseAnalyzer { - ViewAnalyzer(Step step, List tables, List views) - : super(tables, views, step); + final List viewsToAnalyze; + + ViewAnalyzer(Step step, List tables, this.viewsToAnalyze) + : // We're about to analyze views and add them to the engine, but don't + // add the unfinished views right away + super(tables, const [], step); List _viewsOrder; Set _resolvedViews; @@ -16,7 +20,7 @@ class ViewAnalyzer extends BaseAnalyzer { _viewsOrder = []; _resolvedViews = {}; // Topologically sorting all the views. - for (final view in views) { + for (final view in viewsToAnalyze) { if (!_resolvedViews.contains(view)) { _topologicalSort(view); } @@ -32,6 +36,8 @@ class ViewAnalyzer extends BaseAnalyzer { } final ctx = engine.analyzeNode(view.declaration.node, view.file.parseResult.sql); + lintContext(ctx, view.name); + view.parserView = const SchemaFromCreateTable(moorExtensions: true) .readView(ctx, view.declaration.creatingStatement); engine.registerView(mapper.extractView(view)); diff --git a/moor_generator/test/analyzer/moor/create_view_test.dart b/moor_generator/test/analyzer/moor/create_view_test.dart index fcb5026d..7802bd62 100644 --- a/moor_generator/test/analyzer/moor/create_view_test.dart +++ b/moor_generator/test/analyzer/moor/create_view_test.dart @@ -57,8 +57,6 @@ void main() { state.close(); - // Currently failing: - // is it a problem with sqlparser? expect(file.errors.errors, isEmpty); expect(column.type.type, BasicType.text); }); @@ -83,4 +81,27 @@ void main() { contains('Could not find t.'), ))); }); + + test('does not allow nested columns', () async { + final state = TestState.withContent({ + 'foo|lib/a.moor': ''' + CREATE TABLE foo (bar INTEGER NOT NULL PRIMARY KEY); + + CREATE VIEW v AS SELECT foo.** FROM foo; + ''', + }); + + final file = await state.analyze('package:foo/a.moor'); + + state.close(); + + expect( + file.errors.errors, + contains(isA().having( + (e) => e.message, + 'message', + contains('Nested star columns may only appear in a top-level select ' + 'query.'), + ))); + }); }