Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(605)

Unified Diff: pkg/front_end/test/scanner_fasta_test.dart

Issue 2912693002: improve fasta unterminated string recovery (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/front_end/test/scanner_fasta_test.dart
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index f6b8cc1cacb3ff7144907705bfae43abdc31e21a..61848f26b2fa8b746f001b84aa68f6eb590d23ab 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -241,13 +241,6 @@ main() {}
@override
@failingTest
- void test_string_multi_unterminated() {
- // TODO(paulberry,ahe): bad error recovery.
- super.test_string_multi_unterminated();
- }
-
- @override
- @failingTest
void test_string_multi_unterminated_interpolation_block() {
// TODO(paulberry,ahe): bad error recovery.
super.test_string_multi_unterminated_interpolation_block();
@@ -262,41 +255,6 @@ main() {}
@override
@failingTest
- void test_string_raw_multi_unterminated() {
- // TODO(paulberry,ahe): bad error recovery.
- super.test_string_raw_multi_unterminated();
- }
-
- @override
- @failingTest
- void test_string_raw_simple_unterminated_eof() {
- // TODO(paulberry,ahe): bad error recovery.
- super.test_string_raw_simple_unterminated_eof();
- }
-
- @override
- @failingTest
- void test_string_raw_simple_unterminated_eol() {
- // TODO(paulberry,ahe): bad error recovery.
- super.test_string_raw_simple_unterminated_eol();
- }
-
- @override
- @failingTest
- void test_string_simple_unterminated_eof() {
- // TODO(paulberry,ahe): bad error recovery.
- super.test_string_simple_unterminated_eof();
- }
-
- @override
- @failingTest
- void test_string_simple_unterminated_eol() {
- // TODO(paulberry,ahe): bad error recovery.
- super.test_string_simple_unterminated_eol();
- }
-
- @override
- @failingTest
void test_string_simple_unterminated_interpolation_block() {
// TODO(paulberry,ahe): bad error recovery.
super.test_string_simple_unterminated_interpolation_block();
@@ -339,6 +297,120 @@ main() {}
abstract class ScannerTest_Fasta_Base {
Token scan(String source);
+ expectToken(Token token, TokenType type, int offset, int length,
+ {bool isSynthetic: false, String lexeme}) {
+ String description = '${token.type} $token';
+ expect(token.type, type, reason: description);
+ expect(token.offset, offset, reason: description);
+ expect(token.length, length, reason: description);
+ expect(token.isSynthetic, isSynthetic, reason: description);
+ if (lexeme != null) {
+ expect(token.lexeme, lexeme, reason: description);
+ }
+ }
+
+ void test_incomplete_string_interpolation() {
+ Token token = scan(r'"foo ${bar');
+ expectToken(token, TokenType.STRING, 0, 5, lexeme: '"foo ');
+
+ token = token.next;
+ expectToken(token, TokenType.STRING_INTERPOLATION_EXPRESSION, 5, 2);
+ BeginToken interpolationStart = token;
+
+ token = token.next;
+ expectToken(token, TokenType.IDENTIFIER, 7, 3, lexeme: 'bar');
+
+ // Expect interpolation to be terminated before string is closed
+ token = token.next;
+ expectToken(token, TokenType.CLOSE_CURLY_BRACKET, 10, 0,
+ isSynthetic: true, lexeme: '}');
+ expect(interpolationStart.endToken, same(token));
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
+ expect((token as fasta.UnmatchedToken).begin, same(interpolationStart));
+
+ token = token.next;
+ expectToken(token, TokenType.STRING, 10, 0, isSynthetic: true, lexeme: '"');
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
+ }
+
+ void test_string_multi_unterminated() {
+ Token token = scan("'''string");
+ expectToken(token, TokenType.STRING, 0, 9, lexeme: "'''string");
+
+ token = token.next;
+ expectToken(token, TokenType.STRING, 9, 0,
+ isSynthetic: true, lexeme: "'''");
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
+ expect((token as fasta.ErrorToken).start, "'''");
+ }
+
+ void test_string_raw_multi_unterminated() {
+ Token token = scan("r'''string");
+ expectToken(token, TokenType.STRING, 0, 10, lexeme: "r'''string");
+
+ token = token.next;
+ expectToken(token, TokenType.STRING, 10, 0,
+ isSynthetic: true, lexeme: "'''");
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
+ expect((token as fasta.ErrorToken).start, "r'''");
+ }
+
+ void test_string_raw_simple_unterminated_eof() {
+ Token token = scan("r'string");
+ expectToken(token, TokenType.STRING, 0, 8, lexeme: "r'string");
+
+ token = token.next;
+ expectToken(token, TokenType.STRING, 8, 0, isSynthetic: true, lexeme: "'");
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
+ expect((token as fasta.ErrorToken).start, "r'");
+ }
+
+ void test_string_raw_simple_unterminated_eol() {
+ Token token = scan("r'string\n");
+ expectToken(token, TokenType.STRING, 0, 8, lexeme: "r'string");
+
+ token = token.next;
+ expectToken(token, TokenType.STRING, 8, 0, isSynthetic: true, lexeme: "'");
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
+ expect((token as fasta.ErrorToken).start, "r'");
+ }
+
+ void test_string_simple_unterminated_eof() {
+ Token token = scan("'string");
+ expectToken(token, TokenType.STRING, 0, 7, lexeme: "'string");
+
+ token = token.next;
+ expectToken(token, TokenType.STRING, 7, 0, isSynthetic: true, lexeme: "'");
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
+ expect((token as fasta.ErrorToken).start, "'");
+ }
+
+ void test_string_simple_unterminated_eol() {
+ Token token = scan("'string\n");
+ expectToken(token, TokenType.STRING, 0, 7, lexeme: "'string");
+
+ token = token.next;
+ expectToken(token, TokenType.STRING, 7, 0, isSynthetic: true, lexeme: "'");
+
+ token = token.next;
+ expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
+ expect((token as fasta.ErrorToken).start, "'");
+ }
+
void test_match_angle_brackets() {
var x = scan('x<y>');
var lessThan = x.next as BeginToken;
@@ -500,32 +572,6 @@ class ScannerTest_Fasta_Direct extends ScannerTest_Fasta_Base {
var scanner = new fasta.StringScanner(source, includeComments: true);
return scanner.tokenize();
}
-
- test_unterminated_string_with_unterminated_interpolation() {
- Token token = scan(r'"foo ${bar');
- BeginToken interpolationStart = token.next;
-
- Token previous;
- while (token.kind != fasta.BAD_INPUT_TOKEN) {
- expect(token.isEof, isFalse);
- previous = token;
- token = token.next;
- }
-
- // Expect interpolation to be terminated before string is closed
-
- token = previous;
- expect(token.isSynthetic, isTrue);
- expect(token.length, 0);
- expect(token.stringValue, '}');
-
- token = token.next;
- expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
- expect((token as fasta.UnmatchedToken).begin, same(interpolationStart));
-
- token = token.next;
- expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
- }
}
/// Override of [ToAnalyzerTokenStreamConverter] that verifies that there are no

Powered by Google App Engine
This is Rietveld 408576698