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();
}
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;
_ReferenceResolvingVisitor(this.handler);
@override
void visitForeignKeyClause(ForeignKeyClause clause) {
void visitForeignKeyClause(ForeignKeyClause clause, void arg) {
final stmt = clause.parents.whereType<CreateTableStatement>().first;
final referencedTable = handler.availableTables.singleWhere(
(t) => t.sqlName == clause.foreignTable.tableName,
@ -47,6 +48,6 @@ class _ReferenceResolvingVisitor extends RecursiveVisitor<void> {
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
/// them.
class ReferencedTablesVisitor extends RecursiveVisitor<void> {
class ReferencedTablesVisitor extends RecursiveVisitor<void, void> {
/// All tables that have been referenced anywhere in this query.
final Set<Table> 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<void> {
}
}
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);
}
}

View File

@ -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<void> {
class _LintingVisitor extends RecursiveVisitor<void, void> {
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<void> {
}
@override
void visitInsertStatement(InsertStatement e) {
void visitInsertStatement(InsertStatement e, void arg) {
final targeted = e.resolvedTargetColumns;
if (targeted == null) return;

View File

@ -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();

View File

@ -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<void> {
class _FoldingVisitor extends RecursiveVisitor<void, void> {
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<void> {
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;

View File

@ -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<void> {
class _HighlightingVisitor extends RecursiveVisitor<void, void> {
final HighlightsCollector collector;
_HighlightingVisitor(this.collector);
@ -55,41 +55,32 @@ class _HighlightingVisitor extends RecursiveVisitor<void> {
}
@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<void> {
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<void> {
_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) {

View File

@ -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<void> {
class _NavigationVisitor extends RecursiveVisitor<void, void> {
final MoorRequestAtPosition request;
final NavigationCollector collector;
@ -41,7 +41,7 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
}
@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<void> {
}
}
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<void> {
}
}
visitChildren(e);
visitChildren(e, arg);
}
Iterable<Location> _locationOfColumn(Column column) sync* {
@ -96,7 +96,7 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
}
@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<void> {
}
}
visitChildren(e);
visitChildren(e, arg);
}
}

View File

@ -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<void> {
class _OutlineVisitor extends RecursiveVisitor<void, void> {
final MoorRequest request;
final OutlineCollector collector;
@ -40,33 +40,33 @@ class _OutlineVisitor extends RecursiveVisitor<void> {
}
@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<void> {
element.parameters = parameterBuilder.toString();
}
super.visitChildren(e);
super.visitChildren(e, arg);
collector.endElement();
}
}

View File

@ -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

View File

@ -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<void> {
class ColumnResolver extends RecursiveVisitor<void, void> {
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<void> {
}
@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<void> {
}
@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<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
/// on an sql statement.
class LintingVisitor extends RecursiveVisitor<void> {
class LintingVisitor extends RecursiveVisitor<void, void> {
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);
}
}

View File

@ -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<void> {
class AstPreparingVisitor extends RecursiveVisitor<void, void> {
final List<Variable> _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<void> {
}
}
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<void> {
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<void> {
},
);
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<void> {
}
@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);
}
}

View File

@ -1,15 +1,15 @@
part of '../analysis.dart';
/// Resolves any open [Reference] it finds in the AST.
class ReferenceResolver extends RecursiveVisitor<void> {
class ReferenceResolver extends RecursiveVisitor<void, void> {
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<void> {
}
}
visitChildren(e);
visitChildren(e, arg);
}
void _reportUnknownColumnError(Reference e, {Iterable<Column> columns}) {
@ -101,12 +101,12 @@ class ReferenceResolver extends RecursiveVisitor<void> {
}
@override
void visitAggregateExpression(AggregateExpression e) {
void visitAggregateExpression(AggregateExpression e, void arg) {
if (e.windowName != null && e.resolved == null) {
final resolved = e.scope.resolve<NamedWindowDeclaration>(e.windowName);
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
/// expressions, variables and so on. For select statements, we also try to
/// figure out what types they return.
class TypeResolvingVisitor extends RecursiveVisitor<void> {
class TypeResolvingVisitor extends RecursiveVisitor<void, void> {
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<void> {
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<void> {
}
// 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);
}
}
}

View File

@ -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<Typeable> _expandParameters(Invocation call) {
List<Typeable> _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<Expression>((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

View File

@ -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<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
/// 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> {
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});
@override
T accept<T>(AstVisitor<T> visitor) {
return visitor.visitLimit(this);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitLimit(this, arg);
}
@override

View File

@ -15,7 +15,9 @@ class OrderBy extends AstNode implements OrderByBase {
OrderBy({this.terms});
@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
Iterable<AstNode> get childNodes => terms;
@ -38,7 +40,9 @@ class OrderingTerm extends AstNode implements OrderingTermBase {
OrderingTerm({this.expression, this.orderingMode});
@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
Iterable<AstNode> get childNodes => [expression];

View File

@ -11,7 +11,9 @@ class WithClause extends AstNode {
WithClause({@required this.recursive, @required this.ctes});
@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
Iterable<AstNode> 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<T>(AstVisitor<T> visitor) {
return visitor.visitCommonTableExpression(this);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitCommonTableExpression(this, arg);
}
@override

View File

@ -4,7 +4,9 @@ part of '../ast.dart';
/// statement.
abstract class Queryable extends AstNode {
@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>({
@required T Function(TableReference) isTable,
@ -145,7 +147,9 @@ class Join extends AstNode {
}
@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

View File

@ -12,7 +12,9 @@ class Tuple extends Expression {
Tuple({@required this.expressions});
@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
Iterable<AstNode> get childNodes => expressions;

View File

@ -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<T>(AstVisitor<T> visitor) => visitor.visitAggregateExpression(this);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitAggregateExpression(this, arg);
}
@override
Iterable<AstNode> get childNodes {
@ -83,7 +85,9 @@ class WindowDefinition extends AstNode {
@required this.frameSpec});
@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
Iterable<AstNode> get childNodes =>
@ -109,7 +113,9 @@ class FrameSpec extends AstNode {
});
@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
Iterable<AstNode> get childNodes => [

View File

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

View File

@ -7,7 +7,9 @@ abstract class Literal extends Expression {
Literal(this.token);
@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
final Iterable<AstNode> childNodes = const <AstNode>[];

View File

@ -16,7 +16,9 @@ class Reference extends Expression with ReferenceOwner {
Reference({this.tableName, this.columnName});
@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
Iterable<AstNode> get childNodes => const [];

View File

@ -7,7 +7,9 @@ class UnaryExpression extends Expression {
UnaryExpression(this.operator, this.inner);
@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
Iterable<AstNode> get childNodes => [inner];
@ -42,7 +44,9 @@ class BinaryExpression extends Expression {
BinaryExpression(this.left, this.operator, this.right);
@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
Iterable<AstNode> get childNodes => [left, right];
@ -68,7 +72,9 @@ class StringComparisonExpression extends Expression {
this.escape});
@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
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);
@override
T accept<T>(AstVisitor<T> visitor) {
return visitor.visitIsExpression(this);
R accept<A, R>(AstVisitor<A, R> 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<T>(AstVisitor<T> visitor) => visitor.visitBetweenExpression(this);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitBetweenExpression(this, arg);
}
@override
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);
@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
Iterable<AstNode> get childNodes => [left, inside];
@ -155,8 +165,8 @@ class Parentheses extends Expression {
}
@override
T accept<T>(AstVisitor<T> visitor) {
return expression.accept(visitor);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return expression.accept(visitor, arg);
}
@override

View File

@ -8,7 +8,9 @@ class SubQuery extends Expression {
SubQuery({this.select});
@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
Iterable<AstNode> get childNodes => [select];
@ -23,7 +25,9 @@ class ExistsExpression extends Expression {
ExistsExpression({@required this.select});
@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
Iterable<AstNode> get childNodes => [select];

View File

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

View File

@ -17,8 +17,9 @@ class DeclaredStatement extends Statement implements PartOfMoorFile {
DeclaredStatement(this.identifier, this.statement, {this.parameters});
@override
T accept<T>(AstVisitor<T> visitor) =>
visitor.visitMoorDeclaredStatement(this);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitMoorDeclaredStatement(this, arg);
}
@override
Iterable<AstNode> 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<T>(AstVisitor<T> visitor) {
return visitor.visitMoorStatementParameter(this);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitMoorStatementParameter(this, arg);
}
}

View File

@ -9,7 +9,9 @@ class ImportStatement extends Statement implements PartOfMoorFile {
ImportStatement(this.importedFile);
@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
final Iterable<AstNode> childNodes = const [];

View File

@ -24,7 +24,9 @@ abstract class DartPlaceholder extends AstNode {
final Iterable<AstNode> childNodes = const Iterable.empty();
@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;

View File

@ -13,7 +13,9 @@ class MoorFile extends AstNode {
MoorFile(this.statements);
@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
Iterable<AstNode> get childNodes => statements;

View File

@ -16,7 +16,9 @@ class ColumnDefinition extends AstNode {
this.constraints = const []});
@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
Iterable<AstNode> get childNodes => constraints;
@ -43,7 +45,9 @@ abstract class ColumnConstraint extends AstNode {
ColumnConstraint(this.name);
@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 Function(NotNull) notNull,

View File

@ -15,7 +15,9 @@ class ForeignKeyClause extends AstNode {
this.onUpdate});
@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
Iterable<AstNode> get childNodes => [foreignTable, ...columnNames];
@ -32,7 +34,9 @@ abstract class TableConstraint extends AstNode {
TableConstraint(this.name);
@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
bool contentEquals(TableConstraint other) {

View File

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

View File

@ -9,7 +9,9 @@ class DeleteStatement extends CrudStatement implements HasWhereClause {
: super._(withClause);
@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
Iterable<AstNode> get childNodes => [

View File

@ -36,7 +36,9 @@ class InsertStatement extends CrudStatement {
: super._(withClause);
@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
Iterable<AstNode> get childNodes sync* {

View File

@ -35,8 +35,8 @@ class SelectStatement extends BaseSelectStatement implements HasWhereClause {
: super._(withClause);
@override
T accept<T>(AstVisitor<T> visitor) {
return visitor.visitSelectStatement(this);
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
return visitor.visitSelectStatement(this, arg);
}
@override
@ -79,8 +79,8 @@ class CompoundSelectStatement extends BaseSelectStatement {
}
@override
T accept<T>(AstVisitor<T> visitor) {
return visitor.visitCompoundSelectStatement(this);
R accept<A, R>(AstVisitor<A, R> 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<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
@ -136,7 +138,9 @@ class GroupBy extends AstNode {
GroupBy({@required this.by, this.having});
@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
Iterable<AstNode> get childNodes => [...by, if (having != null) having];
@ -170,7 +174,9 @@ class CompoundSelectPart extends AstNode {
Iterable<AstNode> get childNodes => [select];
@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
bool contentEquals(CompoundSelectPart other) => mode == other.mode;

View File

@ -32,7 +32,9 @@ class UpdateStatement extends CrudStatement implements HasWhereClause {
: super._(withClause);
@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
Iterable<AstNode> get childNodes => [
@ -59,7 +61,9 @@ class SetComponent extends AstNode {
SetComponent({@required this.column, @required this.expression});
@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
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
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<Typeable> expandedArgs) {
TypeResolver resolver, SqlInvocation call, List<Typeable> 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(

View File

@ -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<Typeable> expandedArgs);
TypeResolver resolver, SqlInvocation call, List<Typeable> 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

View File

@ -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;