diff --git a/moor_generator/lib/src/analyzer/moor/table_handler.dart b/moor_generator/lib/src/analyzer/moor/table_handler.dart index 6ffd9fea..4be98dc7 100644 --- a/moor_generator/lib/src/analyzer/moor/table_handler.dart +++ b/moor_generator/lib/src/analyzer/moor/table_handler.dart @@ -19,17 +19,18 @@ class TableHandler { table.references.clear(); } - file.parseResult.rootNode?.accept(_ReferenceResolvingVisitor(this)); + file.parseResult.rootNode + ?.acceptWithoutArg(_ReferenceResolvingVisitor(this)); } } -class _ReferenceResolvingVisitor extends RecursiveVisitor { +class _ReferenceResolvingVisitor extends RecursiveVisitor { final TableHandler handler; _ReferenceResolvingVisitor(this.handler); @override - void visitForeignKeyClause(ForeignKeyClause clause) { + void visitForeignKeyClause(ForeignKeyClause clause, void arg) { final stmt = clause.parents.whereType().first; final referencedTable = handler.availableTables.singleWhere( (t) => t.sqlName == clause.foreignTable.tableName, @@ -47,6 +48,6 @@ class _ReferenceResolvingVisitor extends RecursiveVisitor { createdTable?.references?.add(referencedTable); } - super.visitForeignKeyClause(clause); + super.visitForeignKeyClause(clause, arg); } } diff --git a/moor_generator/lib/src/analyzer/sql_queries/affected_tables_visitor.dart b/moor_generator/lib/src/analyzer/sql_queries/affected_tables_visitor.dart index a5bb0e86..0edf9261 100644 --- a/moor_generator/lib/src/analyzer/sql_queries/affected_tables_visitor.dart +++ b/moor_generator/lib/src/analyzer/sql_queries/affected_tables_visitor.dart @@ -2,22 +2,22 @@ import 'package:sqlparser/sqlparser.dart'; /// An AST-visitor that walks sql statements and finds all tables referenced in /// them. -class ReferencedTablesVisitor extends RecursiveVisitor { +class ReferencedTablesVisitor extends RecursiveVisitor { /// All tables that have been referenced anywhere in this query. final Set foundTables = {}; @override - void visitReference(Reference e) { + void visitReference(Reference e, void arg) { final column = e.resolved; if (column is TableColumn) { foundTables.add(column.table); } - visitChildren(e); + visitChildren(e, arg); } @override - void visitQueryable(Queryable e) { + void visitQueryable(Queryable e, void arg) { if (e is TableReference) { final resolved = e.resolved; if (resolved != null && resolved is Table) { @@ -25,7 +25,7 @@ class ReferencedTablesVisitor extends RecursiveVisitor { } } - visitChildren(e); + visitChildren(e, arg); } } @@ -48,20 +48,20 @@ class UpdatedTablesVisitor extends ReferencedTablesVisitor { } @override - void visitDeleteStatement(DeleteStatement e) { + void visitDeleteStatement(DeleteStatement e, void arg) { _addIfResolved(e.from); - visitChildren(e); + visitChildren(e, arg); } @override - void visitUpdateStatement(UpdateStatement e) { + void visitUpdateStatement(UpdateStatement e, void arg) { _addIfResolved(e.table); - visitChildren(e); + visitChildren(e, arg); } @override - void visitInsertStatement(InsertStatement e) { + void visitInsertStatement(InsertStatement e, void arg) { _addIfResolved(e.table); - visitChildren(e); + visitChildren(e, arg); } } diff --git a/moor_generator/lib/src/analyzer/sql_queries/lints/linter.dart b/moor_generator/lib/src/analyzer/sql_queries/lints/linter.dart index 937aa7db..b55abee0 100644 --- a/moor_generator/lib/src/analyzer/sql_queries/lints/linter.dart +++ b/moor_generator/lib/src/analyzer/sql_queries/lints/linter.dart @@ -11,18 +11,18 @@ class Linter { Linter(this.handler); void reportLints() { - handler.context.root.accept(_LintingVisitor(this)); + handler.context.root.acceptWithoutArg(_LintingVisitor(this)); } } -class _LintingVisitor extends RecursiveVisitor { +class _LintingVisitor extends RecursiveVisitor { final Linter linter; _LintingVisitor(this.linter); @override - void visitResultColumn(ResultColumn e) { - super.visitResultColumn(e); + void visitResultColumn(ResultColumn e, void arg) { + super.visitResultColumn(e, arg); if (e is ExpressionResultColumn) { // The generated code will be invalid if knowing the expression is needed @@ -54,7 +54,7 @@ class _LintingVisitor extends RecursiveVisitor { } @override - void visitInsertStatement(InsertStatement e) { + void visitInsertStatement(InsertStatement e, void arg) { final targeted = e.resolvedTargetColumns; if (targeted == null) return; diff --git a/moor_generator/lib/src/analyzer/sql_queries/query_handler.dart b/moor_generator/lib/src/analyzer/sql_queries/query_handler.dart index fca965f3..0c927a94 100644 --- a/moor_generator/lib/src/analyzer/sql_queries/query_handler.dart +++ b/moor_generator/lib/src/analyzer/sql_queries/query_handler.dart @@ -53,7 +53,7 @@ class QueryHandler { UpdatingQuery _handleUpdate() { final updatedFinder = UpdatedTablesVisitor(); - context.root.accept(updatedFinder); + context.root.acceptWithoutArg(updatedFinder); _foundTables = updatedFinder.writtenTables; final isInsert = context.root is InsertStatement; @@ -70,7 +70,7 @@ class QueryHandler { SqlSelectQuery _handleSelect() { final tableFinder = ReferencedTablesVisitor(); - _select.accept(tableFinder); + _select.acceptWithoutArg(tableFinder); _foundTables = tableFinder.foundTables; final moorTables = _foundTables.map(mapper.tableToMoor).where((s) => s != null).toList(); diff --git a/moor_generator/lib/src/backends/plugin/services/folding.dart b/moor_generator/lib/src/backends/plugin/services/folding.dart index 19f65afc..5d6a23cd 100644 --- a/moor_generator/lib/src/backends/plugin/services/folding.dart +++ b/moor_generator/lib/src/backends/plugin/services/folding.dart @@ -13,18 +13,18 @@ class MoorFoldingContributor implements FoldingContributor { if (moorRequest.isMoorAndParsed) { final result = moorRequest.parsedMoor; final visitor = _FoldingVisitor(collector); - result.parsedFile.accept(visitor); + result.parsedFile.acceptWithoutArg(visitor); } } } -class _FoldingVisitor extends RecursiveVisitor { +class _FoldingVisitor extends RecursiveVisitor { final FoldingCollector collector; _FoldingVisitor(this.collector); @override - void visitMoorFile(MoorFile e) { + void visitMoorFile(MoorFile e, void arg) { // construct a folding region for import statements final imports = e.imports.toList(); if (imports.length > 1) { @@ -34,11 +34,11 @@ class _FoldingVisitor extends RecursiveVisitor { collector.addRegion(first, last - first, FoldingKind.DIRECTIVES); } - super.visitChildren(e); + super.visitChildren(e, arg); } @override - void visitCreateTableStatement(CreateTableStatement e) { + void visitCreateTableStatement(CreateTableStatement e, void arg) { final startBody = e.openingBracket; final endBody = e.closingBracket; diff --git a/moor_generator/lib/src/backends/plugin/services/highlights.dart b/moor_generator/lib/src/backends/plugin/services/highlights.dart index 2b05af5c..897b60f7 100644 --- a/moor_generator/lib/src/backends/plugin/services/highlights.dart +++ b/moor_generator/lib/src/backends/plugin/services/highlights.dart @@ -18,7 +18,7 @@ class MoorHighlightContributor implements HighlightsContributor { final result = typedRequest.parsedMoor; final visitor = _HighlightingVisitor(collector); - result.parsedFile.accept(visitor); + result.parsedFile.acceptWithoutArg(visitor); for (final token in result.parseResult.tokens) { final start = token.span.start.offset; @@ -43,7 +43,7 @@ class MoorHighlightContributor implements HighlightsContributor { } } -class _HighlightingVisitor extends RecursiveVisitor { +class _HighlightingVisitor extends RecursiveVisitor { final HighlightsCollector collector; _HighlightingVisitor(this.collector); @@ -55,41 +55,32 @@ class _HighlightingVisitor extends RecursiveVisitor { } @override - void visitReference(Reference e) { + void visitReference(Reference e, void arg) { _contribute(e, HighlightRegionType.INSTANCE_GETTER_REFERENCE); } @override - void visitQueryable(Queryable e) { + void visitQueryable(Queryable e, void arg) { if (e is TableReference) { final tableToken = e.tableNameToken; if (tableToken != null) { _contribute(e, HighlightRegionType.TYPE_PARAMETER); } } - visitChildren(e); + visitChildren(e, arg); } @override - void visitCreateTableStatement(CreateTableStatement e) { - _visitTableInducingStatement(e); - } - - @override - void visitCreateVirtualTableStatement(CreateVirtualTableStatement e) { - _visitTableInducingStatement(e); - } - - void _visitTableInducingStatement(TableInducingStatement e) { + void visitTableInducingStatement(TableInducingStatement e, void arg) { if (e.tableNameToken != null) { _contribute(e.tableNameToken, HighlightRegionType.CLASS); } - visitChildren(e); + visitChildren(e, arg); } @override - void visitColumnDefinition(ColumnDefinition e) { + void visitColumnDefinition(ColumnDefinition e, void arg) { final nameToken = e.nameToken; if (nameToken != null) { _contribute(nameToken, HighlightRegionType.INSTANCE_FIELD_DECLARATION); @@ -103,17 +94,17 @@ class _HighlightingVisitor extends RecursiveVisitor { collector.addRegion(first, length, HighlightRegionType.TYPE_PARAMETER); } - visitChildren(e); + visitChildren(e, arg); } @override - void visitSetComponent(SetComponent e) { + void visitSetComponent(SetComponent e, void arg) { _contribute(e.column, HighlightRegionType.INSTANCE_SETTER_REFERENCE); - visitChildren(e); + visitChildren(e, arg); } @override - void visitMoorDeclaredStatement(DeclaredStatement e) { + void visitMoorDeclaredStatement(DeclaredStatement e, void arg) { final identifier = e.identifier; if (identifier is SimpleName && identifier.identifier != null) { _contribute(identifier.identifier, @@ -123,11 +114,11 @@ class _HighlightingVisitor extends RecursiveVisitor { _contribute(identifier.nameToken, HighlightRegionType.ANNOTATION); } - visitChildren(e); + visitChildren(e, arg); } @override - void visitLiteral(Literal e) { + void visitLiteral(Literal e, void arg) { if (e is NullLiteral) { _contribute(e, HighlightRegionType.BUILT_IN); } else if (e is NumericLiteral) { diff --git a/moor_generator/lib/src/backends/plugin/services/navigation.dart b/moor_generator/lib/src/backends/plugin/services/navigation.dart index a5576bcb..1597f0e5 100644 --- a/moor_generator/lib/src/backends/plugin/services/navigation.dart +++ b/moor_generator/lib/src/backends/plugin/services/navigation.dart @@ -17,12 +17,12 @@ class MoorNavigationContributor implements NavigationContributor { final visitor = _NavigationVisitor(moorRequest, collector); if (moorRequest.file.isParsed) { - moorRequest.parsedMoor.parsedFile.accept(visitor); + moorRequest.parsedMoor.parsedFile.acceptWithoutArg(visitor); } } } -class _NavigationVisitor extends RecursiveVisitor { +class _NavigationVisitor extends RecursiveVisitor { final MoorRequestAtPosition request; final NavigationCollector collector; @@ -41,7 +41,7 @@ class _NavigationVisitor extends RecursiveVisitor { } @override - void visitMoorImportStatement(ImportStatement e) { + void visitMoorImportStatement(ImportStatement e, void arg) { if (request.isMoorAndParsed) { final moor = request.parsedMoor; final resolved = moor.resolvedImports[e]; @@ -53,11 +53,11 @@ class _NavigationVisitor extends RecursiveVisitor { } } - visitChildren(e); + visitChildren(e, arg); } @override - void visitReference(Reference e) { + void visitReference(Reference e, void arg) { if (request.isMoorAndAnalyzed) { final resolved = e.resolved; @@ -69,7 +69,7 @@ class _NavigationVisitor extends RecursiveVisitor { } } - visitChildren(e); + visitChildren(e, arg); } Iterable _locationOfColumn(Column column) sync* { @@ -96,7 +96,7 @@ class _NavigationVisitor extends RecursiveVisitor { } @override - void visitQueryable(Queryable e) { + void visitQueryable(Queryable e, void arg) { if (e is TableReference) { final resolved = e.resolved; @@ -107,6 +107,6 @@ class _NavigationVisitor extends RecursiveVisitor { } } - visitChildren(e); + visitChildren(e, arg); } } diff --git a/moor_generator/lib/src/backends/plugin/services/outline.dart b/moor_generator/lib/src/backends/plugin/services/outline.dart index 7489657d..fe632436 100644 --- a/moor_generator/lib/src/backends/plugin/services/outline.dart +++ b/moor_generator/lib/src/backends/plugin/services/outline.dart @@ -16,12 +16,12 @@ class MoorOutlineContributor implements OutlineContributor { if (moorRequest.isMoorAndParsed) { final visitor = _OutlineVisitor(moorRequest, collector); - moorRequest.parsedMoor.parsedFile.accept(visitor); + moorRequest.parsedMoor.parsedFile.acceptWithoutArg(visitor); } } } -class _OutlineVisitor extends RecursiveVisitor { +class _OutlineVisitor extends RecursiveVisitor { final MoorRequest request; final OutlineCollector collector; @@ -40,33 +40,33 @@ class _OutlineVisitor extends RecursiveVisitor { } @override - void visitCreateTableStatement(CreateTableStatement e) { + void visitCreateTableStatement(CreateTableStatement e, void arg) { _startElement(ElementKind.CLASS, e.tableName, e); - super.visitChildren(e); + super.visitChildren(e, arg); collector.endElement(); } @override - void visitColumnDefinition(ColumnDefinition e) { + void visitColumnDefinition(ColumnDefinition e, void arg) { // we use parameters instead of returnType because VS Code doesn't show // the return type but we'd really like it to be shown _startElement(ElementKind.FIELD, e.columnName, e).parameters = e.typeName; - super.visitChildren(e); + super.visitChildren(e, arg); collector.endElement(); } @override - void visitMoorFile(MoorFile e) { + void visitMoorFile(MoorFile e, void arg) { _startElement(ElementKind.LIBRARY, request.file.shortName, e); - super.visitChildren(e); + super.visitChildren(e, arg); collector.endElement(); } @override - void visitMoorDeclaredStatement(DeclaredStatement e) { + void visitMoorDeclaredStatement(DeclaredStatement e, void arg) { if (!e.isRegularQuery) { - super.visitChildren(e); + super.visitChildren(e, arg); return; } @@ -85,7 +85,7 @@ class _OutlineVisitor extends RecursiveVisitor { element.parameters = parameterBuilder.toString(); } - super.visitChildren(e); + super.visitChildren(e, arg); collector.endElement(); } } diff --git a/sqlparser/CHANGELOG.md b/sqlparser/CHANGELOG.md index 64c611ec..07313de8 100644 --- a/sqlparser/CHANGELOG.md +++ b/sqlparser/CHANGELOG.md @@ -1,3 +1,7 @@ +## unreleased + +- Added a argument type and argument to the visitor classes + ## 0.5.0 - Optionally support the `json1` module - Optionally support the `fts5` module diff --git a/sqlparser/lib/src/analysis/steps/column_resolver.dart b/sqlparser/lib/src/analysis/steps/column_resolver.dart index c5763981..66234879 100644 --- a/sqlparser/lib/src/analysis/steps/column_resolver.dart +++ b/sqlparser/lib/src/analysis/steps/column_resolver.dart @@ -4,23 +4,23 @@ part of '../analysis.dart'; /// 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 /// "SELECT a FROM t" has one result column but two columns available. -class ColumnResolver extends RecursiveVisitor { +class ColumnResolver extends RecursiveVisitor { final AnalysisContext context; ColumnResolver(this.context); @override - void visitSelectStatement(SelectStatement e) { + void visitSelectStatement(SelectStatement e, void arg) { // visit children first so that common table expressions are resolved - visitChildren(e); + visitChildren(e, arg); _resolveSelect(e); } @override - void visitCompoundSelectStatement(CompoundSelectStatement e) { + void visitCompoundSelectStatement(CompoundSelectStatement e, void arg) { // first, visit all children so that the compound parts have their columns // resolved - visitChildren(e); + visitChildren(e, arg); final columnSets = [ e.base.resolvedColumns, @@ -55,8 +55,8 @@ class ColumnResolver extends RecursiveVisitor { } @override - void visitCommonTableExpression(CommonTableExpression e) { - visitChildren(e); + void visitCommonTableExpression(CommonTableExpression e, void arg) { + visitChildren(e, arg); final resolved = e.as.resolvedColumns; final names = e.columnNames; @@ -71,25 +71,25 @@ class ColumnResolver extends RecursiveVisitor { } @override - void visitUpdateStatement(UpdateStatement e) { + void visitUpdateStatement(UpdateStatement e, void arg) { final table = _resolveTableReference(e.table); e.scope.availableColumns = table.resolvedColumns; - visitChildren(e); + visitChildren(e, arg); } @override - void visitInsertStatement(InsertStatement e) { + void visitInsertStatement(InsertStatement e, void arg) { final table = _resolveTableReference(e.table); - visitChildren(e); + visitChildren(e, arg); e.scope.availableColumns = table.resolvedColumns; - visitChildren(e); + visitChildren(e, arg); } @override - void visitDeleteStatement(DeleteStatement e) { + void visitDeleteStatement(DeleteStatement e, void arg) { final table = _resolveTableReference(e.from); e.scope.availableColumns = table.resolvedColumns; - visitChildren(e); + visitChildren(e, arg); } void _handle(Queryable queryable, List availableColumns) { diff --git a/sqlparser/lib/src/analysis/steps/linting_visitor.dart b/sqlparser/lib/src/analysis/steps/linting_visitor.dart index 189bb9a9..257b1ac3 100644 --- a/sqlparser/lib/src/analysis/steps/linting_visitor.dart +++ b/sqlparser/lib/src/analysis/steps/linting_visitor.dart @@ -2,24 +2,19 @@ part of '../analysis.dart'; /// Visitor that runs after all other steps ran and reports more complex lints /// on an sql statement. -class LintingVisitor extends RecursiveVisitor { +class LintingVisitor extends RecursiveVisitor { final EngineOptions options; final AnalysisContext context; LintingVisitor(this.options, this.context); @override - void visitAggregateExpression(Invocation e) => _visitInvocation(e); - - @override - void visitFunction(Invocation e) => _visitInvocation(e); - - void _visitInvocation(Invocation e) { + void visitInvocation(SqlInvocation e, void arg) { final lowercaseCall = e.name.toLowerCase(); if (options.addedFunctions.containsKey(lowercaseCall)) { options.addedFunctions[lowercaseCall].reportErrors(e, context); } - visitChildren(e); + visitChildren(e, arg); } } diff --git a/sqlparser/lib/src/analysis/steps/prepare_ast.dart b/sqlparser/lib/src/analysis/steps/prepare_ast.dart index d193bc58..8c10e056 100644 --- a/sqlparser/lib/src/analysis/steps/prepare_ast.dart +++ b/sqlparser/lib/src/analysis/steps/prepare_ast.dart @@ -8,19 +8,19 @@ part of '../analysis.dart'; /// statement. /// - reports syntactic errors that aren't handled in the parser to keep that /// implementation simpler. -class AstPreparingVisitor extends RecursiveVisitor { +class AstPreparingVisitor extends RecursiveVisitor { final List _foundVariables = []; final AnalysisContext context; AstPreparingVisitor({this.context}); void start(AstNode root) { - root.accept(this); + root.accept(this, null); _resolveIndexOfVariables(); } @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 // 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 @@ -81,11 +81,11 @@ class AstPreparingVisitor extends RecursiveVisitor { } } - visitChildren(e); + visitChildren(e, arg); } @override - void visitResultColumn(ResultColumn e) { + void visitResultColumn(ResultColumn e, void arg) { if (e is StarResultColumn) { // doesn't need special treatment, star expressions can't be referenced } else if (e is ExpressionResultColumn) { @@ -93,11 +93,11 @@ class AstPreparingVisitor extends RecursiveVisitor { e.scope.register(e.as, e); } } - visitChildren(e); + visitChildren(e, arg); } @override - void visitQueryable(Queryable e) { + void visitQueryable(Queryable e, void arg) { final scope = e.scope; e.when( isTable: (table) { @@ -120,25 +120,25 @@ class AstPreparingVisitor extends RecursiveVisitor { }, ); - visitChildren(e); + visitChildren(e, arg); } @override - void visitCommonTableExpression(CommonTableExpression e) { + void visitCommonTableExpression(CommonTableExpression e, void arg) { e.scope.register(e.cteTableName, e); - visitChildren(e); + visitChildren(e, arg); } @override - void visitNumberedVariable(NumberedVariable e) { + void visitNumberedVariable(NumberedVariable e, void arg) { _foundVariables.add(e); - visitChildren(e); + visitChildren(e, arg); } @override - void visitNamedVariable(ColonNamedVariable e) { + void visitNamedVariable(ColonNamedVariable e, void arg) { _foundVariables.add(e); - visitChildren(e); + visitChildren(e, arg); } void _resolveIndexOfVariables() { @@ -179,12 +179,12 @@ class AstPreparingVisitor extends RecursiveVisitor { } @override - void visitChildren(AstNode e) { + void visitChildren(AstNode e, void arg) { // hack to fork scopes on statements (selects are handled above) if (e is Statement && e is! SelectStatement) { _forkScope(e); } - super.visitChildren(e); + super.visitChildren(e, arg); } } diff --git a/sqlparser/lib/src/analysis/steps/reference_resolver.dart b/sqlparser/lib/src/analysis/steps/reference_resolver.dart index 6a4a1e68..33dbc9bb 100644 --- a/sqlparser/lib/src/analysis/steps/reference_resolver.dart +++ b/sqlparser/lib/src/analysis/steps/reference_resolver.dart @@ -1,15 +1,15 @@ part of '../analysis.dart'; /// Resolves any open [Reference] it finds in the AST. -class ReferenceResolver extends RecursiveVisitor { +class ReferenceResolver extends RecursiveVisitor { final AnalysisContext context; ReferenceResolver(this.context); @override - void visitReference(Reference e) { + void visitReference(Reference e, void arg) { if (e.resolved != null) { - return super.visitReference(e); + return super.visitReference(e, arg); } final scope = e.scope; @@ -66,7 +66,7 @@ class ReferenceResolver extends RecursiveVisitor { } } - visitChildren(e); + visitChildren(e, arg); } void _reportUnknownColumnError(Reference e, {Iterable columns}) { @@ -101,12 +101,12 @@ class ReferenceResolver extends RecursiveVisitor { } @override - void visitAggregateExpression(AggregateExpression e) { + void visitAggregateExpression(AggregateExpression e, void arg) { if (e.windowName != null && e.resolved == null) { final resolved = e.scope.resolve(e.windowName); e.resolved = resolved; } - visitChildren(e); + visitChildren(e, arg); } } diff --git a/sqlparser/lib/src/analysis/steps/type_resolver.dart b/sqlparser/lib/src/analysis/steps/type_resolver.dart index 7fe887f4..ffd5f36a 100644 --- a/sqlparser/lib/src/analysis/steps/type_resolver.dart +++ b/sqlparser/lib/src/analysis/steps/type_resolver.dart @@ -3,14 +3,14 @@ part of '../analysis.dart'; /// 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 /// figure out what types they return. -class TypeResolvingVisitor extends RecursiveVisitor { +class TypeResolvingVisitor extends RecursiveVisitor { final AnalysisContext context; TypeResolver get types => context.types; TypeResolvingVisitor(this.context); @override - void visitChildren(AstNode e) { + void visitChildren(AstNode e, void arg) { // called for every ast node, so we implement this here if (e is Expression && !types.needsToBeInferred(e)) { types.resolveExpression(e); @@ -18,11 +18,11 @@ class TypeResolvingVisitor extends RecursiveVisitor { e.resolvedColumns.forEach(types.resolveColumn); } - super.visitChildren(e); + super.visitChildren(e, arg); } @override - void visitInsertStatement(InsertStatement e) { + void visitInsertStatement(InsertStatement e, void arg) { // resolve target columns - this is easy, as we should have the table // structure available. e.targetColumns.forEach(types.resolveExpression); @@ -43,10 +43,12 @@ class TypeResolvingVisitor extends RecursiveVisitor { } // we already handled the source tuples, don't visit them - visitChildren(e.table); - e.targetColumns.forEach(visitChildren); + visit(e.table, arg); + for (final column in e.targetColumns) { + visit(column, arg); + } } else { - visitChildren(e); + visitChildren(e, arg); } } } diff --git a/sqlparser/lib/src/analysis/types/resolver.dart b/sqlparser/lib/src/analysis/types/resolver.dart index f48783aa..65a1ac48 100644 --- a/sqlparser/lib/src/analysis/types/resolver.dart +++ b/sqlparser/lib/src/analysis/types/resolver.dart @@ -112,7 +112,7 @@ class TypeResolver { } else { return const ResolveResult.unknown(); } - } else if (expr is Invocation) { + } else if (expr is SqlInvocation) { return resolveFunctionCall(expr); } else if (expr is IsExpression || expr is InExpression || @@ -168,7 +168,7 @@ class TypeResolver { /// Returns the expanded parameters of a function [call]. When a /// [StarFunctionParameter] is used, it's expanded to the /// [ReferenceScope.availableColumns]. - List _expandParameters(Invocation call) { + List _expandParameters(SqlInvocation call) { final sqlParameters = call.parameters; if (sqlParameters is ExprFunctionParameters) { return sqlParameters.parameters; @@ -180,8 +180,8 @@ class TypeResolver { throw ArgumentError('Unknown parameters: $sqlParameters'); } - ResolveResult resolveFunctionCall(Invocation call) { - return _cache((Invocation call) { + ResolveResult resolveFunctionCall(SqlInvocation call) { + return _cache((SqlInvocation call) { final parameters = _expandParameters(call); final firstNullable = // ignore: avoid_bool_literals_in_conditional_expressions @@ -328,7 +328,7 @@ class TypeResolver { } ResolveResult _resolveFunctionArgument( - Invocation parent, Expression argument) { + SqlInvocation parent, Expression argument) { return _cache((argument) { final functionName = parent.name.toLowerCase(); final args = _expandParameters(parent); @@ -420,7 +420,7 @@ class TypeResolver { parent is Tuple || parent is UnaryExpression) { 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 // that. Otherwise, just assume that the argument has the same type as the // return type of the function diff --git a/sqlparser/lib/src/ast/ast.dart b/sqlparser/lib/src/ast/ast.dart index 0759ed2d..919ee270 100644 --- a/sqlparser/lib/src/ast/ast.dart +++ b/sqlparser/lib/src/ast/ast.dart @@ -33,6 +33,7 @@ part 'statements/insert.dart'; part 'statements/select.dart'; part 'statements/statement.dart'; part 'statements/update.dart'; +part 'visitor.dart'; /// A node in the abstract syntax tree of an SQL statement. 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 /// node. - T accept(AstVisitor visitor); + R accept(AstVisitor visitor, A arg); + + /// Like [accept], but without an argument. + /// + /// Null will be used for the argument instead. + R acceptWithoutArg(AstVisitor visitor) { + return accept(visitor, null); + } /// 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 @@ -144,209 +152,3 @@ abstract class AstNode with HasMetaMixin implements SyntacticEntity { return super.toString(); } } - -abstract class AstVisitor { - 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 extends AstVisitor { - @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; - } -} diff --git a/sqlparser/lib/src/ast/clauses/limit.dart b/sqlparser/lib/src/ast/clauses/limit.dart index b79fa1dd..7678aeff 100644 --- a/sqlparser/lib/src/ast/clauses/limit.dart +++ b/sqlparser/lib/src/ast/clauses/limit.dart @@ -13,8 +13,8 @@ class Limit extends AstNode implements LimitBase { Limit({this.count, this.offsetSeparator, this.offset}); @override - T accept(AstVisitor visitor) { - return visitor.visitLimit(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitLimit(this, arg); } @override diff --git a/sqlparser/lib/src/ast/clauses/ordering.dart b/sqlparser/lib/src/ast/clauses/ordering.dart index 92d4bac1..a8d84664 100644 --- a/sqlparser/lib/src/ast/clauses/ordering.dart +++ b/sqlparser/lib/src/ast/clauses/ordering.dart @@ -15,7 +15,9 @@ class OrderBy extends AstNode implements OrderByBase { OrderBy({this.terms}); @override - T accept(AstVisitor visitor) => visitor.visitOrderBy(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitOrderBy(this, arg); + } @override Iterable get childNodes => terms; @@ -38,7 +40,9 @@ class OrderingTerm extends AstNode implements OrderingTermBase { OrderingTerm({this.expression, this.orderingMode}); @override - T accept(AstVisitor visitor) => visitor.visitOrderingTerm(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitOrderingTerm(this, arg); + } @override Iterable get childNodes => [expression]; diff --git a/sqlparser/lib/src/ast/clauses/with.dart b/sqlparser/lib/src/ast/clauses/with.dart index 311eeca1..9b5b81ac 100644 --- a/sqlparser/lib/src/ast/clauses/with.dart +++ b/sqlparser/lib/src/ast/clauses/with.dart @@ -11,7 +11,9 @@ class WithClause extends AstNode { WithClause({@required this.recursive, @required this.ctes}); @override - T accept(AstVisitor visitor) => visitor.visitWithClause(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitWithClause(this, arg); + } @override Iterable get childNodes => ctes; @@ -38,8 +40,8 @@ class CommonTableExpression extends AstNode with ResultSet, VisibleToChildren { {@required this.cteTableName, this.columnNames, @required this.as}); @override - T accept(AstVisitor visitor) { - return visitor.visitCommonTableExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitCommonTableExpression(this, arg); } @override diff --git a/sqlparser/lib/src/ast/common/queryables.dart b/sqlparser/lib/src/ast/common/queryables.dart index f238d40e..931832b1 100644 --- a/sqlparser/lib/src/ast/common/queryables.dart +++ b/sqlparser/lib/src/ast/common/queryables.dart @@ -4,7 +4,9 @@ part of '../ast.dart'; /// statement. abstract class Queryable extends AstNode { @override - T accept(AstVisitor visitor) => visitor.visitQueryable(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitQueryable(this, arg); + } T when({ @required T Function(TableReference) isTable, @@ -145,7 +147,9 @@ class Join extends AstNode { } @override - T accept(AstVisitor visitor) => visitor.visitJoin(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitJoin(this, arg); + } } /// https://www.sqlite.org/syntax/join-constraint.html diff --git a/sqlparser/lib/src/ast/common/tuple.dart b/sqlparser/lib/src/ast/common/tuple.dart index 5732af9c..8e0bdd6d 100644 --- a/sqlparser/lib/src/ast/common/tuple.dart +++ b/sqlparser/lib/src/ast/common/tuple.dart @@ -12,7 +12,9 @@ class Tuple extends Expression { Tuple({@required this.expressions}); @override - T accept(AstVisitor visitor) => visitor.visitTuple(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitTuple(this, arg); + } @override Iterable get childNodes => expressions; diff --git a/sqlparser/lib/src/ast/expressions/aggregate.dart b/sqlparser/lib/src/ast/expressions/aggregate.dart index 4b74235e..a86a18fb 100644 --- a/sqlparser/lib/src/ast/expressions/aggregate.dart +++ b/sqlparser/lib/src/ast/expressions/aggregate.dart @@ -1,7 +1,7 @@ part of '../ast.dart'; class AggregateExpression extends Expression - implements Invocation, ReferenceOwner { + implements SqlInvocation, ReferenceOwner { final IdentifierToken function; @override @@ -42,7 +42,9 @@ class AggregateExpression extends Expression : assert((windowDefinition == null) != (windowName == null)); @override - T accept(AstVisitor visitor) => visitor.visitAggregateExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitAggregateExpression(this, arg); + } @override Iterable get childNodes { @@ -83,7 +85,9 @@ class WindowDefinition extends AstNode { @required this.frameSpec}); @override - T accept(AstVisitor visitor) => visitor.visitWindowDefinition(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitWindowDefinition(this, arg); + } @override Iterable get childNodes => @@ -109,7 +113,9 @@ class FrameSpec extends AstNode { }); @override - T accept(AstVisitor visitor) => visitor.visitFrameSpec(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitFrameSpec(this, arg); + } @override Iterable get childNodes => [ diff --git a/sqlparser/lib/src/ast/expressions/case.dart b/sqlparser/lib/src/ast/expressions/case.dart index b147fd60..80a7c689 100644 --- a/sqlparser/lib/src/ast/expressions/case.dart +++ b/sqlparser/lib/src/ast/expressions/case.dart @@ -8,7 +8,9 @@ class CaseExpression extends Expression { CaseExpression({this.base, @required this.whens, this.elseExpr}); @override - T accept(AstVisitor visitor) => visitor.visitCaseExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitCaseExpression(this, arg); + } @override Iterable get childNodes => @@ -25,7 +27,9 @@ class WhenComponent extends AstNode { WhenComponent({this.when, this.then}); @override - T accept(AstVisitor visitor) => visitor.visitWhen(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitWhen(this, arg); + } @override Iterable get childNodes => [when, then]; diff --git a/sqlparser/lib/src/ast/expressions/function.dart b/sqlparser/lib/src/ast/expressions/function.dart index d72e7719..7a5b6e64 100644 --- a/sqlparser/lib/src/ast/expressions/function.dart +++ b/sqlparser/lib/src/ast/expressions/function.dart @@ -2,9 +2,7 @@ part of '../ast.dart'; /// Interface for function calls, either a [FunctionExpression] or a /// [AggregateExpression]. -// todo: How does this not clash with Invocation from dart:core :O Anyway, we -// might want to consider renaming. -abstract class Invocation extends Expression { +abstract class SqlInvocation extends Expression { /// The name of the function being called String get name; @@ -13,7 +11,7 @@ abstract class Invocation extends Expression { class FunctionExpression extends Expression with ReferenceOwner - implements Invocation { + implements SqlInvocation { @override final String name; @override @@ -22,7 +20,9 @@ class FunctionExpression extends Expression FunctionExpression({@required this.name, @required this.parameters}); @override - T accept(AstVisitor visitor) => visitor.visitFunction(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitFunction(this, arg); + } @override Iterable get childNodes { diff --git a/sqlparser/lib/src/ast/expressions/literals.dart b/sqlparser/lib/src/ast/expressions/literals.dart index 983b53df..f0d74054 100644 --- a/sqlparser/lib/src/ast/expressions/literals.dart +++ b/sqlparser/lib/src/ast/expressions/literals.dart @@ -7,7 +7,9 @@ abstract class Literal extends Expression { Literal(this.token); @override - T accept(AstVisitor visitor) => visitor.visitLiteral(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitLiteral(this, arg); + } @override final Iterable childNodes = const []; diff --git a/sqlparser/lib/src/ast/expressions/reference.dart b/sqlparser/lib/src/ast/expressions/reference.dart index 66b94d73..ddf1beee 100644 --- a/sqlparser/lib/src/ast/expressions/reference.dart +++ b/sqlparser/lib/src/ast/expressions/reference.dart @@ -16,7 +16,9 @@ class Reference extends Expression with ReferenceOwner { Reference({this.tableName, this.columnName}); @override - T accept(AstVisitor visitor) => visitor.visitReference(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitReference(this, arg); + } @override Iterable get childNodes => const []; diff --git a/sqlparser/lib/src/ast/expressions/simple.dart b/sqlparser/lib/src/ast/expressions/simple.dart index 2e73685e..1c140426 100644 --- a/sqlparser/lib/src/ast/expressions/simple.dart +++ b/sqlparser/lib/src/ast/expressions/simple.dart @@ -7,7 +7,9 @@ class UnaryExpression extends Expression { UnaryExpression(this.operator, this.inner); @override - T accept(AstVisitor visitor) => visitor.visitUnaryExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitUnaryExpression(this, arg); + } @override Iterable get childNodes => [inner]; @@ -42,7 +44,9 @@ class BinaryExpression extends Expression { BinaryExpression(this.left, this.operator, this.right); @override - T accept(AstVisitor visitor) => visitor.visitBinaryExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitBinaryExpression(this, arg); + } @override Iterable get childNodes => [left, right]; @@ -68,7 +72,9 @@ class StringComparisonExpression extends Expression { this.escape}); @override - T accept(AstVisitor visitor) => visitor.visitStringComparison(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitStringComparison(this, arg); + } @override Iterable get childNodes => [left, right, if (escape != null) escape]; @@ -86,8 +92,8 @@ class IsExpression extends Expression { IsExpression(this.negated, this.left, this.right); @override - T accept(AstVisitor visitor) { - return visitor.visitIsExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitIsExpression(this, arg); } @override @@ -109,7 +115,9 @@ class BetweenExpression extends Expression { BetweenExpression({this.not = false, this.check, this.lower, this.upper}); @override - T accept(AstVisitor visitor) => visitor.visitBetweenExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitBetweenExpression(this, arg); + } @override Iterable get childNodes => [check, lower, upper]; @@ -133,7 +141,9 @@ class InExpression extends Expression { : assert(inside is Tuple || inside is Variable || inside is SubQuery); @override - T accept(AstVisitor visitor) => visitor.visitInExpression(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitInExpression(this, arg); + } @override Iterable get childNodes => [left, inside]; @@ -155,8 +165,8 @@ class Parentheses extends Expression { } @override - T accept(AstVisitor visitor) { - return expression.accept(visitor); + R accept(AstVisitor visitor, A arg) { + return expression.accept(visitor, arg); } @override diff --git a/sqlparser/lib/src/ast/expressions/subquery.dart b/sqlparser/lib/src/ast/expressions/subquery.dart index ff2baccc..2b235994 100644 --- a/sqlparser/lib/src/ast/expressions/subquery.dart +++ b/sqlparser/lib/src/ast/expressions/subquery.dart @@ -8,7 +8,9 @@ class SubQuery extends Expression { SubQuery({this.select}); @override - T accept(AstVisitor visitor) => visitor.visitSubQuery(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitSubQuery(this, arg); + } @override Iterable get childNodes => [select]; @@ -23,7 +25,9 @@ class ExistsExpression extends Expression { ExistsExpression({@required this.select}); @override - T accept(AstVisitor visitor) => visitor.visitExists(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitExists(this, arg); + } @override Iterable get childNodes => [select]; diff --git a/sqlparser/lib/src/ast/expressions/variables.dart b/sqlparser/lib/src/ast/expressions/variables.dart index 67713a33..e2a02fd0 100644 --- a/sqlparser/lib/src/ast/expressions/variables.dart +++ b/sqlparser/lib/src/ast/expressions/variables.dart @@ -14,8 +14,8 @@ class NumberedVariable extends Expression with Variable { } @override - T accept(AstVisitor visitor) { - return visitor.visitNumberedVariable(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitNumberedVariable(this, arg); } @override @@ -34,8 +34,8 @@ class ColonNamedVariable extends Expression with Variable { ColonNamedVariable(this.token); @override - T accept(AstVisitor visitor) { - return visitor.visitNamedVariable(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitNamedVariable(this, arg); } @override diff --git a/sqlparser/lib/src/ast/moor/declared_statement.dart b/sqlparser/lib/src/ast/moor/declared_statement.dart index 690c1834..60572399 100644 --- a/sqlparser/lib/src/ast/moor/declared_statement.dart +++ b/sqlparser/lib/src/ast/moor/declared_statement.dart @@ -17,8 +17,9 @@ class DeclaredStatement extends Statement implements PartOfMoorFile { DeclaredStatement(this.identifier, this.statement, {this.parameters}); @override - T accept(AstVisitor visitor) => - visitor.visitMoorDeclaredStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitMoorDeclaredStatement(this, arg); + } @override Iterable get childNodes => @@ -85,8 +86,8 @@ class SpecialStatementIdentifier extends DeclaredStatementIdentifier { /// In `selectString(:name AS TEXT): SELECT :name`, `:name AS TEXT` is a abstract class StatementParameter extends AstNode { @override - T accept(AstVisitor visitor) { - return visitor.visitMoorStatementParameter(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitMoorStatementParameter(this, arg); } } diff --git a/sqlparser/lib/src/ast/moor/import_statement.dart b/sqlparser/lib/src/ast/moor/import_statement.dart index bdbfc8d8..b7553404 100644 --- a/sqlparser/lib/src/ast/moor/import_statement.dart +++ b/sqlparser/lib/src/ast/moor/import_statement.dart @@ -9,7 +9,9 @@ class ImportStatement extends Statement implements PartOfMoorFile { ImportStatement(this.importedFile); @override - T accept(AstVisitor visitor) => visitor.visitMoorImportStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitMoorImportStatement(this, arg); + } @override final Iterable childNodes = const []; diff --git a/sqlparser/lib/src/ast/moor/inline_dart.dart b/sqlparser/lib/src/ast/moor/inline_dart.dart index 031249ef..ad2f638c 100644 --- a/sqlparser/lib/src/ast/moor/inline_dart.dart +++ b/sqlparser/lib/src/ast/moor/inline_dart.dart @@ -24,7 +24,9 @@ abstract class DartPlaceholder extends AstNode { final Iterable childNodes = const Iterable.empty(); @override - T accept(AstVisitor visitor) => visitor.visitDartPlaceholder(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitDartPlaceholder(this, arg); + } bool _dartEquals(covariant DartPlaceholder other) => true; diff --git a/sqlparser/lib/src/ast/moor/moor_file.dart b/sqlparser/lib/src/ast/moor/moor_file.dart index 30005bef..07ab465f 100644 --- a/sqlparser/lib/src/ast/moor/moor_file.dart +++ b/sqlparser/lib/src/ast/moor/moor_file.dart @@ -13,7 +13,9 @@ class MoorFile extends AstNode { MoorFile(this.statements); @override - T accept(AstVisitor visitor) => visitor.visitMoorFile(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitMoorFile(this, arg); + } @override Iterable get childNodes => statements; diff --git a/sqlparser/lib/src/ast/schema/column_definition.dart b/sqlparser/lib/src/ast/schema/column_definition.dart index 2f68aa93..7464f658 100644 --- a/sqlparser/lib/src/ast/schema/column_definition.dart +++ b/sqlparser/lib/src/ast/schema/column_definition.dart @@ -16,7 +16,9 @@ class ColumnDefinition extends AstNode { this.constraints = const []}); @override - T accept(AstVisitor visitor) => visitor.visitColumnDefinition(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitColumnDefinition(this, arg); + } @override Iterable get childNodes => constraints; @@ -43,7 +45,9 @@ abstract class ColumnConstraint extends AstNode { ColumnConstraint(this.name); @override - T accept(AstVisitor visitor) => visitor.visitColumnConstraint(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitColumnConstraint(this, arg); + } T when({ T Function(NotNull) notNull, diff --git a/sqlparser/lib/src/ast/schema/table_definition.dart b/sqlparser/lib/src/ast/schema/table_definition.dart index 2d98a02b..79fed89a 100644 --- a/sqlparser/lib/src/ast/schema/table_definition.dart +++ b/sqlparser/lib/src/ast/schema/table_definition.dart @@ -15,7 +15,9 @@ class ForeignKeyClause extends AstNode { this.onUpdate}); @override - T accept(AstVisitor visitor) => visitor.visitForeignKeyClause(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitForeignKeyClause(this, arg); + } @override Iterable get childNodes => [foreignTable, ...columnNames]; @@ -32,7 +34,9 @@ abstract class TableConstraint extends AstNode { TableConstraint(this.name); @override - T accept(AstVisitor visitor) => visitor.visitTableConstraint(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitTableConstraint(this, arg); + } @override bool contentEquals(TableConstraint other) { diff --git a/sqlparser/lib/src/ast/statements/create_table.dart b/sqlparser/lib/src/ast/statements/create_table.dart index 19e3e1d2..8fa6a708 100644 --- a/sqlparser/lib/src/ast/statements/create_table.dart +++ b/sqlparser/lib/src/ast/statements/create_table.dart @@ -36,7 +36,9 @@ class CreateTableStatement extends TableInducingStatement { : super._(ifNotExists, tableName, overriddenDataClassName); @override - T accept(AstVisitor visitor) => visitor.visitCreateTableStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitCreateTableStatement(this, arg); + } @override Iterable get childNodes => [...columns, ...tableConstraints]; @@ -73,8 +75,9 @@ class CreateVirtualTableStatement extends TableInducingStatement { }) : super._(ifNotExists, tableName, overriddenDataClassName); @override - T accept(AstVisitor visitor) => - visitor.visitCreateVirtualTableStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitCreateVirtualTableStatement(this, arg); + } @override Iterable get childNodes => const []; diff --git a/sqlparser/lib/src/ast/statements/delete.dart b/sqlparser/lib/src/ast/statements/delete.dart index 4f1c3e05..9135932d 100644 --- a/sqlparser/lib/src/ast/statements/delete.dart +++ b/sqlparser/lib/src/ast/statements/delete.dart @@ -9,7 +9,9 @@ class DeleteStatement extends CrudStatement implements HasWhereClause { : super._(withClause); @override - T accept(AstVisitor visitor) => visitor.visitDeleteStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitDeleteStatement(this, arg); + } @override Iterable get childNodes => [ diff --git a/sqlparser/lib/src/ast/statements/insert.dart b/sqlparser/lib/src/ast/statements/insert.dart index 693d126d..0b205bdf 100644 --- a/sqlparser/lib/src/ast/statements/insert.dart +++ b/sqlparser/lib/src/ast/statements/insert.dart @@ -36,7 +36,9 @@ class InsertStatement extends CrudStatement { : super._(withClause); @override - T accept(AstVisitor visitor) => visitor.visitInsertStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitInsertStatement(this, arg); + } @override Iterable get childNodes sync* { diff --git a/sqlparser/lib/src/ast/statements/select.dart b/sqlparser/lib/src/ast/statements/select.dart index 6df707cc..de0ac6d7 100644 --- a/sqlparser/lib/src/ast/statements/select.dart +++ b/sqlparser/lib/src/ast/statements/select.dart @@ -35,8 +35,8 @@ class SelectStatement extends BaseSelectStatement implements HasWhereClause { : super._(withClause); @override - T accept(AstVisitor visitor) { - return visitor.visitSelectStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitSelectStatement(this, arg); } @override @@ -79,8 +79,8 @@ class CompoundSelectStatement extends BaseSelectStatement { } @override - T accept(AstVisitor visitor) { - return visitor.visitCompoundSelectStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitCompoundSelectStatement(this, arg); } @override @@ -92,7 +92,9 @@ class CompoundSelectStatement extends BaseSelectStatement { abstract class ResultColumn extends AstNode { @override - T accept(AstVisitor visitor) => visitor.visitResultColumn(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitResultColumn(this, arg); + } } /// 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}); @override - T accept(AstVisitor visitor) => visitor.visitGroupBy(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitGroupBy(this, arg); + } @override Iterable get childNodes => [...by, if (having != null) having]; @@ -170,7 +174,9 @@ class CompoundSelectPart extends AstNode { Iterable get childNodes => [select]; @override - T accept(AstVisitor visitor) => visitor.visitCompoundSelectPart(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitCompoundSelectPart(this, arg); + } @override bool contentEquals(CompoundSelectPart other) => mode == other.mode; diff --git a/sqlparser/lib/src/ast/statements/update.dart b/sqlparser/lib/src/ast/statements/update.dart index 6c9dc048..04f138f5 100644 --- a/sqlparser/lib/src/ast/statements/update.dart +++ b/sqlparser/lib/src/ast/statements/update.dart @@ -32,7 +32,9 @@ class UpdateStatement extends CrudStatement implements HasWhereClause { : super._(withClause); @override - T accept(AstVisitor visitor) => visitor.visitUpdateStatement(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitUpdateStatement(this, arg); + } @override Iterable get childNodes => [ @@ -59,7 +61,9 @@ class SetComponent extends AstNode { SetComponent({@required this.column, @required this.expression}); @override - T accept(AstVisitor visitor) => visitor.visitSetComponent(this); + R accept(AstVisitor visitor, A arg) { + return visitor.visitSetComponent(this, arg); + } @override Iterable get childNodes => [column, expression]; diff --git a/sqlparser/lib/src/ast/visitor.dart b/sqlparser/lib/src/ast/visitor.dart new file mode 100644 index 00000000..b6c80fbb --- /dev/null +++ b/sqlparser/lib/src/ast/visitor.dart @@ -0,0 +1,340 @@ +part of 'ast.dart'; + +abstract class AstVisitor { + 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 implements AstVisitor { + // 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; + } +} diff --git a/sqlparser/lib/src/engine/module/fts5.dart b/sqlparser/lib/src/engine/module/fts5.dart index d9477a97..8d03e93a 100644 --- a/sqlparser/lib/src/engine/module/fts5.dart +++ b/sqlparser/lib/src/engine/module/fts5.dart @@ -61,7 +61,7 @@ class _Fts5Functions implements FunctionHandler { @override ResolveResult inferArgumentType( - TypeResolver resolver, Invocation call, Expression argument) { + TypeResolver resolver, SqlInvocation call, Expression argument) { int argumentIndex; if (call.parameters is ExprFunctionParameters) { argumentIndex = (call.parameters as ExprFunctionParameters) @@ -100,7 +100,7 @@ class _Fts5Functions implements FunctionHandler { @override ResolveResult inferReturnType( - TypeResolver resolver, Invocation call, List expandedArgs) { + TypeResolver resolver, SqlInvocation call, List expandedArgs) { switch (call.name) { case 'bm25': return const ResolveResult(ResolvedType(type: BasicType.real)); @@ -113,7 +113,7 @@ class _Fts5Functions implements FunctionHandler { } @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 if (call.parameters is StarFunctionParameter) { context.reportError(AnalysisError( diff --git a/sqlparser/lib/src/engine/module/module.dart b/sqlparser/lib/src/engine/module/module.dart index 6edd198f..4689d6da 100644 --- a/sqlparser/lib/src/engine/module/module.dart +++ b/sqlparser/lib/src/engine/module/module.dart @@ -26,7 +26,7 @@ abstract class FunctionHandler { /// If resolving to a type isn't possible, implementations should return /// [ResolveResult.unknown]. ResolveResult inferReturnType( - TypeResolver resolver, Invocation call, List expandedArgs); + TypeResolver resolver, SqlInvocation call, List expandedArgs); /// 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 /// [ResolveResult.unknown]. ResolveResult inferArgumentType( - TypeResolver resolver, Invocation call, Expression argument); + TypeResolver resolver, SqlInvocation call, Expression argument); /// Can optionally be used by implementations to provide [AnalysisError]s /// from the [call]. /// /// 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 diff --git a/sqlparser/lib/src/engine/sql_engine.dart b/sqlparser/lib/src/engine/sql_engine.dart index a41d99d4..a7c0aba2 100644 --- a/sqlparser/lib/src/engine/sql_engine.dart +++ b/sqlparser/lib/src/engine/sql_engine.dart @@ -184,10 +184,10 @@ class SqlEngine { if (node is CrudStatement) { node - ..accept(ColumnResolver(context)) - ..accept(ReferenceResolver(context)) - ..accept(TypeResolvingVisitor(context)) - ..accept(LintingVisitor(options, context)); + ..acceptWithoutArg(ColumnResolver(context)) + ..acceptWithoutArg(ReferenceResolver(context)) + ..acceptWithoutArg(TypeResolvingVisitor(context)) + ..acceptWithoutArg(LintingVisitor(options, context)); } } catch (_) { rethrow;