mirror of https://github.com/AMT-Cheif/drift.git
Fix error recovery on early finished statements #453
This commit is contained in:
parent
5d6fcec438
commit
d533a0a254
|
@ -376,20 +376,27 @@ class Parser extends ParserBase
|
||||||
T result;
|
T result;
|
||||||
try {
|
try {
|
||||||
result = parser();
|
result = parser();
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
result.semicolon = _consume(TokenType.semicolon,
|
||||||
|
'Expected a semicolon after the statement ended');
|
||||||
|
result.setSpan(first, _previous);
|
||||||
|
}
|
||||||
} on ParsingError {
|
} on ParsingError {
|
||||||
_lastStmtHadParsingError = true;
|
_lastStmtHadParsingError = true;
|
||||||
// the error is added to the list errors, so ignore. We skip after the
|
// the error is added to the list errors, so ignore. We skip after the
|
||||||
// next semicolon to parse the next statement.
|
// next semicolon to parse the next statement.
|
||||||
_synchronize(TokenType.semicolon, skipTarget: true);
|
_synchronize(TokenType.semicolon, skipTarget: true);
|
||||||
|
|
||||||
|
if (result == null) return null;
|
||||||
|
|
||||||
|
if (_matchOne(TokenType.semicolon)) {
|
||||||
|
result.semicolon = _previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.setSpan(first, _previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null) return null;
|
|
||||||
|
|
||||||
if (_matchOne(TokenType.semicolon)) {
|
|
||||||
result.semicolon = _previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.setSpan(first, _previous);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ CREATE TABLE tbl (
|
||||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
-- this is a single-line comment
|
-- this is a single-line comment
|
||||||
place VARCHAR REFERENCES other(location)
|
place VARCHAR REFERENCES other(location)
|
||||||
) AS RowName
|
) AS RowName;
|
||||||
|
|
||||||
all: SELECT /* COUNT(*), */ * FROM tbl WHERE $predicate;
|
all: SELECT /* COUNT(*), */ * FROM tbl WHERE $predicate;
|
||||||
@special: SELECT * FROM tbl;
|
@special: SELECT * FROM tbl;
|
||||||
|
@ -111,4 +111,19 @@ void main() {
|
||||||
isNot(contains(const TypeMatcher<DeclaredStatement>())),
|
isNot(contains(const TypeMatcher<DeclaredStatement>())),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('syntax errors contain correct position', () {
|
||||||
|
final engine = SqlEngine(EngineOptions(useMoorExtensions: true));
|
||||||
|
final result = engine.parseMoorFile('''
|
||||||
|
worksByComposer:
|
||||||
|
SELECT DISTINCT A.* FROM works A, works B ON A.id = B.part_of
|
||||||
|
WHERE A.composer = :id OR B.composer = :id;
|
||||||
|
''');
|
||||||
|
|
||||||
|
expect(result.errors, hasLength(1));
|
||||||
|
expect(
|
||||||
|
result.errors.single,
|
||||||
|
isA<ParsingError>()
|
||||||
|
.having((e) => e.token.lexeme, 'token.lexeme', 'ON'));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue