diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart index 85e78e01874..3f172299d6a 100644 --- a/pkg/analyzer/test/generated/parser_fasta_test.dart +++ b/pkg/analyzer/test/generated/parser_fasta_test.dart @@ -1062,6 +1062,17 @@ main() { // missing async ]); } + void test_constructor_this_cascade_synthetic() { + // https://github.com/dart-lang/sdk/issues/37110 + parseCompilationUnit('class B extends A { B(): this.. {} }', errors: [ + expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 25, 4), + expectedError(ParserErrorCode.EXPECTED_TOKEN, 29, 2), + expectedError(ParserErrorCode.MISSING_IDENTIFIER, 32, 1), + expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 33, 1), + expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 35, 1), + ]); + } + void test_constructor_this_field() { // https://github.com/dart-lang/sdk/issues/36262 // https://github.com/dart-lang/sdk/issues/31198 diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart index 3a37ce61958..f85a2d35a43 100644 --- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart +++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart @@ -26,7 +26,8 @@ import 'error_token.dart' import 'keyword_state.dart' show KeywordState; -import 'token.dart' show CommentToken, DartDocToken, LanguageVersionToken; +import 'token.dart' + show CommentToken, DartDocToken, LanguageVersionToken, SyntheticStringToken; import 'token_constants.dart'; @@ -247,6 +248,9 @@ abstract class AbstractScanner implements Scanner { /// Append [token] to the token stream. void appendErrorToken(ErrorToken token); + /// Prepend [token] to the token stream. + void prependErrorToken(ErrorToken token); + /** * Returns a new comment from the scan offset [start] to the current * [scanOffset] plus the [extraOffset]. For example, if the current @@ -790,7 +794,11 @@ abstract class AbstractScanner implements Scanner { hasDigits = true; } else { if (!hasDigits) { - unterminated(messageExpectedHexDigit, shouldAdvance: false); + prependErrorToken(new UnterminatedToken( + messageExpectedHexDigit, start, stringOffset)); + // Recovery + // TODO(danrubel): append actual characters not "0" + appendToken(SyntheticStringToken(TokenType.INT, "0", tokenStart)); return next; } appendSubstringToken(TokenType.HEXADECIMAL, start, true); diff --git a/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart index ffc82028f98..3ba37128fd4 100644 --- a/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart +++ b/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart @@ -260,6 +260,7 @@ abstract class ArrayBasedScanner extends AbstractScanner { appendToken(token); } + @override void prependErrorToken(ErrorToken token) { hasErrors = true; if (_errorTail == tail) { diff --git a/pkg/front_end/lib/src/fasta/scanner/recover.dart b/pkg/front_end/lib/src/fasta/scanner/recover.dart index a54c94a9644..2998eccc526 100644 --- a/pkg/front_end/lib/src/fasta/scanner/recover.dart +++ b/pkg/front_end/lib/src/fasta/scanner/recover.dart @@ -135,8 +135,7 @@ Token scannerRecovery(List bytes, Token tokens, List lineStarts) { } recoverHexDigit() { - return synthesizeToken(errorTail.charOffset, "0", TokenType.INT) - ..setNext(errorTail.next); + throw "Internal error: Hex digit error token should have been prepended"; } recoverStringInterpolation() { @@ -156,7 +155,9 @@ Token scannerRecovery(List bytes, Token tokens, List lineStarts) { // All unmatched error tokens should have been prepended Token current = tokens; - while (current is ErrorToken && current.errorCode == codeUnmatchedToken) { + while (current is ErrorToken && + (current.errorCode == codeUnmatchedToken || + current.errorCode == codeExpectedHexDigit)) { if (errorTail == null) { error = current; } diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart index 932d67a0906..39a24acf5f4 100644 --- a/pkg/front_end/test/scanner_test.dart +++ b/pkg/front_end/test/scanner_test.dart @@ -303,7 +303,7 @@ abstract class ScannerTestBase { } void test_hexadecimal_missingDigit() { - _assertError(ScannerErrorCode.MISSING_HEX_DIGIT, 1, "0x"); + _assertError(ScannerErrorCode.MISSING_HEX_DIGIT, 5, "a = 0x"); } void test_identifier() {