Add argument to sql visitor class

This commit is contained in:
Simon Binder 2019-12-26 12:35:29 +01:00
parent 72934d1b87
commit 7abda32ac4
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
44 changed files with 613 additions and 406 deletions

View File

@ -19,17 +19,18 @@ class TableHandler {
table.references.clear(); table.references.clear();
} }
file.parseResult.rootNode?.accept(_ReferenceResolvingVisitor(this)); file.parseResult.rootNode
?.acceptWithoutArg(_ReferenceResolvingVisitor(this));
} }
} }
class _ReferenceResolvingVisitor extends RecursiveVisitor<void> { class _ReferenceResolvingVisitor extends RecursiveVisitor<void, void> {
final TableHandler handler; final TableHandler handler;
_ReferenceResolvingVisitor(this.handler); _ReferenceResolvingVisitor(this.handler);
@override @override
void visitForeignKeyClause(ForeignKeyClause clause) { void visitForeignKeyClause(ForeignKeyClause clause, void arg) {
final stmt = clause.parents.whereType<CreateTableStatement>().first; final stmt = clause.parents.whereType<CreateTableStatement>().first;
final referencedTable = handler.availableTables.singleWhere( final referencedTable = handler.availableTables.singleWhere(
(t) => t.sqlName == clause.foreignTable.tableName, (t) => t.sqlName == clause.foreignTable.tableName,
@ -47,6 +48,6 @@ class _ReferenceResolvingVisitor extends RecursiveVisitor<void> {
createdTable?.references?.add(referencedTable); createdTable?.references?.add(referencedTable);
} }
super.visitForeignKeyClause(clause); super.visitForeignKeyClause(clause, arg);
} }
} }

View File

@ -2,22 +2,22 @@ import 'package:sqlparser/sqlparser.dart';
/// An AST-visitor that walks sql statements and finds all tables referenced in /// An AST-visitor that walks sql statements and finds all tables referenced in
/// them. /// them.
class ReferencedTablesVisitor extends RecursiveVisitor<void> { class ReferencedTablesVisitor extends RecursiveVisitor<void, void> {
/// All tables that have been referenced anywhere in this query. /// All tables that have been referenced anywhere in this query.
final Set<Table> foundTables = {}; final Set<Table> foundTables = {};
@override @override
void visitReference(Reference e) { void visitReference(Reference e, void arg) {
final column = e.resolved; final column = e.resolved;
if (column is TableColumn) { if (column is TableColumn) {
foundTables.add(column.table); foundTables.add(column.table);
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitQueryable(Queryable e) { void visitQueryable(Queryable e, void arg) {
if (e is TableReference) { if (e is TableReference) {
final resolved = e.resolved; final resolved = e.resolved;
if (resolved != null && resolved is Table) { if (resolved != null && resolved is Table) {
@ -25,7 +25,7 @@ class ReferencedTablesVisitor extends RecursiveVisitor<void> {
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
} }
@ -48,20 +48,20 @@ class UpdatedTablesVisitor extends ReferencedTablesVisitor {
} }
@override @override
void visitDeleteStatement(DeleteStatement e) { void visitDeleteStatement(DeleteStatement e, void arg) {
_addIfResolved(e.from); _addIfResolved(e.from);
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitUpdateStatement(UpdateStatement e) { void visitUpdateStatement(UpdateStatement e, void arg) {
_addIfResolved(e.table); _addIfResolved(e.table);
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitInsertStatement(InsertStatement e) { void visitInsertStatement(InsertStatement e, void arg) {
_addIfResolved(e.table); _addIfResolved(e.table);
visitChildren(e); visitChildren(e, arg);
} }
} }

View File

@ -11,18 +11,18 @@ class Linter {
Linter(this.handler); Linter(this.handler);
void reportLints() { void reportLints() {
handler.context.root.accept(_LintingVisitor(this)); handler.context.root.acceptWithoutArg(_LintingVisitor(this));
} }
} }
class _LintingVisitor extends RecursiveVisitor<void> { class _LintingVisitor extends RecursiveVisitor<void, void> {
final Linter linter; final Linter linter;
_LintingVisitor(this.linter); _LintingVisitor(this.linter);
@override @override
void visitResultColumn(ResultColumn e) { void visitResultColumn(ResultColumn e, void arg) {
super.visitResultColumn(e); super.visitResultColumn(e, arg);
if (e is ExpressionResultColumn) { if (e is ExpressionResultColumn) {
// The generated code will be invalid if knowing the expression is needed // The generated code will be invalid if knowing the expression is needed
@ -54,7 +54,7 @@ class _LintingVisitor extends RecursiveVisitor<void> {
} }
@override @override
void visitInsertStatement(InsertStatement e) { void visitInsertStatement(InsertStatement e, void arg) {
final targeted = e.resolvedTargetColumns; final targeted = e.resolvedTargetColumns;
if (targeted == null) return; if (targeted == null) return;

View File

@ -53,7 +53,7 @@ class QueryHandler {
UpdatingQuery _handleUpdate() { UpdatingQuery _handleUpdate() {
final updatedFinder = UpdatedTablesVisitor(); final updatedFinder = UpdatedTablesVisitor();
context.root.accept(updatedFinder); context.root.acceptWithoutArg(updatedFinder);
_foundTables = updatedFinder.writtenTables; _foundTables = updatedFinder.writtenTables;
final isInsert = context.root is InsertStatement; final isInsert = context.root is InsertStatement;
@ -70,7 +70,7 @@ class QueryHandler {
SqlSelectQuery _handleSelect() { SqlSelectQuery _handleSelect() {
final tableFinder = ReferencedTablesVisitor(); final tableFinder = ReferencedTablesVisitor();
_select.accept(tableFinder); _select.acceptWithoutArg(tableFinder);
_foundTables = tableFinder.foundTables; _foundTables = tableFinder.foundTables;
final moorTables = final moorTables =
_foundTables.map(mapper.tableToMoor).where((s) => s != null).toList(); _foundTables.map(mapper.tableToMoor).where((s) => s != null).toList();

View File

@ -13,18 +13,18 @@ class MoorFoldingContributor implements FoldingContributor {
if (moorRequest.isMoorAndParsed) { if (moorRequest.isMoorAndParsed) {
final result = moorRequest.parsedMoor; final result = moorRequest.parsedMoor;
final visitor = _FoldingVisitor(collector); final visitor = _FoldingVisitor(collector);
result.parsedFile.accept(visitor); result.parsedFile.acceptWithoutArg(visitor);
} }
} }
} }
class _FoldingVisitor extends RecursiveVisitor<void> { class _FoldingVisitor extends RecursiveVisitor<void, void> {
final FoldingCollector collector; final FoldingCollector collector;
_FoldingVisitor(this.collector); _FoldingVisitor(this.collector);
@override @override
void visitMoorFile(MoorFile e) { void visitMoorFile(MoorFile e, void arg) {
// construct a folding region for import statements // construct a folding region for import statements
final imports = e.imports.toList(); final imports = e.imports.toList();
if (imports.length > 1) { if (imports.length > 1) {
@ -34,11 +34,11 @@ class _FoldingVisitor extends RecursiveVisitor<void> {
collector.addRegion(first, last - first, FoldingKind.DIRECTIVES); collector.addRegion(first, last - first, FoldingKind.DIRECTIVES);
} }
super.visitChildren(e); super.visitChildren(e, arg);
} }
@override @override
void visitCreateTableStatement(CreateTableStatement e) { void visitCreateTableStatement(CreateTableStatement e, void arg) {
final startBody = e.openingBracket; final startBody = e.openingBracket;
final endBody = e.closingBracket; final endBody = e.closingBracket;

View File

@ -18,7 +18,7 @@ class MoorHighlightContributor implements HighlightsContributor {
final result = typedRequest.parsedMoor; final result = typedRequest.parsedMoor;
final visitor = _HighlightingVisitor(collector); final visitor = _HighlightingVisitor(collector);
result.parsedFile.accept(visitor); result.parsedFile.acceptWithoutArg(visitor);
for (final token in result.parseResult.tokens) { for (final token in result.parseResult.tokens) {
final start = token.span.start.offset; final start = token.span.start.offset;
@ -43,7 +43,7 @@ class MoorHighlightContributor implements HighlightsContributor {
} }
} }
class _HighlightingVisitor extends RecursiveVisitor<void> { class _HighlightingVisitor extends RecursiveVisitor<void, void> {
final HighlightsCollector collector; final HighlightsCollector collector;
_HighlightingVisitor(this.collector); _HighlightingVisitor(this.collector);
@ -55,41 +55,32 @@ class _HighlightingVisitor extends RecursiveVisitor<void> {
} }
@override @override
void visitReference(Reference e) { void visitReference(Reference e, void arg) {
_contribute(e, HighlightRegionType.INSTANCE_GETTER_REFERENCE); _contribute(e, HighlightRegionType.INSTANCE_GETTER_REFERENCE);
} }
@override @override
void visitQueryable(Queryable e) { void visitQueryable(Queryable e, void arg) {
if (e is TableReference) { if (e is TableReference) {
final tableToken = e.tableNameToken; final tableToken = e.tableNameToken;
if (tableToken != null) { if (tableToken != null) {
_contribute(e, HighlightRegionType.TYPE_PARAMETER); _contribute(e, HighlightRegionType.TYPE_PARAMETER);
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitCreateTableStatement(CreateTableStatement e) { void visitTableInducingStatement(TableInducingStatement e, void arg) {
_visitTableInducingStatement(e);
}
@override
void visitCreateVirtualTableStatement(CreateVirtualTableStatement e) {
_visitTableInducingStatement(e);
}
void _visitTableInducingStatement(TableInducingStatement e) {
if (e.tableNameToken != null) { if (e.tableNameToken != null) {
_contribute(e.tableNameToken, HighlightRegionType.CLASS); _contribute(e.tableNameToken, HighlightRegionType.CLASS);
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitColumnDefinition(ColumnDefinition e) { void visitColumnDefinition(ColumnDefinition e, void arg) {
final nameToken = e.nameToken; final nameToken = e.nameToken;
if (nameToken != null) { if (nameToken != null) {
_contribute(nameToken, HighlightRegionType.INSTANCE_FIELD_DECLARATION); _contribute(nameToken, HighlightRegionType.INSTANCE_FIELD_DECLARATION);
@ -103,17 +94,17 @@ class _HighlightingVisitor extends RecursiveVisitor<void> {
collector.addRegion(first, length, HighlightRegionType.TYPE_PARAMETER); collector.addRegion(first, length, HighlightRegionType.TYPE_PARAMETER);
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitSetComponent(SetComponent e) { void visitSetComponent(SetComponent e, void arg) {
_contribute(e.column, HighlightRegionType.INSTANCE_SETTER_REFERENCE); _contribute(e.column, HighlightRegionType.INSTANCE_SETTER_REFERENCE);
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitMoorDeclaredStatement(DeclaredStatement e) { void visitMoorDeclaredStatement(DeclaredStatement e, void arg) {
final identifier = e.identifier; final identifier = e.identifier;
if (identifier is SimpleName && identifier.identifier != null) { if (identifier is SimpleName && identifier.identifier != null) {
_contribute(identifier.identifier, _contribute(identifier.identifier,
@ -123,11 +114,11 @@ class _HighlightingVisitor extends RecursiveVisitor<void> {
_contribute(identifier.nameToken, HighlightRegionType.ANNOTATION); _contribute(identifier.nameToken, HighlightRegionType.ANNOTATION);
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitLiteral(Literal e) { void visitLiteral(Literal e, void arg) {
if (e is NullLiteral) { if (e is NullLiteral) {
_contribute(e, HighlightRegionType.BUILT_IN); _contribute(e, HighlightRegionType.BUILT_IN);
} else if (e is NumericLiteral) { } else if (e is NumericLiteral) {

View File

@ -17,12 +17,12 @@ class MoorNavigationContributor implements NavigationContributor {
final visitor = _NavigationVisitor(moorRequest, collector); final visitor = _NavigationVisitor(moorRequest, collector);
if (moorRequest.file.isParsed) { if (moorRequest.file.isParsed) {
moorRequest.parsedMoor.parsedFile.accept(visitor); moorRequest.parsedMoor.parsedFile.acceptWithoutArg(visitor);
} }
} }
} }
class _NavigationVisitor extends RecursiveVisitor<void> { class _NavigationVisitor extends RecursiveVisitor<void, void> {
final MoorRequestAtPosition request; final MoorRequestAtPosition request;
final NavigationCollector collector; final NavigationCollector collector;
@ -41,7 +41,7 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
} }
@override @override
void visitMoorImportStatement(ImportStatement e) { void visitMoorImportStatement(ImportStatement e, void arg) {
if (request.isMoorAndParsed) { if (request.isMoorAndParsed) {
final moor = request.parsedMoor; final moor = request.parsedMoor;
final resolved = moor.resolvedImports[e]; final resolved = moor.resolvedImports[e];
@ -53,11 +53,11 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitReference(Reference e) { void visitReference(Reference e, void arg) {
if (request.isMoorAndAnalyzed) { if (request.isMoorAndAnalyzed) {
final resolved = e.resolved; final resolved = e.resolved;
@ -69,7 +69,7 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
Iterable<Location> _locationOfColumn(Column column) sync* { Iterable<Location> _locationOfColumn(Column column) sync* {
@ -96,7 +96,7 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
} }
@override @override
void visitQueryable(Queryable e) { void visitQueryable(Queryable e, void arg) {
if (e is TableReference) { if (e is TableReference) {
final resolved = e.resolved; final resolved = e.resolved;
@ -107,6 +107,6 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
} }

View File

@ -16,12 +16,12 @@ class MoorOutlineContributor implements OutlineContributor {
if (moorRequest.isMoorAndParsed) { if (moorRequest.isMoorAndParsed) {
final visitor = _OutlineVisitor(moorRequest, collector); final visitor = _OutlineVisitor(moorRequest, collector);
moorRequest.parsedMoor.parsedFile.accept(visitor); moorRequest.parsedMoor.parsedFile.acceptWithoutArg(visitor);
} }
} }
} }
class _OutlineVisitor extends RecursiveVisitor<void> { class _OutlineVisitor extends RecursiveVisitor<void, void> {
final MoorRequest request; final MoorRequest request;
final OutlineCollector collector; final OutlineCollector collector;
@ -40,33 +40,33 @@ class _OutlineVisitor extends RecursiveVisitor<void> {
} }
@override @override
void visitCreateTableStatement(CreateTableStatement e) { void visitCreateTableStatement(CreateTableStatement e, void arg) {
_startElement(ElementKind.CLASS, e.tableName, e); _startElement(ElementKind.CLASS, e.tableName, e);
super.visitChildren(e); super.visitChildren(e, arg);
collector.endElement(); collector.endElement();
} }
@override @override
void visitColumnDefinition(ColumnDefinition e) { void visitColumnDefinition(ColumnDefinition e, void arg) {
// we use parameters instead of returnType because VS Code doesn't show // we use parameters instead of returnType because VS Code doesn't show
// the return type but we'd really like it to be shown // the return type but we'd really like it to be shown
_startElement(ElementKind.FIELD, e.columnName, e).parameters = e.typeName; _startElement(ElementKind.FIELD, e.columnName, e).parameters = e.typeName;
super.visitChildren(e); super.visitChildren(e, arg);
collector.endElement(); collector.endElement();
} }
@override @override
void visitMoorFile(MoorFile e) { void visitMoorFile(MoorFile e, void arg) {
_startElement(ElementKind.LIBRARY, request.file.shortName, e); _startElement(ElementKind.LIBRARY, request.file.shortName, e);
super.visitChildren(e); super.visitChildren(e, arg);
collector.endElement(); collector.endElement();
} }
@override @override
void visitMoorDeclaredStatement(DeclaredStatement e) { void visitMoorDeclaredStatement(DeclaredStatement e, void arg) {
if (!e.isRegularQuery) { if (!e.isRegularQuery) {
super.visitChildren(e); super.visitChildren(e, arg);
return; return;
} }
@ -85,7 +85,7 @@ class _OutlineVisitor extends RecursiveVisitor<void> {
element.parameters = parameterBuilder.toString(); element.parameters = parameterBuilder.toString();
} }
super.visitChildren(e); super.visitChildren(e, arg);
collector.endElement(); collector.endElement();
} }
} }

View File

@ -1,3 +1,7 @@
## unreleased
- Added a argument type and argument to the visitor classes
## 0.5.0 ## 0.5.0
- Optionally support the `json1` module - Optionally support the `json1` module
- Optionally support the `fts5` module - Optionally support the `fts5` module

View File

@ -4,23 +4,23 @@ part of '../analysis.dart';
/// columns are returned and which columns are available. For instance, when /// columns are returned and which columns are available. For instance, when
/// we have a table "t" with two columns "a" and "b", the select statement /// we have a table "t" with two columns "a" and "b", the select statement
/// "SELECT a FROM t" has one result column but two columns available. /// "SELECT a FROM t" has one result column but two columns available.
class ColumnResolver extends RecursiveVisitor<void> { class ColumnResolver extends RecursiveVisitor<void, void> {
final AnalysisContext context; final AnalysisContext context;
ColumnResolver(this.context); ColumnResolver(this.context);
@override @override
void visitSelectStatement(SelectStatement e) { void visitSelectStatement(SelectStatement e, void arg) {
// visit children first so that common table expressions are resolved // visit children first so that common table expressions are resolved
visitChildren(e); visitChildren(e, arg);
_resolveSelect(e); _resolveSelect(e);
} }
@override @override
void visitCompoundSelectStatement(CompoundSelectStatement e) { void visitCompoundSelectStatement(CompoundSelectStatement e, void arg) {
// first, visit all children so that the compound parts have their columns // first, visit all children so that the compound parts have their columns
// resolved // resolved
visitChildren(e); visitChildren(e, arg);
final columnSets = [ final columnSets = [
e.base.resolvedColumns, e.base.resolvedColumns,
@ -55,8 +55,8 @@ class ColumnResolver extends RecursiveVisitor<void> {
} }
@override @override
void visitCommonTableExpression(CommonTableExpression e) { void visitCommonTableExpression(CommonTableExpression e, void arg) {
visitChildren(e); visitChildren(e, arg);
final resolved = e.as.resolvedColumns; final resolved = e.as.resolvedColumns;
final names = e.columnNames; final names = e.columnNames;
@ -71,25 +71,25 @@ class ColumnResolver extends RecursiveVisitor<void> {
} }
@override @override
void visitUpdateStatement(UpdateStatement e) { void visitUpdateStatement(UpdateStatement e, void arg) {
final table = _resolveTableReference(e.table); final table = _resolveTableReference(e.table);
e.scope.availableColumns = table.resolvedColumns; e.scope.availableColumns = table.resolvedColumns;
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitInsertStatement(InsertStatement e) { void visitInsertStatement(InsertStatement e, void arg) {
final table = _resolveTableReference(e.table); final table = _resolveTableReference(e.table);
visitChildren(e); visitChildren(e, arg);
e.scope.availableColumns = table.resolvedColumns; e.scope.availableColumns = table.resolvedColumns;
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitDeleteStatement(DeleteStatement e) { void visitDeleteStatement(DeleteStatement e, void arg) {
final table = _resolveTableReference(e.from); final table = _resolveTableReference(e.from);
e.scope.availableColumns = table.resolvedColumns; e.scope.availableColumns = table.resolvedColumns;
visitChildren(e); visitChildren(e, arg);
} }
void _handle(Queryable queryable, List<Column> availableColumns) { void _handle(Queryable queryable, List<Column> availableColumns) {

View File

@ -2,24 +2,19 @@ part of '../analysis.dart';
/// Visitor that runs after all other steps ran and reports more complex lints /// Visitor that runs after all other steps ran and reports more complex lints
/// on an sql statement. /// on an sql statement.
class LintingVisitor extends RecursiveVisitor<void> { class LintingVisitor extends RecursiveVisitor<void, void> {
final EngineOptions options; final EngineOptions options;
final AnalysisContext context; final AnalysisContext context;
LintingVisitor(this.options, this.context); LintingVisitor(this.options, this.context);
@override @override
void visitAggregateExpression(Invocation e) => _visitInvocation(e); void visitInvocation(SqlInvocation e, void arg) {
@override
void visitFunction(Invocation e) => _visitInvocation(e);
void _visitInvocation(Invocation e) {
final lowercaseCall = e.name.toLowerCase(); final lowercaseCall = e.name.toLowerCase();
if (options.addedFunctions.containsKey(lowercaseCall)) { if (options.addedFunctions.containsKey(lowercaseCall)) {
options.addedFunctions[lowercaseCall].reportErrors(e, context); options.addedFunctions[lowercaseCall].reportErrors(e, context);
} }
visitChildren(e); visitChildren(e, arg);
} }
} }

View File

@ -8,19 +8,19 @@ part of '../analysis.dart';
/// statement. /// statement.
/// - reports syntactic errors that aren't handled in the parser to keep that /// - reports syntactic errors that aren't handled in the parser to keep that
/// implementation simpler. /// implementation simpler.
class AstPreparingVisitor extends RecursiveVisitor<void> { class AstPreparingVisitor extends RecursiveVisitor<void, void> {
final List<Variable> _foundVariables = []; final List<Variable> _foundVariables = [];
final AnalysisContext context; final AnalysisContext context;
AstPreparingVisitor({this.context}); AstPreparingVisitor({this.context});
void start(AstNode root) { void start(AstNode root) {
root.accept(this); root.accept(this, null);
_resolveIndexOfVariables(); _resolveIndexOfVariables();
} }
@override @override
void visitSelectStatement(SelectStatement e) { void visitSelectStatement(SelectStatement e, void arg) {
// a select statement can appear as a sub query which has its own scope, so // a select statement can appear as a sub query which has its own scope, so
// we need to fork the scope here. There is one special case though: // we need to fork the scope here. There is one special case though:
// Select statements that appear as a query source can't depend on data // Select statements that appear as a query source can't depend on data
@ -81,11 +81,11 @@ class AstPreparingVisitor extends RecursiveVisitor<void> {
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitResultColumn(ResultColumn e) { void visitResultColumn(ResultColumn e, void arg) {
if (e is StarResultColumn) { if (e is StarResultColumn) {
// doesn't need special treatment, star expressions can't be referenced // doesn't need special treatment, star expressions can't be referenced
} else if (e is ExpressionResultColumn) { } else if (e is ExpressionResultColumn) {
@ -93,11 +93,11 @@ class AstPreparingVisitor extends RecursiveVisitor<void> {
e.scope.register(e.as, e); e.scope.register(e.as, e);
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitQueryable(Queryable e) { void visitQueryable(Queryable e, void arg) {
final scope = e.scope; final scope = e.scope;
e.when( e.when(
isTable: (table) { isTable: (table) {
@ -120,25 +120,25 @@ class AstPreparingVisitor extends RecursiveVisitor<void> {
}, },
); );
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitCommonTableExpression(CommonTableExpression e) { void visitCommonTableExpression(CommonTableExpression e, void arg) {
e.scope.register(e.cteTableName, e); e.scope.register(e.cteTableName, e);
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitNumberedVariable(NumberedVariable e) { void visitNumberedVariable(NumberedVariable e, void arg) {
_foundVariables.add(e); _foundVariables.add(e);
visitChildren(e); visitChildren(e, arg);
} }
@override @override
void visitNamedVariable(ColonNamedVariable e) { void visitNamedVariable(ColonNamedVariable e, void arg) {
_foundVariables.add(e); _foundVariables.add(e);
visitChildren(e); visitChildren(e, arg);
} }
void _resolveIndexOfVariables() { void _resolveIndexOfVariables() {
@ -179,12 +179,12 @@ class AstPreparingVisitor extends RecursiveVisitor<void> {
} }
@override @override
void visitChildren(AstNode e) { void visitChildren(AstNode e, void arg) {
// hack to fork scopes on statements (selects are handled above) // hack to fork scopes on statements (selects are handled above)
if (e is Statement && e is! SelectStatement) { if (e is Statement && e is! SelectStatement) {
_forkScope(e); _forkScope(e);
} }
super.visitChildren(e); super.visitChildren(e, arg);
} }
} }

View File

@ -1,15 +1,15 @@
part of '../analysis.dart'; part of '../analysis.dart';
/// Resolves any open [Reference] it finds in the AST. /// Resolves any open [Reference] it finds in the AST.
class ReferenceResolver extends RecursiveVisitor<void> { class ReferenceResolver extends RecursiveVisitor<void, void> {
final AnalysisContext context; final AnalysisContext context;
ReferenceResolver(this.context); ReferenceResolver(this.context);
@override @override
void visitReference(Reference e) { void visitReference(Reference e, void arg) {
if (e.resolved != null) { if (e.resolved != null) {
return super.visitReference(e); return super.visitReference(e, arg);
} }
final scope = e.scope; final scope = e.scope;
@ -66,7 +66,7 @@ class ReferenceResolver extends RecursiveVisitor<void> {
} }
} }
visitChildren(e); visitChildren(e, arg);
} }
void _reportUnknownColumnError(Reference e, {Iterable<Column> columns}) { void _reportUnknownColumnError(Reference e, {Iterable<Column> columns}) {
@ -101,12 +101,12 @@ class ReferenceResolver extends RecursiveVisitor<void> {
} }
@override @override
void visitAggregateExpression(AggregateExpression e) { void visitAggregateExpression(AggregateExpression e, void arg) {
if (e.windowName != null && e.resolved == null) { if (e.windowName != null && e.resolved == null) {
final resolved = e.scope.resolve<NamedWindowDeclaration>(e.windowName); final resolved = e.scope.resolve<NamedWindowDeclaration>(e.windowName);
e.resolved = resolved; e.resolved = resolved;
} }
visitChildren(e); visitChildren(e, arg);
} }
} }

View File

@ -3,14 +3,14 @@ part of '../analysis.dart';
/// Resolves types for all nodes in the AST which can have a type. This includes /// Resolves types for all nodes in the AST which can have a type. This includes
/// expressions, variables and so on. For select statements, we also try to /// expressions, variables and so on. For select statements, we also try to
/// figure out what types they return. /// figure out what types they return.
class TypeResolvingVisitor extends RecursiveVisitor<void> { class TypeResolvingVisitor extends RecursiveVisitor<void, void> {
final AnalysisContext context; final AnalysisContext context;
TypeResolver get types => context.types; TypeResolver get types => context.types;
TypeResolvingVisitor(this.context); TypeResolvingVisitor(this.context);
@override @override
void visitChildren(AstNode e) { void visitChildren(AstNode e, void arg) {
// called for every ast node, so we implement this here // called for every ast node, so we implement this here
if (e is Expression && !types.needsToBeInferred(e)) { if (e is Expression && !types.needsToBeInferred(e)) {
types.resolveExpression(e); types.resolveExpression(e);
@ -18,11 +18,11 @@ class TypeResolvingVisitor extends RecursiveVisitor<void> {
e.resolvedColumns.forEach(types.resolveColumn); e.resolvedColumns.forEach(types.resolveColumn);
} }
super.visitChildren(e); super.visitChildren(e, arg);
} }
@override @override
void visitInsertStatement(InsertStatement e) { void visitInsertStatement(InsertStatement e, void arg) {
// resolve target columns - this is easy, as we should have the table // resolve target columns - this is easy, as we should have the table
// structure available. // structure available.
e.targetColumns.forEach(types.resolveExpression); e.targetColumns.forEach(types.resolveExpression);
@ -43,10 +43,12 @@ class TypeResolvingVisitor extends RecursiveVisitor<void> {
} }
// we already handled the source tuples, don't visit them // we already handled the source tuples, don't visit them
visitChildren(e.table); visit(e.table, arg);
e.targetColumns.forEach(visitChildren); for (final column in e.targetColumns) {
visit(column, arg);
}
} else { } else {
visitChildren(e); visitChildren(e, arg);
} }
} }
} }

View File

@ -112,7 +112,7 @@ class TypeResolver {
} else { } else {
return const ResolveResult.unknown(); return const ResolveResult.unknown();
} }
} else if (expr is Invocation) { } else if (expr is SqlInvocation) {
return resolveFunctionCall(expr); return resolveFunctionCall(expr);
} else if (expr is IsExpression || } else if (expr is IsExpression ||
expr is InExpression || expr is InExpression ||
@ -168,7 +168,7 @@ class TypeResolver {
/// Returns the expanded parameters of a function [call]. When a /// Returns the expanded parameters of a function [call]. When a
/// [StarFunctionParameter] is used, it's expanded to the /// [StarFunctionParameter] is used, it's expanded to the
/// [ReferenceScope.availableColumns]. /// [ReferenceScope.availableColumns].
List<Typeable> _expandParameters(Invocation call) { List<Typeable> _expandParameters(SqlInvocation call) {
final sqlParameters = call.parameters; final sqlParameters = call.parameters;
if (sqlParameters is ExprFunctionParameters) { if (sqlParameters is ExprFunctionParameters) {
return sqlParameters.parameters; return sqlParameters.parameters;
@ -180,8 +180,8 @@ class TypeResolver {
throw ArgumentError('Unknown parameters: $sqlParameters'); throw ArgumentError('Unknown parameters: $sqlParameters');
} }
ResolveResult resolveFunctionCall(Invocation call) { ResolveResult resolveFunctionCall(SqlInvocation call) {
return _cache((Invocation call) { return _cache((SqlInvocation call) {
final parameters = _expandParameters(call); final parameters = _expandParameters(call);
final firstNullable = final firstNullable =
// ignore: avoid_bool_literals_in_conditional_expressions // ignore: avoid_bool_literals_in_conditional_expressions
@ -328,7 +328,7 @@ class TypeResolver {
} }
ResolveResult _resolveFunctionArgument( ResolveResult _resolveFunctionArgument(
Invocation parent, Expression argument) { SqlInvocation parent, Expression argument) {
return _cache<Expression>((argument) { return _cache<Expression>((argument) {
final functionName = parent.name.toLowerCase(); final functionName = parent.name.toLowerCase();
final args = _expandParameters(parent); final args = _expandParameters(parent);
@ -420,7 +420,7 @@ class TypeResolver {
parent is Tuple || parent is Tuple ||
parent is UnaryExpression) { parent is UnaryExpression) {
return const ResolveResult.needsContext(); return const ResolveResult.needsContext();
} else if (parent is Invocation) { } else if (parent is SqlInvocation) {
// if we have a special case for the mix of function and argument, use // if we have a special case for the mix of function and argument, use
// that. Otherwise, just assume that the argument has the same type as the // that. Otherwise, just assume that the argument has the same type as the
// return type of the function // return type of the function

View File

@ -33,6 +33,7 @@ part 'statements/insert.dart';
part 'statements/select.dart'; part 'statements/select.dart';
part 'statements/statement.dart'; part 'statements/statement.dart';
part 'statements/update.dart'; part 'statements/update.dart';
part 'visitor.dart';
/// A node in the abstract syntax tree of an SQL statement. /// A node in the abstract syntax tree of an SQL statement.
abstract class AstNode with HasMetaMixin implements SyntacticEntity { abstract class AstNode with HasMetaMixin implements SyntacticEntity {
@ -129,7 +130,14 @@ abstract class AstNode with HasMetaMixin implements SyntacticEntity {
/// Calls the appropriate method on the [visitor] to make it recognize this /// Calls the appropriate method on the [visitor] to make it recognize this
/// node. /// node.
T accept<T>(AstVisitor<T> visitor); R accept<A, R>(AstVisitor<A, R> visitor, A arg);
/// Like [accept], but without an argument.
///
/// Null will be used for the argument instead.
R acceptWithoutArg<R>(AstVisitor<void, R> visitor) {
return accept(visitor, null);
}
/// Whether the content of this node is equal to the [other] node of the same /// Whether the content of this node is equal to the [other] node of the same
/// type. The "content" refers to anything stored only in this node, children /// type. The "content" refers to anything stored only in this node, children
@ -144,209 +152,3 @@ abstract class AstNode with HasMetaMixin implements SyntacticEntity {
return super.toString(); return super.toString();
} }
} }
abstract class AstVisitor<T> {
T visitSelectStatement(SelectStatement e);
T visitCompoundSelectStatement(CompoundSelectStatement e);
T visitCompoundSelectPart(CompoundSelectPart e);
T visitResultColumn(ResultColumn e);
T visitInsertStatement(InsertStatement e);
T visitDeleteStatement(DeleteStatement e);
T visitUpdateStatement(UpdateStatement e);
T visitCreateTableStatement(CreateTableStatement e);
T visitCreateVirtualTableStatement(CreateVirtualTableStatement e);
T visitWithClause(WithClause e);
T visitCommonTableExpression(CommonTableExpression e);
T visitOrderBy(OrderBy e);
T visitOrderingTerm(OrderingTerm e);
T visitLimit(Limit e);
T visitQueryable(Queryable e);
T visitJoin(Join e);
T visitGroupBy(GroupBy e);
T visitSetComponent(SetComponent e);
T visitColumnDefinition(ColumnDefinition e);
T visitColumnConstraint(ColumnConstraint e);
T visitTableConstraint(TableConstraint e);
T visitForeignKeyClause(ForeignKeyClause e);
T visitBinaryExpression(BinaryExpression e);
T visitStringComparison(StringComparisonExpression e);
T visitUnaryExpression(UnaryExpression e);
T visitIsExpression(IsExpression e);
T visitBetweenExpression(BetweenExpression e);
T visitLiteral(Literal e);
T visitReference(Reference e);
T visitFunction(FunctionExpression e);
T visitSubQuery(SubQuery e);
T visitExists(ExistsExpression e);
T visitCaseExpression(CaseExpression e);
T visitWhen(WhenComponent e);
T visitTuple(Tuple e);
T visitInExpression(InExpression e);
T visitAggregateExpression(AggregateExpression e);
T visitWindowDefinition(WindowDefinition e);
T visitFrameSpec(FrameSpec e);
T visitNumberedVariable(NumberedVariable e);
T visitNamedVariable(ColonNamedVariable e);
T visitMoorFile(MoorFile e);
T visitMoorImportStatement(ImportStatement e);
T visitMoorDeclaredStatement(DeclaredStatement e);
T visitMoorStatementParameter(StatementParameter e);
T visitDartPlaceholder(DartPlaceholder e);
}
/// Visitor that walks down the entire tree, visiting all children in order.
class RecursiveVisitor<T> extends AstVisitor<T> {
@override
T visitBinaryExpression(BinaryExpression e) => visitChildren(e);
@override
T visitStringComparison(StringComparisonExpression e) => visitChildren(e);
@override
T visitFunction(FunctionExpression e) => visitChildren(e);
@override
T visitGroupBy(GroupBy e) => visitChildren(e);
@override
T visitIsExpression(IsExpression e) => visitChildren(e);
@override
T visitBetweenExpression(BetweenExpression e) => visitChildren(e);
@override
T visitCaseExpression(CaseExpression e) => visitChildren(e);
@override
T visitWhen(WhenComponent e) => visitChildren(e);
@override
T visitTuple(Tuple e) => visitChildren(e);
@override
T visitInExpression(InExpression e) => visitChildren(e);
@override
T visitSubQuery(SubQuery e) => visitChildren(e);
@override
T visitExists(ExistsExpression e) => visitChildren(e);
@override
T visitSetComponent(SetComponent e) => visitChildren(e);
@override
T visitJoin(Join e) => visitChildren(e);
@override
T visitLimit(Limit e) => visitChildren(e);
@override
T visitLiteral(Literal e) => visitChildren(e);
@override
T visitNamedVariable(ColonNamedVariable e) => visitChildren(e);
@override
T visitNumberedVariable(NumberedVariable e) => visitChildren(e);
@override
T visitOrderBy(OrderBy e) => visitChildren(e);
@override
T visitOrderingTerm(OrderingTerm e) => visitChildren(e);
@override
T visitQueryable(Queryable e) => visitChildren(e);
@override
T visitReference(Reference e) => visitChildren(e);
@override
T visitResultColumn(ResultColumn e) => visitChildren(e);
@override
T visitSelectStatement(SelectStatement e) => visitChildren(e);
@override
T visitCompoundSelectStatement(CompoundSelectStatement e) => visitChildren(e);
@override
T visitCompoundSelectPart(CompoundSelectPart e) => visitChildren(e);
@override
T visitInsertStatement(InsertStatement e) => visitChildren(e);
@override
T visitDeleteStatement(DeleteStatement e) => visitChildren(e);
@override
T visitUpdateStatement(UpdateStatement e) => visitChildren(e);
@override
T visitCreateTableStatement(CreateTableStatement e) => visitChildren(e);
@override
T visitCreateVirtualTableStatement(CreateVirtualTableStatement e) =>
visitChildren(e);
@override
T visitUnaryExpression(UnaryExpression e) => visitChildren(e);
@override
T visitColumnDefinition(ColumnDefinition e) => visitChildren(e);
@override
T visitTableConstraint(TableConstraint e) => visitChildren(e);
@override
T visitColumnConstraint(ColumnConstraint e) => visitChildren(e);
@override
T visitForeignKeyClause(ForeignKeyClause e) => visitChildren(e);
@override
T visitAggregateExpression(AggregateExpression e) => visitChildren(e);
@override
T visitWindowDefinition(WindowDefinition e) => visitChildren(e);
@override
T visitFrameSpec(FrameSpec e) => visitChildren(e);
@override
T visitWithClause(WithClause e) => visitChildren(e);
@override
T visitCommonTableExpression(CommonTableExpression e) => visitChildren(e);
@override
T visitMoorFile(MoorFile e) => visitChildren(e);
@override
T visitMoorImportStatement(ImportStatement e) => visitChildren(e);
@override
T visitMoorDeclaredStatement(DeclaredStatement e) => visitChildren(e);
@override
T visitMoorStatementParameter(StatementParameter e) => visitChildren(e);
@override
T visitDartPlaceholder(DartPlaceholder e) => visitChildren(e);
@protected
T visitChildren(AstNode e) {
for (final child in e.childNodes) {
child.accept(this);
}
return null;
}
}

View File

@ -13,8 +13,8 @@ class Limit extends AstNode implements LimitBase {
Limit({this.count, this.offsetSeparator, this.offset}); Limit({this.count, this.offsetSeparator, this.offset});
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitLimit(this); return visitor.visitLimit(this, arg);
} }
@override @override

View File

@ -15,7 +15,9 @@ class OrderBy extends AstNode implements OrderByBase {
OrderBy({this.terms}); OrderBy({this.terms});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitOrderBy(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitOrderBy(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => terms; Iterable<AstNode> get childNodes => terms;
@ -38,7 +40,9 @@ class OrderingTerm extends AstNode implements OrderingTermBase {
OrderingTerm({this.expression, this.orderingMode}); OrderingTerm({this.expression, this.orderingMode});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitOrderingTerm(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitOrderingTerm(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [expression]; Iterable<AstNode> get childNodes => [expression];

View File

@ -11,7 +11,9 @@ class WithClause extends AstNode {
WithClause({@required this.recursive, @required this.ctes}); WithClause({@required this.recursive, @required this.ctes});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitWithClause(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitWithClause(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => ctes; Iterable<AstNode> get childNodes => ctes;
@ -38,8 +40,8 @@ class CommonTableExpression extends AstNode with ResultSet, VisibleToChildren {
{@required this.cteTableName, this.columnNames, @required this.as}); {@required this.cteTableName, this.columnNames, @required this.as});
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitCommonTableExpression(this); return visitor.visitCommonTableExpression(this, arg);
} }
@override @override

View File

@ -4,7 +4,9 @@ part of '../ast.dart';
/// statement. /// statement.
abstract class Queryable extends AstNode { abstract class Queryable extends AstNode {
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitQueryable(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitQueryable(this, arg);
}
T when<T>({ T when<T>({
@required T Function(TableReference) isTable, @required T Function(TableReference) isTable,
@ -145,7 +147,9 @@ class Join extends AstNode {
} }
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitJoin(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitJoin(this, arg);
}
} }
/// https://www.sqlite.org/syntax/join-constraint.html /// https://www.sqlite.org/syntax/join-constraint.html

View File

@ -12,7 +12,9 @@ class Tuple extends Expression {
Tuple({@required this.expressions}); Tuple({@required this.expressions});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitTuple(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitTuple(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => expressions; Iterable<AstNode> get childNodes => expressions;

View File

@ -1,7 +1,7 @@
part of '../ast.dart'; part of '../ast.dart';
class AggregateExpression extends Expression class AggregateExpression extends Expression
implements Invocation, ReferenceOwner { implements SqlInvocation, ReferenceOwner {
final IdentifierToken function; final IdentifierToken function;
@override @override
@ -42,7 +42,9 @@ class AggregateExpression extends Expression
: assert((windowDefinition == null) != (windowName == null)); : assert((windowDefinition == null) != (windowName == null));
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitAggregateExpression(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitAggregateExpression(this, arg);
}
@override @override
Iterable<AstNode> get childNodes { Iterable<AstNode> get childNodes {
@ -83,7 +85,9 @@ class WindowDefinition extends AstNode {
@required this.frameSpec}); @required this.frameSpec});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitWindowDefinition(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitWindowDefinition(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => Iterable<AstNode> get childNodes =>
@ -109,7 +113,9 @@ class FrameSpec extends AstNode {
}); });
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitFrameSpec(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitFrameSpec(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [ Iterable<AstNode> get childNodes => [

View File

@ -8,7 +8,9 @@ class CaseExpression extends Expression {
CaseExpression({this.base, @required this.whens, this.elseExpr}); CaseExpression({this.base, @required this.whens, this.elseExpr});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitCaseExpression(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitCaseExpression(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => Iterable<AstNode> get childNodes =>
@ -25,7 +27,9 @@ class WhenComponent extends AstNode {
WhenComponent({this.when, this.then}); WhenComponent({this.when, this.then});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitWhen(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitWhen(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [when, then]; Iterable<AstNode> get childNodes => [when, then];

View File

@ -2,9 +2,7 @@ part of '../ast.dart';
/// Interface for function calls, either a [FunctionExpression] or a /// Interface for function calls, either a [FunctionExpression] or a
/// [AggregateExpression]. /// [AggregateExpression].
// todo: How does this not clash with Invocation from dart:core :O Anyway, we abstract class SqlInvocation extends Expression {
// might want to consider renaming.
abstract class Invocation extends Expression {
/// The name of the function being called /// The name of the function being called
String get name; String get name;
@ -13,7 +11,7 @@ abstract class Invocation extends Expression {
class FunctionExpression extends Expression class FunctionExpression extends Expression
with ReferenceOwner with ReferenceOwner
implements Invocation { implements SqlInvocation {
@override @override
final String name; final String name;
@override @override
@ -22,7 +20,9 @@ class FunctionExpression extends Expression
FunctionExpression({@required this.name, @required this.parameters}); FunctionExpression({@required this.name, @required this.parameters});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitFunction(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitFunction(this, arg);
}
@override @override
Iterable<AstNode> get childNodes { Iterable<AstNode> get childNodes {

View File

@ -7,7 +7,9 @@ abstract class Literal extends Expression {
Literal(this.token); Literal(this.token);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitLiteral(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitLiteral(this, arg);
}
@override @override
final Iterable<AstNode> childNodes = const <AstNode>[]; final Iterable<AstNode> childNodes = const <AstNode>[];

View File

@ -16,7 +16,9 @@ class Reference extends Expression with ReferenceOwner {
Reference({this.tableName, this.columnName}); Reference({this.tableName, this.columnName});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitReference(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitReference(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => const []; Iterable<AstNode> get childNodes => const [];

View File

@ -7,7 +7,9 @@ class UnaryExpression extends Expression {
UnaryExpression(this.operator, this.inner); UnaryExpression(this.operator, this.inner);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitUnaryExpression(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitUnaryExpression(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [inner]; Iterable<AstNode> get childNodes => [inner];
@ -42,7 +44,9 @@ class BinaryExpression extends Expression {
BinaryExpression(this.left, this.operator, this.right); BinaryExpression(this.left, this.operator, this.right);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitBinaryExpression(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitBinaryExpression(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [left, right]; Iterable<AstNode> get childNodes => [left, right];
@ -68,7 +72,9 @@ class StringComparisonExpression extends Expression {
this.escape}); this.escape});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitStringComparison(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitStringComparison(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [left, right, if (escape != null) escape]; Iterable<AstNode> get childNodes => [left, right, if (escape != null) escape];
@ -86,8 +92,8 @@ class IsExpression extends Expression {
IsExpression(this.negated, this.left, this.right); IsExpression(this.negated, this.left, this.right);
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitIsExpression(this); return visitor.visitIsExpression(this, arg);
} }
@override @override
@ -109,7 +115,9 @@ class BetweenExpression extends Expression {
BetweenExpression({this.not = false, this.check, this.lower, this.upper}); BetweenExpression({this.not = false, this.check, this.lower, this.upper});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitBetweenExpression(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitBetweenExpression(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [check, lower, upper]; Iterable<AstNode> get childNodes => [check, lower, upper];
@ -133,7 +141,9 @@ class InExpression extends Expression {
: assert(inside is Tuple || inside is Variable || inside is SubQuery); : assert(inside is Tuple || inside is Variable || inside is SubQuery);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitInExpression(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitInExpression(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [left, inside]; Iterable<AstNode> get childNodes => [left, inside];
@ -155,8 +165,8 @@ class Parentheses extends Expression {
} }
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return expression.accept(visitor); return expression.accept(visitor, arg);
} }
@override @override

View File

@ -8,7 +8,9 @@ class SubQuery extends Expression {
SubQuery({this.select}); SubQuery({this.select});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitSubQuery(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitSubQuery(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [select]; Iterable<AstNode> get childNodes => [select];
@ -23,7 +25,9 @@ class ExistsExpression extends Expression {
ExistsExpression({@required this.select}); ExistsExpression({@required this.select});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitExists(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitExists(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [select]; Iterable<AstNode> get childNodes => [select];

View File

@ -14,8 +14,8 @@ class NumberedVariable extends Expression with Variable {
} }
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitNumberedVariable(this); return visitor.visitNumberedVariable(this, arg);
} }
@override @override
@ -34,8 +34,8 @@ class ColonNamedVariable extends Expression with Variable {
ColonNamedVariable(this.token); ColonNamedVariable(this.token);
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitNamedVariable(this); return visitor.visitNamedVariable(this, arg);
} }
@override @override

View File

@ -17,8 +17,9 @@ class DeclaredStatement extends Statement implements PartOfMoorFile {
DeclaredStatement(this.identifier, this.statement, {this.parameters}); DeclaredStatement(this.identifier, this.statement, {this.parameters});
@override @override
T accept<T>(AstVisitor<T> visitor) => R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
visitor.visitMoorDeclaredStatement(this); return visitor.visitMoorDeclaredStatement(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => Iterable<AstNode> get childNodes =>
@ -85,8 +86,8 @@ class SpecialStatementIdentifier extends DeclaredStatementIdentifier {
/// In `selectString(:name AS TEXT): SELECT :name`, `:name AS TEXT` is a /// In `selectString(:name AS TEXT): SELECT :name`, `:name AS TEXT` is a
abstract class StatementParameter extends AstNode { abstract class StatementParameter extends AstNode {
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitMoorStatementParameter(this); return visitor.visitMoorStatementParameter(this, arg);
} }
} }

View File

@ -9,7 +9,9 @@ class ImportStatement extends Statement implements PartOfMoorFile {
ImportStatement(this.importedFile); ImportStatement(this.importedFile);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitMoorImportStatement(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitMoorImportStatement(this, arg);
}
@override @override
final Iterable<AstNode> childNodes = const []; final Iterable<AstNode> childNodes = const [];

View File

@ -24,7 +24,9 @@ abstract class DartPlaceholder extends AstNode {
final Iterable<AstNode> childNodes = const Iterable.empty(); final Iterable<AstNode> childNodes = const Iterable.empty();
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitDartPlaceholder(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitDartPlaceholder(this, arg);
}
bool _dartEquals(covariant DartPlaceholder other) => true; bool _dartEquals(covariant DartPlaceholder other) => true;

View File

@ -13,7 +13,9 @@ class MoorFile extends AstNode {
MoorFile(this.statements); MoorFile(this.statements);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitMoorFile(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitMoorFile(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => statements; Iterable<AstNode> get childNodes => statements;

View File

@ -16,7 +16,9 @@ class ColumnDefinition extends AstNode {
this.constraints = const []}); this.constraints = const []});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitColumnDefinition(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitColumnDefinition(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => constraints; Iterable<AstNode> get childNodes => constraints;
@ -43,7 +45,9 @@ abstract class ColumnConstraint extends AstNode {
ColumnConstraint(this.name); ColumnConstraint(this.name);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitColumnConstraint(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitColumnConstraint(this, arg);
}
T when<T>({ T when<T>({
T Function(NotNull) notNull, T Function(NotNull) notNull,

View File

@ -15,7 +15,9 @@ class ForeignKeyClause extends AstNode {
this.onUpdate}); this.onUpdate});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitForeignKeyClause(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitForeignKeyClause(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [foreignTable, ...columnNames]; Iterable<AstNode> get childNodes => [foreignTable, ...columnNames];
@ -32,7 +34,9 @@ abstract class TableConstraint extends AstNode {
TableConstraint(this.name); TableConstraint(this.name);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitTableConstraint(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitTableConstraint(this, arg);
}
@override @override
bool contentEquals(TableConstraint other) { bool contentEquals(TableConstraint other) {

View File

@ -36,7 +36,9 @@ class CreateTableStatement extends TableInducingStatement {
: super._(ifNotExists, tableName, overriddenDataClassName); : super._(ifNotExists, tableName, overriddenDataClassName);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitCreateTableStatement(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitCreateTableStatement(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [...columns, ...tableConstraints]; Iterable<AstNode> get childNodes => [...columns, ...tableConstraints];
@ -73,8 +75,9 @@ class CreateVirtualTableStatement extends TableInducingStatement {
}) : super._(ifNotExists, tableName, overriddenDataClassName); }) : super._(ifNotExists, tableName, overriddenDataClassName);
@override @override
T accept<T>(AstVisitor<T> visitor) => R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
visitor.visitCreateVirtualTableStatement(this); return visitor.visitCreateVirtualTableStatement(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => const []; Iterable<AstNode> get childNodes => const [];

View File

@ -9,7 +9,9 @@ class DeleteStatement extends CrudStatement implements HasWhereClause {
: super._(withClause); : super._(withClause);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitDeleteStatement(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitDeleteStatement(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [ Iterable<AstNode> get childNodes => [

View File

@ -36,7 +36,9 @@ class InsertStatement extends CrudStatement {
: super._(withClause); : super._(withClause);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitInsertStatement(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitInsertStatement(this, arg);
}
@override @override
Iterable<AstNode> get childNodes sync* { Iterable<AstNode> get childNodes sync* {

View File

@ -35,8 +35,8 @@ class SelectStatement extends BaseSelectStatement implements HasWhereClause {
: super._(withClause); : super._(withClause);
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitSelectStatement(this); return visitor.visitSelectStatement(this, arg);
} }
@override @override
@ -79,8 +79,8 @@ class CompoundSelectStatement extends BaseSelectStatement {
} }
@override @override
T accept<T>(AstVisitor<T> visitor) { R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitCompoundSelectStatement(this); return visitor.visitCompoundSelectStatement(this, arg);
} }
@override @override
@ -92,7 +92,9 @@ class CompoundSelectStatement extends BaseSelectStatement {
abstract class ResultColumn extends AstNode { abstract class ResultColumn extends AstNode {
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitResultColumn(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitResultColumn(this, arg);
}
} }
/// A result column that either yields all columns or all columns from a table /// A result column that either yields all columns or all columns from a table
@ -136,7 +138,9 @@ class GroupBy extends AstNode {
GroupBy({@required this.by, this.having}); GroupBy({@required this.by, this.having});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitGroupBy(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitGroupBy(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [...by, if (having != null) having]; Iterable<AstNode> get childNodes => [...by, if (having != null) having];
@ -170,7 +174,9 @@ class CompoundSelectPart extends AstNode {
Iterable<AstNode> get childNodes => [select]; Iterable<AstNode> get childNodes => [select];
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitCompoundSelectPart(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitCompoundSelectPart(this, arg);
}
@override @override
bool contentEquals(CompoundSelectPart other) => mode == other.mode; bool contentEquals(CompoundSelectPart other) => mode == other.mode;

View File

@ -32,7 +32,9 @@ class UpdateStatement extends CrudStatement implements HasWhereClause {
: super._(withClause); : super._(withClause);
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitUpdateStatement(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitUpdateStatement(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [ Iterable<AstNode> get childNodes => [
@ -59,7 +61,9 @@ class SetComponent extends AstNode {
SetComponent({@required this.column, @required this.expression}); SetComponent({@required this.column, @required this.expression});
@override @override
T accept<T>(AstVisitor<T> visitor) => visitor.visitSetComponent(this); R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitSetComponent(this, arg);
}
@override @override
Iterable<AstNode> get childNodes => [column, expression]; Iterable<AstNode> get childNodes => [column, expression];

View File

@ -0,0 +1,340 @@
part of 'ast.dart';
abstract class AstVisitor<A, R> {
R visitSelectStatement(SelectStatement e, A arg);
R visitCompoundSelectStatement(CompoundSelectStatement e, A arg);
R visitCompoundSelectPart(CompoundSelectPart e, A arg);
R visitResultColumn(ResultColumn e, A arg);
R visitInsertStatement(InsertStatement e, A arg);
R visitDeleteStatement(DeleteStatement e, A arg);
R visitUpdateStatement(UpdateStatement e, A arg);
R visitCreateTableStatement(CreateTableStatement e, A arg);
R visitCreateVirtualTableStatement(CreateVirtualTableStatement e, A arg);
R visitWithClause(WithClause e, A arg);
R visitCommonTableExpression(CommonTableExpression e, A arg);
R visitOrderBy(OrderBy e, A arg);
R visitOrderingTerm(OrderingTerm e, A arg);
R visitLimit(Limit e, A arg);
R visitQueryable(Queryable e, A arg);
R visitJoin(Join e, A arg);
R visitGroupBy(GroupBy e, A arg);
R visitSetComponent(SetComponent e, A arg);
R visitColumnDefinition(ColumnDefinition e, A arg);
R visitColumnConstraint(ColumnConstraint e, A arg);
R visitTableConstraint(TableConstraint e, A arg);
R visitForeignKeyClause(ForeignKeyClause e, A arg);
R visitBinaryExpression(BinaryExpression e, A arg);
R visitStringComparison(StringComparisonExpression e, A arg);
R visitUnaryExpression(UnaryExpression e, A arg);
R visitIsExpression(IsExpression e, A arg);
R visitBetweenExpression(BetweenExpression e, A arg);
R visitLiteral(Literal e, A arg);
R visitReference(Reference e, A arg);
R visitFunction(FunctionExpression e, A arg);
R visitSubQuery(SubQuery e, A arg);
R visitExists(ExistsExpression e, A arg);
R visitCaseExpression(CaseExpression e, A arg);
R visitWhen(WhenComponent e, A arg);
R visitTuple(Tuple e, A arg);
R visitInExpression(InExpression e, A arg);
R visitAggregateExpression(AggregateExpression e, A arg);
R visitWindowDefinition(WindowDefinition e, A arg);
R visitFrameSpec(FrameSpec e, A arg);
R visitNumberedVariable(NumberedVariable e, A arg);
R visitNamedVariable(ColonNamedVariable e, A arg);
R visitMoorFile(MoorFile e, A arg);
R visitMoorImportStatement(ImportStatement e, A arg);
R visitMoorDeclaredStatement(DeclaredStatement e, A arg);
R visitMoorStatementParameter(StatementParameter e, A arg);
R visitDartPlaceholder(DartPlaceholder e, A arg);
}
/// Visitor that walks down the entire tree, visiting all children in order.
class RecursiveVisitor<A, R> implements AstVisitor<A, R> {
// Statements
@override
R visitSelectStatement(SelectStatement e, A arg) {
return visitBaseSelectStatement(e, arg);
}
@override
R visitCompoundSelectStatement(CompoundSelectStatement e, A arg) {
return visitBaseSelectStatement(e, arg);
}
@override
R visitInsertStatement(InsertStatement e, A arg) {
return visitCrudStatement(e, arg);
}
@override
R visitDeleteStatement(DeleteStatement e, A arg) {
return visitCrudStatement(e, arg);
}
@override
R visitUpdateStatement(UpdateStatement e, A arg) {
return visitCrudStatement(e, arg);
}
@override
R visitCreateTableStatement(CreateTableStatement e, A arg) {
return visitTableInducingStatement(e, arg);
}
@override
@override
R visitCreateVirtualTableStatement(CreateVirtualTableStatement e, A arg) {
return visitTableInducingStatement(e, arg);
}
R visitBaseSelectStatement(BaseSelectStatement stmt, A arg) {
return visitCrudStatement(stmt, arg);
}
R visitCrudStatement(CrudStatement stmt, A arg) {
return visitStatement(stmt, arg);
}
R visitTableInducingStatement(TableInducingStatement stmt, A arg) {
return visitSchemaStatement(stmt, arg);
}
R visitSchemaStatement(SchemaStatement stmt, A arg) {
return visitStatement(stmt, arg);
}
R visitStatement(Statement statement, A arg) {
return visitChildren(statement, arg);
}
@override
R visitCompoundSelectPart(CompoundSelectPart e, A arg) {
return visitChildren(e, arg);
}
// General clauses
@override
R visitResultColumn(ResultColumn e, A arg) {
return visitChildren(e, arg);
}
@override
R visitWithClause(WithClause e, A arg) {
return visitChildren(e, arg);
}
@override
R visitCommonTableExpression(CommonTableExpression e, A arg) {
return visitChildren(e, arg);
}
@override
R visitOrderBy(OrderBy e, A arg) {
return visitChildren(e, arg);
}
@override
R visitOrderingTerm(OrderingTerm e, A arg) {
return visitChildren(e, arg);
}
@override
R visitLimit(Limit e, A arg) {
return visitChildren(e, arg);
}
@override
R visitQueryable(Queryable e, A arg) {
return visitChildren(e, arg);
}
@override
R visitJoin(Join e, A arg) {
return visitChildren(e, arg);
}
@override
R visitGroupBy(GroupBy e, A arg) {
return visitChildren(e, arg);
}
@override
R visitSetComponent(SetComponent e, A arg) {
return visitChildren(e, arg);
}
@override
R visitColumnDefinition(ColumnDefinition e, A arg) {
return visitChildren(e, arg);
}
@override
R visitColumnConstraint(ColumnConstraint e, A arg) {
return visitChildren(e, arg);
}
@override
R visitTableConstraint(TableConstraint e, A arg) {
return visitChildren(e, arg);
}
@override
R visitForeignKeyClause(ForeignKeyClause e, A arg) {
return visitChildren(e, arg);
}
@override
R visitWindowDefinition(WindowDefinition e, A arg) {
return visitChildren(e, arg);
}
@override
R visitFrameSpec(FrameSpec e, A arg) {
return visitChildren(e, arg);
}
// Moor-specific additions
@override
R visitMoorFile(MoorFile e, A arg) {
return visitChildren(e, arg);
}
@override
R visitMoorImportStatement(ImportStatement e, A arg) {
return visitStatement(e, arg);
}
@override
R visitMoorDeclaredStatement(DeclaredStatement e, A arg) {
return visitStatement(e, arg);
}
@override
R visitDartPlaceholder(DartPlaceholder e, A arg) {
return visitChildren(e, arg);
}
@override
R visitMoorStatementParameter(StatementParameter e, A arg) {
return visitChildren(e, arg);
}
// Expressions
@override
R visitBinaryExpression(BinaryExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitUnaryExpression(UnaryExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitStringComparison(StringComparisonExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitIsExpression(IsExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitBetweenExpression(BetweenExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitLiteral(Literal e, A arg) {
return visitExpression(e, arg);
}
@override
R visitReference(Reference e, A arg) {
return visitExpression(e, arg);
}
@override
R visitFunction(FunctionExpression e, A arg) {
return visitInvocation(e, arg);
}
@override
R visitAggregateExpression(AggregateExpression e, A arg) {
return visitInvocation(e, arg);
}
@override
R visitSubQuery(SubQuery e, A arg) {
return visitExpression(e, arg);
}
@override
R visitExists(ExistsExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitCaseExpression(CaseExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitWhen(WhenComponent e, A arg) {
return visitChildren(e, arg);
}
@override
R visitTuple(Tuple e, A arg) {
return visitExpression(e, arg);
}
@override
R visitInExpression(InExpression e, A arg) {
return visitExpression(e, arg);
}
@override
R visitNumberedVariable(NumberedVariable e, A arg) {
return visitVariable(e, arg);
}
@override
R visitNamedVariable(ColonNamedVariable e, A arg) {
return visitVariable(e, arg);
}
R visitVariable(Variable e, A arg) {
return visitExpression(e, arg);
}
R visitInvocation(SqlInvocation e, A arg) {
return visitExpression(e, arg);
}
R visitExpression(Expression e, A arg) {
return visitChildren(e, arg);
}
R visit(AstNode e, A arg) => visitChildren(e, arg);
@protected
R visitChildren(AstNode e, A arg) {
for (final child in e.childNodes) {
child.accept(this, arg);
}
return null;
}
}

View File

@ -61,7 +61,7 @@ class _Fts5Functions implements FunctionHandler {
@override @override
ResolveResult inferArgumentType( ResolveResult inferArgumentType(
TypeResolver resolver, Invocation call, Expression argument) { TypeResolver resolver, SqlInvocation call, Expression argument) {
int argumentIndex; int argumentIndex;
if (call.parameters is ExprFunctionParameters) { if (call.parameters is ExprFunctionParameters) {
argumentIndex = (call.parameters as ExprFunctionParameters) argumentIndex = (call.parameters as ExprFunctionParameters)
@ -100,7 +100,7 @@ class _Fts5Functions implements FunctionHandler {
@override @override
ResolveResult inferReturnType( ResolveResult inferReturnType(
TypeResolver resolver, Invocation call, List<Typeable> expandedArgs) { TypeResolver resolver, SqlInvocation call, List<Typeable> expandedArgs) {
switch (call.name) { switch (call.name) {
case 'bm25': case 'bm25':
return const ResolveResult(ResolvedType(type: BasicType.real)); return const ResolveResult(ResolvedType(type: BasicType.real));
@ -113,7 +113,7 @@ class _Fts5Functions implements FunctionHandler {
} }
@override @override
void reportErrors(Invocation call, AnalysisContext context) { void reportErrors(SqlInvocation call, AnalysisContext context) {
// it doesn't make sense to call fts5 functions with a star parameter // it doesn't make sense to call fts5 functions with a star parameter
if (call.parameters is StarFunctionParameter) { if (call.parameters is StarFunctionParameter) {
context.reportError(AnalysisError( context.reportError(AnalysisError(

View File

@ -26,7 +26,7 @@ abstract class FunctionHandler {
/// If resolving to a type isn't possible, implementations should return /// If resolving to a type isn't possible, implementations should return
/// [ResolveResult.unknown]. /// [ResolveResult.unknown].
ResolveResult inferReturnType( ResolveResult inferReturnType(
TypeResolver resolver, Invocation call, List<Typeable> expandedArgs); TypeResolver resolver, SqlInvocation call, List<Typeable> expandedArgs);
/// Resolve the type of an argument used in a function invocation. /// Resolve the type of an argument used in a function invocation.
/// ///
@ -38,13 +38,13 @@ abstract class FunctionHandler {
/// If resolving to a type isn't possible, implementations should return /// If resolving to a type isn't possible, implementations should return
/// [ResolveResult.unknown]. /// [ResolveResult.unknown].
ResolveResult inferArgumentType( ResolveResult inferArgumentType(
TypeResolver resolver, Invocation call, Expression argument); TypeResolver resolver, SqlInvocation call, Expression argument);
/// Can optionally be used by implementations to provide [AnalysisError]s /// Can optionally be used by implementations to provide [AnalysisError]s
/// from the [call]. /// from the [call].
/// ///
/// Errors should be reported via [AnalysisContext.reportError]. /// Errors should be reported via [AnalysisContext.reportError].
void reportErrors(Invocation call, AnalysisContext context) {} void reportErrors(SqlInvocation call, AnalysisContext context) {}
} }
/// An sqlite module, which can be used in a `CREATE VIRTUAL TABLE` statement /// An sqlite module, which can be used in a `CREATE VIRTUAL TABLE` statement

View File

@ -184,10 +184,10 @@ class SqlEngine {
if (node is CrudStatement) { if (node is CrudStatement) {
node node
..accept(ColumnResolver(context)) ..acceptWithoutArg(ColumnResolver(context))
..accept(ReferenceResolver(context)) ..acceptWithoutArg(ReferenceResolver(context))
..accept(TypeResolvingVisitor(context)) ..acceptWithoutArg(TypeResolvingVisitor(context))
..accept(LintingVisitor(options, context)); ..acceptWithoutArg(LintingVisitor(options, context));
} }
} catch (_) { } catch (_) {
rethrow; rethrow;