OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'package:front_end/src/fasta/scanner/precedence.dart' |
| 6 show BAD_INPUT_INFO, EOF_INFO; |
| 7 import 'package:front_end/src/fasta/scanner/recover.dart' |
| 8 show defaultRecoveryStrategy; |
| 9 import 'package:front_end/src/fasta/scanner.dart' as fasta; |
| 10 import 'package:front_end/src/scanner/token.dart' as analyzer; |
| 11 import 'package:front_end/src/scanner/errors.dart' |
| 12 show ScannerErrorCode, translateErrorToken; |
| 13 import 'package:test/test.dart'; |
| 14 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 15 |
| 16 import 'scanner_test.dart'; |
| 17 |
| 18 main() { |
| 19 defineReflectiveSuite(() { |
| 20 defineReflectiveTests(ScannerTest_Replacement); |
| 21 }); |
| 22 } |
| 23 |
| 24 /// Scanner tests that use the analyzer scanner, then convert the resulting |
| 25 /// token stream into a Fasta token stream, then convert back to an analyzer |
| 26 /// token stream before verifying assertions. |
| 27 /// |
| 28 /// These tests help to validate the correctness of the analyzer->Fasta token |
| 29 /// stream conversion. |
| 30 @reflectiveTest |
| 31 class ScannerTest_Replacement extends ScannerTest { |
| 32 @override |
| 33 analyzer.Token scanWithListener(String source, ErrorListener listener, |
| 34 {bool genericMethodComments: false, |
| 35 bool lazyAssignmentOperators: false}) { |
| 36 if (genericMethodComments) { |
| 37 // Fasta doesn't support generic method comments. |
| 38 // TODO(danrubel): once the analyzer toolchain no longer needs generic |
| 39 // method comments, remove tests that exercise them. |
| 40 fail('No generic method comment support in Fasta'); |
| 41 } |
| 42 // Note: Fasta always supports lazy assignment operators (`&&=` and `||=`), |
| 43 // so we can ignore the `lazyAssignmentOperators` flag. |
| 44 // TODO(danrubel): once lazyAssignmentOperators are fully supported by |
| 45 // Dart, remove this flag. |
| 46 fasta.ScannerResult result = fasta.scanString(source, |
| 47 includeComments: true, |
| 48 recover: ((List<int> bytes, fasta.Token tokens, List<int> lineStarts) { |
| 49 // perform recovery as a separate step |
| 50 // so that the token stream can be validated before and after recovery |
| 51 return tokens; |
| 52 })); |
| 53 fasta.Token tokens = result.tokens; |
| 54 assertValidTokenStream(tokens); |
| 55 if (result.hasErrors) { |
| 56 // TODO(danrubel): what should be passed for the "bytes" argument? |
| 57 // does the Recover API need to be adjusted for a String source? |
| 58 tokens = defaultRecoveryStrategy(null, tokens, result.lineStarts); |
| 59 assertValidTokenStream(tokens); |
| 60 } |
| 61 return extractErrors(tokens, listener); |
| 62 } |
| 63 |
| 64 @override |
| 65 @failingTest |
| 66 void test_ampersand_ampersand_eq() { |
| 67 // TODO(paulberry,ahe): Fasta scanner doesn't support lazy assignment |
| 68 // operators. |
| 69 super.test_ampersand_ampersand_eq(); |
| 70 } |
| 71 |
| 72 @override |
| 73 @failingTest |
| 74 void test_bar_bar_eq() { |
| 75 // TODO(paulberry,ahe): Fasta scanner doesn't support lazy assignment |
| 76 // operators. |
| 77 super.test_bar_bar_eq(); |
| 78 } |
| 79 |
| 80 @override |
| 81 @failingTest |
| 82 void test_comment_generic_method_type_assign() { |
| 83 // TODO(paulberry,ahe): Fasta scanner doesn't support generic comment |
| 84 // syntax. |
| 85 super.test_comment_generic_method_type_assign(); |
| 86 } |
| 87 |
| 88 @override |
| 89 @failingTest |
| 90 void test_comment_generic_method_type_list() { |
| 91 // TODO(paulberry,ahe): Fasta scanner doesn't support generic comment |
| 92 // syntax. |
| 93 super.test_comment_generic_method_type_list(); |
| 94 } |
| 95 |
| 96 @override |
| 97 @failingTest |
| 98 void test_double_missingDigitInExponent() { |
| 99 // TODO(danrubel): investigate and fix |
| 100 super.test_double_missingDigitInExponent(); |
| 101 } |
| 102 |
| 103 @override |
| 104 @failingTest |
| 105 void test_hexidecimal_missingDigit() { |
| 106 // TODO(danrubel): investigate and fix |
| 107 super.test_hexidecimal_missingDigit(); |
| 108 } |
| 109 |
| 110 @override |
| 111 @failingTest |
| 112 void test_mismatched_closer() { |
| 113 // TODO(danrubel): investigate and fix |
| 114 super.test_mismatched_closer(); |
| 115 } |
| 116 |
| 117 @override |
| 118 @failingTest |
| 119 void test_mismatched_opener() { |
| 120 // TODO(danrubel): investigate and fix |
| 121 super.test_mismatched_opener(); |
| 122 } |
| 123 |
| 124 @override |
| 125 @failingTest |
| 126 void test_mismatched_opener_in_interpolation() { |
| 127 // TODO(danrubel): investigate and fix |
| 128 super.test_mismatched_opener_in_interpolation(); |
| 129 } |
| 130 |
| 131 @override |
| 132 @failingTest |
| 133 void test_string_multi_unterminated() { |
| 134 // See defaultRecoveryStrategy recoverString |
| 135 super.test_string_multi_unterminated(); |
| 136 } |
| 137 |
| 138 @override |
| 139 @failingTest |
| 140 void test_string_multi_unterminated_interpolation_block() { |
| 141 // See defaultRecoveryStrategy recoverString |
| 142 super.test_string_multi_unterminated_interpolation_block(); |
| 143 } |
| 144 |
| 145 @override |
| 146 @failingTest |
| 147 void test_string_multi_unterminated_interpolation_identifier() { |
| 148 // See defaultRecoveryStrategy recoverString |
| 149 super.test_string_multi_unterminated_interpolation_identifier(); |
| 150 } |
| 151 |
| 152 @override |
| 153 @failingTest |
| 154 void test_string_raw_multi_unterminated() { |
| 155 // See defaultRecoveryStrategy recoverString |
| 156 super.test_string_raw_multi_unterminated(); |
| 157 } |
| 158 |
| 159 @override |
| 160 @failingTest |
| 161 void test_string_raw_simple_unterminated_eof() { |
| 162 // See defaultRecoveryStrategy recoverString |
| 163 super.test_string_raw_simple_unterminated_eof(); |
| 164 } |
| 165 |
| 166 @override |
| 167 @failingTest |
| 168 void test_string_raw_simple_unterminated_eol() { |
| 169 // See defaultRecoveryStrategy recoverString |
| 170 super.test_string_raw_simple_unterminated_eol(); |
| 171 } |
| 172 |
| 173 @override |
| 174 @failingTest |
| 175 void test_string_simple_interpolation_missingIdentifier() { |
| 176 // See defaultRecoveryStrategy recoverStringInterpolation |
| 177 super.test_string_simple_interpolation_missingIdentifier(); |
| 178 } |
| 179 |
| 180 @override |
| 181 @failingTest |
| 182 void test_string_simple_interpolation_nonIdentifier() { |
| 183 // See defaultRecoveryStrategy recoverStringInterpolation |
| 184 super.test_string_simple_interpolation_nonIdentifier(); |
| 185 } |
| 186 |
| 187 @override |
| 188 @failingTest |
| 189 void test_string_simple_unterminated_eof() { |
| 190 // See defaultRecoveryStrategy recoverString |
| 191 super.test_string_simple_unterminated_eof(); |
| 192 } |
| 193 |
| 194 @override |
| 195 @failingTest |
| 196 void test_string_simple_unterminated_eol() { |
| 197 // See defaultRecoveryStrategy recoverString |
| 198 super.test_string_simple_unterminated_eol(); |
| 199 } |
| 200 |
| 201 @override |
| 202 @failingTest |
| 203 void test_string_simple_unterminated_interpolation_block() { |
| 204 // See defaultRecoveryStrategy recoverString |
| 205 super.test_string_simple_unterminated_interpolation_block(); |
| 206 } |
| 207 |
| 208 @override |
| 209 @failingTest |
| 210 void test_string_simple_unterminated_interpolation_identifier() { |
| 211 // See defaultRecoveryStrategy recoverString |
| 212 super.test_string_simple_unterminated_interpolation_identifier(); |
| 213 } |
| 214 |
| 215 @failingTest |
| 216 @override |
| 217 void test_unmatched_openers() { |
| 218 // fasta recovery inserts closers |
| 219 var openBrace = _scan('{[(<') as analyzer.BeginToken; |
| 220 var openBracket = openBrace.next as analyzer.BeginToken; |
| 221 var openParen = openBracket.next as analyzer.BeginToken; |
| 222 var openLT = openParen.next as analyzer.BeginToken; |
| 223 var closeGT = openLT.next; |
| 224 var closeParen = closeGT.next; |
| 225 var closeBracket = closeParen.next; |
| 226 var closeBrace = closeBracket.next; |
| 227 expect(closeBrace.next.type, analyzer.TokenType.EOF); |
| 228 |
| 229 expect(openBrace.endToken, closeBrace); |
| 230 expect(openBracket.endToken, closeBracket); |
| 231 expect(openParen.endToken, closeParen); |
| 232 expect(openLT.endToken, closeGT); |
| 233 } |
| 234 |
| 235 analyzer.Token _scan(String source, |
| 236 {bool genericMethodComments: false, |
| 237 bool lazyAssignmentOperators: false}) { |
| 238 ErrorListener listener = new ErrorListener(); |
| 239 analyzer.Token token = scanWithListener(source, listener, |
| 240 genericMethodComments: genericMethodComments, |
| 241 lazyAssignmentOperators: lazyAssignmentOperators); |
| 242 listener.assertNoErrors(); |
| 243 return token; |
| 244 } |
| 245 |
| 246 analyzer.Token extractErrors(fasta.Token firstToken, ErrorListener listener) { |
| 247 var token = firstToken; |
| 248 // The default recovery strategy used by scanString |
| 249 // places all error tokens at the head of the stream. |
| 250 while (token.info == BAD_INPUT_INFO) { |
| 251 translateErrorToken(token, |
| 252 (ScannerErrorCode errorCode, int offset, List<Object> arguments) { |
| 253 listener.errors.add(new TestError(offset, errorCode, arguments)); |
| 254 }); |
| 255 token = token.next; |
| 256 } |
| 257 if (!token.previousToken.isEof) { |
| 258 var head = new fasta.SymbolToken(EOF_INFO, -1); |
| 259 token.previous = head; |
| 260 head.next = token; |
| 261 } |
| 262 return token; |
| 263 } |
| 264 |
| 265 /// Assert that the tokens in the stream are correctly connected prev/next. |
| 266 void assertValidTokenStream(fasta.Token firstToken) { |
| 267 fasta.Token token = firstToken; |
| 268 fasta.Token previous = token.previousToken; |
| 269 expect(previous.isEof, isTrue, reason: 'Missing leading EOF'); |
| 270 expect(previous.next, token, reason: 'Invalid leading EOF'); |
| 271 expect(previous.previous, previous, reason: 'Invalid leading EOF'); |
| 272 while (!token.isEof) { |
| 273 previous = token; |
| 274 token = token.next; |
| 275 expect(token, isNotNull, reason: previous.toString()); |
| 276 expect(token.previous, previous, reason: token.toString()); |
| 277 } |
| 278 expect(token.next, token, reason: 'Invalid trailing EOF'); |
| 279 } |
| 280 } |
OLD | NEW |