| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:front_end/src/fasta/analyzer/token_utils.dart'; | 5 import 'package:front_end/src/fasta/analyzer/token_utils.dart'; |
| 6 import 'package:front_end/src/fasta/scanner/error_token.dart' as fasta; | 6 import 'package:front_end/src/fasta/scanner/error_token.dart' as fasta; |
| 7 import 'package:front_end/src/fasta/scanner/keyword.dart' as fasta; | 7 import 'package:front_end/src/fasta/scanner/keyword.dart' as fasta; |
| 8 import 'package:front_end/src/fasta/scanner/string_scanner.dart' as fasta; | 8 import 'package:front_end/src/fasta/scanner/string_scanner.dart' as fasta; |
| 9 import 'package:front_end/src/fasta/scanner/token.dart' as fasta; | 9 import 'package:front_end/src/fasta/scanner/token.dart' as fasta; |
| 10 import 'package:front_end/src/fasta/scanner/token_constants.dart' as fasta; | 10 import 'package:front_end/src/fasta/scanner/token_constants.dart' as fasta; |
| 11 import 'package:front_end/src/scanner/errors.dart'; | 11 import 'package:front_end/src/scanner/errors.dart'; |
| 12 import 'package:front_end/src/scanner/token.dart'; | 12 import 'package:front_end/src/scanner/token.dart'; |
| 13 import 'package:test/test.dart'; | 13 import 'package:test/test.dart'; |
| 14 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 14 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 15 | 15 |
| 16 import 'scanner_test.dart'; | 16 import 'scanner_test.dart'; |
| 17 | 17 |
| 18 main() { | 18 main() { |
| 19 defineReflectiveSuite(() { | 19 defineReflectiveSuite(() { |
| 20 defineReflectiveTests(ScannerTest_Fasta); | 20 defineReflectiveTests(ScannerTest_Fasta); |
| 21 defineReflectiveTests(ScannerTest_Fasta_Direct); |
| 22 defineReflectiveTests(ScannerTest_Fasta_Roundtrip); |
| 21 }); | 23 }); |
| 22 } | 24 } |
| 23 | 25 |
| 24 @reflectiveTest | 26 @reflectiveTest |
| 25 class ScannerTest_Fasta extends ScannerTestBase { | 27 class ScannerTest_Fasta extends ScannerTestBase { |
| 26 @override | 28 @override |
| 27 Token scanWithListener(String source, ErrorListener listener, | 29 Token scanWithListener(String source, ErrorListener listener, |
| 28 {bool genericMethodComments: false, | 30 {bool genericMethodComments: false, |
| 29 bool lazyAssignmentOperators: false}) { | 31 bool lazyAssignmentOperators: false}) { |
| 30 if (genericMethodComments) { | 32 if (genericMethodComments) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 super.test_string_simple_unterminated_interpolation_block(); | 191 super.test_string_simple_unterminated_interpolation_block(); |
| 190 } | 192 } |
| 191 | 193 |
| 192 @override | 194 @override |
| 193 @failingTest | 195 @failingTest |
| 194 void test_string_simple_unterminated_interpolation_identifier() { | 196 void test_string_simple_unterminated_interpolation_identifier() { |
| 195 // TODO(paulberry,ahe): bad error recovery. | 197 // TODO(paulberry,ahe): bad error recovery. |
| 196 super.test_string_simple_unterminated_interpolation_identifier(); | 198 super.test_string_simple_unterminated_interpolation_identifier(); |
| 197 } | 199 } |
| 198 } | 200 } |
| 201 |
| 202 /// Base class for scanner tests that examine the token stream in Fasta format. |
| 203 abstract class ScannerTest_Fasta_Base { |
| 204 fasta.Token scan(String source); |
| 205 |
| 206 void test_match_angle_brackets() { |
| 207 var x = scan('x<y>'); |
| 208 var lessThan = x.next as fasta.BeginGroupToken; |
| 209 var y = lessThan.next; |
| 210 var greaterThan = y.next; |
| 211 expect(greaterThan.next.isEof, isTrue); |
| 212 expect(lessThan.endGroup, same(greaterThan)); |
| 213 } |
| 214 |
| 215 void test_match_angle_brackets_gt_gt() { |
| 216 // When a ">>" appears in the token stream, Fasta's scanner matches it to |
| 217 // the outer "<". The inner "<" is left unmatched. |
| 218 var x = scan('x<y<z>>'); |
| 219 var lessThan1 = x.next as fasta.BeginGroupToken; |
| 220 var y = lessThan1.next; |
| 221 var lessThan2 = y.next as fasta.BeginGroupToken; |
| 222 var z = lessThan2.next; |
| 223 var greaterThans = z.next; |
| 224 expect(greaterThans.next.isEof, isTrue); |
| 225 expect(lessThan1.endGroup, same(greaterThans)); |
| 226 expect(lessThan2.endGroup, isNull); |
| 227 } |
| 228 |
| 229 void test_match_angle_brackets_interrupted_by_close_brace() { |
| 230 // A "}" appearing in the token stream interrupts matching of "<" and ">". |
| 231 var openBrace = scan('{x<y}>z') as fasta.BeginGroupToken; |
| 232 var x = openBrace.next; |
| 233 var lessThan = x.next as fasta.BeginGroupToken; |
| 234 var y = lessThan.next; |
| 235 var closeBrace = y.next; |
| 236 var greaterThan = closeBrace.next; |
| 237 var z = greaterThan.next; |
| 238 expect(z.next.isEof, isTrue); |
| 239 expect(openBrace.endGroup, same(closeBrace)); |
| 240 expect(lessThan.endGroup, isNull); |
| 241 } |
| 242 |
| 243 void test_match_angle_brackets_interrupted_by_close_bracket() { |
| 244 // A "]" appearing in the token stream interrupts matching of "<" and ">". |
| 245 var openBracket = scan('[x<y]>z') as fasta.BeginGroupToken; |
| 246 var x = openBracket.next; |
| 247 var lessThan = x.next as fasta.BeginGroupToken; |
| 248 var y = lessThan.next; |
| 249 var closeBracket = y.next; |
| 250 var greaterThan = closeBracket.next; |
| 251 var z = greaterThan.next; |
| 252 expect(z.next.isEof, isTrue); |
| 253 expect(openBracket.endGroup, same(closeBracket)); |
| 254 expect(lessThan.endGroup, isNull); |
| 255 } |
| 256 |
| 257 void test_match_angle_brackets_interrupted_by_close_paren() { |
| 258 // A ")" appearing in the token stream interrupts matching of "<" and ">". |
| 259 var openParen = scan('(x<y)>z') as fasta.BeginGroupToken; |
| 260 var x = openParen.next; |
| 261 var lessThan = x.next as fasta.BeginGroupToken; |
| 262 var y = lessThan.next; |
| 263 var closeParen = y.next; |
| 264 var greaterThan = closeParen.next; |
| 265 var z = greaterThan.next; |
| 266 expect(z.next.isEof, isTrue); |
| 267 expect(openParen.endGroup, same(closeParen)); |
| 268 expect(lessThan.endGroup, isNull); |
| 269 } |
| 270 |
| 271 void test_match_angle_brackets_interrupted_by_interpolation_expr() { |
| 272 // A "${" appearing in the token stream interrupts matching of "<" and ">". |
| 273 var x = scan(r'x<"${y>z}"'); |
| 274 var lessThan = x.next as fasta.BeginGroupToken; |
| 275 var beginString = lessThan.next; |
| 276 var beginInterpolation = beginString.next as fasta.BeginGroupToken; |
| 277 var y = beginInterpolation.next; |
| 278 var greaterThan = y.next; |
| 279 var z = greaterThan.next; |
| 280 var endInterpolation = z.next; |
| 281 var endString = endInterpolation.next; |
| 282 expect(endString.next.isEof, isTrue); |
| 283 expect(lessThan.endGroup, isNull); |
| 284 expect(beginInterpolation.endGroup, same(endInterpolation)); |
| 285 } |
| 286 |
| 287 void test_match_angle_brackets_interrupted_by_open_brace() { |
| 288 // A "{" appearing in the token stream interrupts matching of "<" and ">". |
| 289 var x = scan('x<{y>z}'); |
| 290 var lessThan = x.next as fasta.BeginGroupToken; |
| 291 var openBrace = lessThan.next as fasta.BeginGroupToken; |
| 292 var y = openBrace.next; |
| 293 var greaterThan = y.next; |
| 294 var z = greaterThan.next; |
| 295 var closeBrace = z.next; |
| 296 expect(closeBrace.next.isEof, isTrue); |
| 297 expect(lessThan.endGroup, isNull); |
| 298 expect(openBrace.endGroup, same(closeBrace)); |
| 299 } |
| 300 |
| 301 void test_match_angle_brackets_interrupted_by_open_bracket() { |
| 302 // A "[" appearing in the token stream interrupts matching of "<" and ">". |
| 303 var x = scan('x<y[z>a]'); |
| 304 var lessThan = x.next as fasta.BeginGroupToken; |
| 305 var y = lessThan.next; |
| 306 var openBracket = y.next as fasta.BeginGroupToken; |
| 307 var z = openBracket.next; |
| 308 var greaterThan = z.next; |
| 309 var a = greaterThan.next; |
| 310 var closeBracket = a.next; |
| 311 expect(closeBracket.next.isEof, isTrue); |
| 312 expect(lessThan.endGroup, isNull); |
| 313 expect(openBracket.endGroup, same(closeBracket)); |
| 314 } |
| 315 |
| 316 void test_match_angle_brackets_interrupted_by_open_paren() { |
| 317 // A "(" appearing in the token stream interrupts matching of "<" and ">". |
| 318 var x = scan('x<y(z>a)'); |
| 319 var lessThan = x.next as fasta.BeginGroupToken; |
| 320 var y = lessThan.next; |
| 321 var openParen = y.next as fasta.BeginGroupToken; |
| 322 var z = openParen.next; |
| 323 var greaterThan = z.next; |
| 324 var a = greaterThan.next; |
| 325 var closeParen = a.next; |
| 326 expect(closeParen.next.isEof, isTrue); |
| 327 expect(lessThan.endGroup, isNull); |
| 328 expect(openParen.endGroup, same(closeParen)); |
| 329 } |
| 330 |
| 331 void test_match_angle_brackets_nested() { |
| 332 var x = scan('x<y<z>,a>'); |
| 333 var lessThan1 = x.next as fasta.BeginGroupToken; |
| 334 var y = lessThan1.next; |
| 335 var lessThan2 = y.next as fasta.BeginGroupToken; |
| 336 var z = lessThan2.next; |
| 337 var greaterThan1 = z.next; |
| 338 var comma = greaterThan1.next; |
| 339 var a = comma.next; |
| 340 var greaterThan2 = a.next; |
| 341 expect(greaterThan2.next.isEof, isTrue); |
| 342 expect(lessThan1.endGroup, same(greaterThan2)); |
| 343 expect(lessThan2.endGroup, same(greaterThan1)); |
| 344 } |
| 345 |
| 346 void test_match_angle_brackets_unmatched_gt_gt() { |
| 347 // When a ">>" appears in the token stream and there is no outer "<", |
| 348 // Fasta's scanner leaves the inner "<" unmatched. |
| 349 var x = scan('x<y>>z'); |
| 350 var lessThan = x.next as fasta.BeginGroupToken; |
| 351 var y = lessThan.next; |
| 352 var greaterThans = y.next; |
| 353 var z = greaterThans.next; |
| 354 expect(z.next.isEof, isTrue); |
| 355 expect(lessThan.endGroup, isNull); |
| 356 } |
| 357 } |
| 358 |
| 359 /// Scanner tests that exercise the Fasta scanner directly. |
| 360 @reflectiveTest |
| 361 class ScannerTest_Fasta_Direct extends ScannerTest_Fasta_Base { |
| 362 @override |
| 363 fasta.Token scan(String source) { |
| 364 var scanner = new fasta.StringScanner(source, includeComments: true); |
| 365 return scanner.tokenize(); |
| 366 } |
| 367 } |
| 368 |
| 369 /// Scanner tests that exercise the Fasta scanner, then convert the tokens to |
| 370 /// analyzer tokens, then convert back to Fasta tokens before checking |
| 371 /// assertions. |
| 372 @reflectiveTest |
| 373 class ScannerTest_Fasta_Roundtrip extends ScannerTest_Fasta_Base { |
| 374 @override |
| 375 fasta.Token scan(String source) { |
| 376 var scanner = new fasta.StringScanner(source, includeComments: true); |
| 377 var fastaTokenStream = scanner.tokenize(); |
| 378 var analyzerTokenStream = toAnalyzerTokenStream(fastaTokenStream, |
| 379 (ScannerErrorCode errorCode, int offset, List<Object> arguments) { |
| 380 fail('Unexpected error: $errorCode, $offset, $arguments'); |
| 381 }); |
| 382 return fromAnalyzerTokenStream(analyzerTokenStream); |
| 383 } |
| 384 } |
| OLD | NEW |