Skip to content

Commit b41b868

Browse files
Dan Rubelcommit-bot@chromium.org
authored andcommitted
prepend UnmatchedToken error tokens
This change ensures that instances of UnmatchedToken are always prepended to the token stream. This should prevent the exception that occurs in #37491. This addresses only one type of error token and we may see a similar exception with other types of error tokens. Future CLs will prepend other and eventually all error tokens. Change-Id: I99cdc331c03f47b21c5a67d436a0e62ebf416e94 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/110100 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Dan Rubel <[email protected]>
1 parent 04a3f9e commit b41b868

18 files changed

+98
-71
lines changed

pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,8 +1090,8 @@ abstract class AbstractScanner implements Scanner {
10901090
*/
10911091
void appendToken(Token token) {
10921092
tail.next = token;
1093-
tail.next.previous = tail;
1094-
tail = tail.next;
1093+
token.previous = tail;
1094+
tail = token;
10951095
if (comments != null && comments == token.precedingComments) {
10961096
comments = null;
10971097
commentsTail = null;

pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@ import '../util/link.dart' show Link;
3333

3434
abstract class ArrayBasedScanner extends AbstractScanner {
3535
bool hasErrors = false;
36+
Token _errorTail;
3637

3738
ArrayBasedScanner(ScannerConfiguration config, bool includeComments,
3839
LanguageVersionChanged languageVersionChanged, {int numberOfBytesHint})
3940
: super(config, includeComments, languageVersionChanged,
40-
numberOfBytesHint: numberOfBytesHint);
41+
numberOfBytesHint: numberOfBytesHint) {
42+
this._errorTail = this.tokens;
43+
}
4144

4245
/**
4346
* The stack of open groups, e.g [: { ... ( .. :]
@@ -257,6 +260,20 @@ abstract class ArrayBasedScanner extends AbstractScanner {
257260
appendToken(token);
258261
}
259262

263+
void prependErrorToken(ErrorToken token) {
264+
hasErrors = true;
265+
if (_errorTail == tail) {
266+
appendToken(token);
267+
_errorTail = tail;
268+
} else {
269+
token.next = _errorTail.next;
270+
token.next.previous = token;
271+
_errorTail.next = token;
272+
token.previous = _errorTail;
273+
_errorTail = _errorTail.next;
274+
}
275+
}
276+
260277
@override
261278
void appendSubstringToken(TokenType type, int start, bool asciiOnly,
262279
[int extraOffset = 0]) {
@@ -374,6 +391,6 @@ abstract class ArrayBasedScanner extends AbstractScanner {
374391
TokenType type = closeBraceInfoFor(begin);
375392
appendToken(new SyntheticToken(type, tokenStart)..beforeSynthetic = tail);
376393
begin.endGroup = tail;
377-
appendErrorToken(new UnmatchedToken(begin));
394+
prependErrorToken(new UnmatchedToken(begin));
378395
}
379396
}

pkg/front_end/lib/src/fasta/scanner/recover.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,20 @@ Token scannerRecovery(List<int> bytes, Token tokens, List<int> lineStarts) {
151151
recoverUnmatched() {
152152
// TODO(ahe): Try to use top-level keywords (such as `class`, `typedef`,
153153
// and `enum`) and indentation to recover.
154-
return errorTail.next;
154+
throw "Internal error: Unmatched error token should have been prepended";
155+
}
156+
157+
// All unmatched error tokens should have been prepended
158+
Token current = tokens;
159+
while (current is ErrorToken && current.errorCode == codeUnmatchedToken) {
160+
if (errorTail == null) {
161+
error = current;
162+
}
163+
errorTail = current;
164+
current = current.next;
155165
}
156166

157-
for (Token current = tokens; !current.isEof; current = current.next) {
167+
for (; !current.isEof; current = current.next) {
158168
while (current is ErrorToken) {
159169
ErrorToken first = current;
160170
Token next = current;

pkg/front_end/testcases/rasta/bad_interpolation.dart.legacy.expect

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
6-
// print(" $x.);
7-
// ^^^
8-
//
95
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:8: Error: Can't find ')' to match '('.
106
// print(" $x.);
117
// ^
128
//
9+
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
10+
// print(" $x.);
11+
// ^^^
12+
//
1313
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:12: Warning: Getter not found: 'x'.
1414
// print(" $x.);
1515
// ^

pkg/front_end/testcases/rasta/bad_interpolation.dart.legacy.transformed.expect

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
6-
// print(" $x.);
7-
// ^^^
8-
//
95
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:8: Error: Can't find ')' to match '('.
106
// print(" $x.);
117
// ^
128
//
9+
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
10+
// print(" $x.);
11+
// ^^^
12+
//
1313
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:12: Warning: Getter not found: 'x'.
1414
// print(" $x.);
1515
// ^

pkg/front_end/testcases/rasta/bad_interpolation.dart.outline.expect

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
6-
// print(" $x.);
7-
// ^^^
8-
//
95
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:8: Error: Can't find ')' to match '('.
106
// print(" $x.);
117
// ^
128
//
9+
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
10+
// print(" $x.);
11+
// ^^^
12+
//
1313
import self as self;
1414

1515
static method main() → dynamic

pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.expect

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
6-
// print(" $x.);
7-
// ^^^
8-
//
95
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:8: Error: Can't find ')' to match '('.
106
// print(" $x.);
117
// ^
128
//
9+
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
10+
// print(" $x.);
11+
// ^^^
12+
//
1313
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:12: Error: Getter not found: 'x'.
1414
// print(" $x.);
1515
// ^

pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.transformed.expect

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
6-
// print(" $x.);
7-
// ^^^
8-
//
95
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:8: Error: Can't find ')' to match '('.
106
// print(" $x.);
117
// ^
128
//
9+
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
10+
// print(" $x.);
11+
// ^^^
12+
//
1313
// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:12: Error: Getter not found: 'x'.
1414
// print(" $x.);
1515
// ^

pkg/front_end/testcases/regress/issue_29976.dart.legacy.expect

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/regress/issue_29976.dart:9:7: Error: Can't find '}' to match '${'.
6+
// "x${x*"'"é'}x
7+
// ^
8+
//
59
// pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
610
// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
711
// "x${x*"'"é'}x
@@ -11,10 +15,6 @@ library;
1115
// "x${x*"'"é'}x
1216
// ^^^
1317
//
14-
// pkg/front_end/testcases/regress/issue_29976.dart:9:7: Error: Can't find '}' to match '${'.
15-
// "x${x*"'"é'}x
16-
// ^
17-
//
1818
// pkg/front_end/testcases/regress/issue_29976.dart:9:5: Error: String starting with " must end with ".
1919
// "x${x*"'"é'}x
2020
// ^^^^^^^^^^^^^^...

pkg/front_end/testcases/regress/issue_29976.dart.legacy.transformed.expect

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ library;
22
//
33
// Problems in library:
44
//
5+
// pkg/front_end/testcases/regress/issue_29976.dart:9:7: Error: Can't find '}' to match '${'.
6+
// "x${x*"'"é'}x
7+
// ^
8+
//
59
// pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
610
// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
711
// "x${x*"'"é'}x
@@ -11,10 +15,6 @@ library;
1115
// "x${x*"'"é'}x
1216
// ^^^
1317
//
14-
// pkg/front_end/testcases/regress/issue_29976.dart:9:7: Error: Can't find '}' to match '${'.
15-
// "x${x*"'"é'}x
16-
// ^
17-
//
1818
// pkg/front_end/testcases/regress/issue_29976.dart:9:5: Error: String starting with " must end with ".
1919
// "x${x*"'"é'}x
2020
// ^^^^^^^^^^^^^^...

0 commit comments

Comments
 (0)