| Index: pkg/front_end/test/scanner_replacement_test.dart
|
| diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a9fd3db746d81f8fa1dbba7959834f93cf86e715
|
| --- /dev/null
|
| +++ b/pkg/front_end/test/scanner_replacement_test.dart
|
| @@ -0,0 +1,280 @@
|
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +import 'package:front_end/src/fasta/scanner/precedence.dart'
|
| + show BAD_INPUT_INFO, EOF_INFO;
|
| +import 'package:front_end/src/fasta/scanner/recover.dart'
|
| + show defaultRecoveryStrategy;
|
| +import 'package:front_end/src/fasta/scanner.dart' as fasta;
|
| +import 'package:front_end/src/scanner/token.dart' as analyzer;
|
| +import 'package:front_end/src/scanner/errors.dart'
|
| + show ScannerErrorCode, translateErrorToken;
|
| +import 'package:test/test.dart';
|
| +import 'package:test_reflective_loader/test_reflective_loader.dart';
|
| +
|
| +import 'scanner_test.dart';
|
| +
|
| +main() {
|
| + defineReflectiveSuite(() {
|
| + defineReflectiveTests(ScannerTest_Replacement);
|
| + });
|
| +}
|
| +
|
| +/// Scanner tests that use the analyzer scanner, then convert the resulting
|
| +/// token stream into a Fasta token stream, then convert back to an analyzer
|
| +/// token stream before verifying assertions.
|
| +///
|
| +/// These tests help to validate the correctness of the analyzer->Fasta token
|
| +/// stream conversion.
|
| +@reflectiveTest
|
| +class ScannerTest_Replacement extends ScannerTest {
|
| + @override
|
| + analyzer.Token scanWithListener(String source, ErrorListener listener,
|
| + {bool genericMethodComments: false,
|
| + bool lazyAssignmentOperators: false}) {
|
| + if (genericMethodComments) {
|
| + // Fasta doesn't support generic method comments.
|
| + // TODO(danrubel): once the analyzer toolchain no longer needs generic
|
| + // method comments, remove tests that exercise them.
|
| + fail('No generic method comment support in Fasta');
|
| + }
|
| + // Note: Fasta always supports lazy assignment operators (`&&=` and `||=`),
|
| + // so we can ignore the `lazyAssignmentOperators` flag.
|
| + // TODO(danrubel): once lazyAssignmentOperators are fully supported by
|
| + // Dart, remove this flag.
|
| + fasta.ScannerResult result = fasta.scanString(source,
|
| + includeComments: true,
|
| + recover: ((List<int> bytes, fasta.Token tokens, List<int> lineStarts) {
|
| + // perform recovery as a separate step
|
| + // so that the token stream can be validated before and after recovery
|
| + return tokens;
|
| + }));
|
| + fasta.Token tokens = result.tokens;
|
| + assertValidTokenStream(tokens);
|
| + if (result.hasErrors) {
|
| + // TODO(danrubel): what should be passed for the "bytes" argument?
|
| + // does the Recover API need to be adjusted for a String source?
|
| + tokens = defaultRecoveryStrategy(null, tokens, result.lineStarts);
|
| + assertValidTokenStream(tokens);
|
| + }
|
| + return extractErrors(tokens, listener);
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_ampersand_ampersand_eq() {
|
| + // TODO(paulberry,ahe): Fasta scanner doesn't support lazy assignment
|
| + // operators.
|
| + super.test_ampersand_ampersand_eq();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_bar_bar_eq() {
|
| + // TODO(paulberry,ahe): Fasta scanner doesn't support lazy assignment
|
| + // operators.
|
| + super.test_bar_bar_eq();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_comment_generic_method_type_assign() {
|
| + // TODO(paulberry,ahe): Fasta scanner doesn't support generic comment
|
| + // syntax.
|
| + super.test_comment_generic_method_type_assign();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_comment_generic_method_type_list() {
|
| + // TODO(paulberry,ahe): Fasta scanner doesn't support generic comment
|
| + // syntax.
|
| + super.test_comment_generic_method_type_list();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_double_missingDigitInExponent() {
|
| + // TODO(danrubel): investigate and fix
|
| + super.test_double_missingDigitInExponent();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_hexidecimal_missingDigit() {
|
| + // TODO(danrubel): investigate and fix
|
| + super.test_hexidecimal_missingDigit();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_mismatched_closer() {
|
| + // TODO(danrubel): investigate and fix
|
| + super.test_mismatched_closer();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_mismatched_opener() {
|
| + // TODO(danrubel): investigate and fix
|
| + super.test_mismatched_opener();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_mismatched_opener_in_interpolation() {
|
| + // TODO(danrubel): investigate and fix
|
| + super.test_mismatched_opener_in_interpolation();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_multi_unterminated() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_multi_unterminated();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_multi_unterminated_interpolation_block() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_multi_unterminated_interpolation_block();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_multi_unterminated_interpolation_identifier() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_multi_unterminated_interpolation_identifier();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_raw_multi_unterminated() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_raw_multi_unterminated();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_raw_simple_unterminated_eof() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_raw_simple_unterminated_eof();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_raw_simple_unterminated_eol() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_raw_simple_unterminated_eol();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_simple_interpolation_missingIdentifier() {
|
| + // See defaultRecoveryStrategy recoverStringInterpolation
|
| + super.test_string_simple_interpolation_missingIdentifier();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_simple_interpolation_nonIdentifier() {
|
| + // See defaultRecoveryStrategy recoverStringInterpolation
|
| + super.test_string_simple_interpolation_nonIdentifier();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_simple_unterminated_eof() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_simple_unterminated_eof();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_simple_unterminated_eol() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_simple_unterminated_eol();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_simple_unterminated_interpolation_block() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_simple_unterminated_interpolation_block();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + void test_string_simple_unterminated_interpolation_identifier() {
|
| + // See defaultRecoveryStrategy recoverString
|
| + super.test_string_simple_unterminated_interpolation_identifier();
|
| + }
|
| +
|
| + @failingTest
|
| + @override
|
| + void test_unmatched_openers() {
|
| + // fasta recovery inserts closers
|
| + var openBrace = _scan('{[(<') as analyzer.BeginToken;
|
| + var openBracket = openBrace.next as analyzer.BeginToken;
|
| + var openParen = openBracket.next as analyzer.BeginToken;
|
| + var openLT = openParen.next as analyzer.BeginToken;
|
| + var closeGT = openLT.next;
|
| + var closeParen = closeGT.next;
|
| + var closeBracket = closeParen.next;
|
| + var closeBrace = closeBracket.next;
|
| + expect(closeBrace.next.type, analyzer.TokenType.EOF);
|
| +
|
| + expect(openBrace.endToken, closeBrace);
|
| + expect(openBracket.endToken, closeBracket);
|
| + expect(openParen.endToken, closeParen);
|
| + expect(openLT.endToken, closeGT);
|
| + }
|
| +
|
| + analyzer.Token _scan(String source,
|
| + {bool genericMethodComments: false,
|
| + bool lazyAssignmentOperators: false}) {
|
| + ErrorListener listener = new ErrorListener();
|
| + analyzer.Token token = scanWithListener(source, listener,
|
| + genericMethodComments: genericMethodComments,
|
| + lazyAssignmentOperators: lazyAssignmentOperators);
|
| + listener.assertNoErrors();
|
| + return token;
|
| + }
|
| +
|
| + analyzer.Token extractErrors(fasta.Token firstToken, ErrorListener listener) {
|
| + var token = firstToken;
|
| + // The default recovery strategy used by scanString
|
| + // places all error tokens at the head of the stream.
|
| + while (token.info == BAD_INPUT_INFO) {
|
| + translateErrorToken(token,
|
| + (ScannerErrorCode errorCode, int offset, List<Object> arguments) {
|
| + listener.errors.add(new TestError(offset, errorCode, arguments));
|
| + });
|
| + token = token.next;
|
| + }
|
| + if (!token.previousToken.isEof) {
|
| + var head = new fasta.SymbolToken(EOF_INFO, -1);
|
| + token.previous = head;
|
| + head.next = token;
|
| + }
|
| + return token;
|
| + }
|
| +
|
| + /// Assert that the tokens in the stream are correctly connected prev/next.
|
| + void assertValidTokenStream(fasta.Token firstToken) {
|
| + fasta.Token token = firstToken;
|
| + fasta.Token previous = token.previousToken;
|
| + expect(previous.isEof, isTrue, reason: 'Missing leading EOF');
|
| + expect(previous.next, token, reason: 'Invalid leading EOF');
|
| + expect(previous.previous, previous, reason: 'Invalid leading EOF');
|
| + while (!token.isEof) {
|
| + previous = token;
|
| + token = token.next;
|
| + expect(token, isNotNull, reason: previous.toString());
|
| + expect(token.previous, previous, reason: token.toString());
|
| + }
|
| + expect(token.next, token, reason: 'Invalid trailing EOF');
|
| + }
|
| +}
|
|
|