| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library engine.scanner_test; | 8 library engine.scanner_test; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/java_core.dart'; | 10 import 'package:analyzer/src/generated/java_core.dart'; |
| 11 import 'package:analyzer/src/generated/java_junit.dart'; | 11 import 'package:analyzer/src/generated/java_junit.dart'; |
| 12 import 'package:analyzer/src/generated/source.dart'; | 12 import 'package:analyzer/src/generated/source.dart'; |
| 13 import 'package:analyzer/src/generated/error.dart'; | 13 import 'package:analyzer/src/generated/error.dart'; |
| 14 import 'package:analyzer/src/generated/scanner.dart'; | 14 import 'package:analyzer/src/generated/scanner.dart'; |
| 15 import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap; | 15 import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap; |
| 16 import 'package:unittest/unittest.dart' as _ut; | 16 import 'package:unittest/unittest.dart' as _ut; |
| 17 import 'test_support.dart'; | 17 import 'test_support.dart'; |
| 18 | 18 |
| 19 class KeywordStateTest extends JUnitTestCase { | 19 /** |
| 20 void test_KeywordState() { | 20 * Instances of the class `TokenStreamValidator` are used to validate the correc
t construction |
| 21 // | 21 * of a stream of tokens. |
| 22 // Generate the test data to be scanned. | 22 */ |
| 23 // | 23 class TokenStreamValidator { |
| 24 List<Keyword> keywords = Keyword.values; | 24 /** |
| 25 int keywordCount = keywords.length; | 25 * Validate that the stream of tokens that starts with the given token is corr
ect. |
| 26 List<String> textToTest = new List<String>(keywordCount * 3); | 26 * |
| 27 for (int i = 0; i < keywordCount; i++) { | 27 * @param token the first token in the stream of tokens to be validated |
| 28 String syntax = keywords[i].syntax; | 28 */ |
| 29 textToTest[i] = syntax; | 29 void validate(Token token) { |
| 30 textToTest[i + keywordCount] = "${syntax}x"; | 30 JavaStringBuilder builder = new JavaStringBuilder(); |
| 31 textToTest[i + keywordCount * 2] = syntax.substring(0, syntax.length - 1); | 31 _validateStream(builder, token); |
| 32 } | 32 if (builder.length > 0) { |
| 33 // | 33 JUnitTestCase.fail(builder.toString()); |
| 34 // Scan each of the identifiers. | |
| 35 // | |
| 36 KeywordState firstState = KeywordState.KEYWORD_STATE; | |
| 37 for (int i = 0; i < textToTest.length; i++) { | |
| 38 String text = textToTest[i]; | |
| 39 int index = 0; | |
| 40 int length = text.length; | |
| 41 KeywordState state = firstState; | |
| 42 while (index < length && state != null) { | |
| 43 state = state.next(text.codeUnitAt(index)); | |
| 44 index++; | |
| 45 } | |
| 46 if (i < keywordCount) { | |
| 47 // keyword | |
| 48 JUnitTestCase.assertNotNull(state); | |
| 49 JUnitTestCase.assertNotNull(state.keyword()); | |
| 50 JUnitTestCase.assertEquals(keywords[i], state.keyword()); | |
| 51 } else if (i < keywordCount * 2) { | |
| 52 // keyword + "x" | |
| 53 JUnitTestCase.assertNull(state); | |
| 54 } else { | |
| 55 // keyword.substring(0, keyword.length() - 1) | |
| 56 JUnitTestCase.assertNotNull(state); | |
| 57 } | |
| 58 } | 34 } |
| 59 } | 35 } |
| 60 | 36 |
| 61 static dartSuite() { | 37 void _validateStream(JavaStringBuilder builder, Token token) { |
| 62 _ut.group('KeywordStateTest', () { | 38 if (token == null) { |
| 63 _ut.test('test_KeywordState', () { | 39 return; |
| 64 final __test = new KeywordStateTest(); | 40 } |
| 65 runJUnitTest(__test, __test.test_KeywordState); | 41 Token previousToken = null; |
| 66 }); | 42 int previousEnd = -1; |
| 67 }); | 43 Token currentToken = token; |
| 44 while (currentToken != null && currentToken.type != TokenType.EOF) { |
| 45 _validateStream(builder, currentToken.precedingComments); |
| 46 TokenType type = currentToken.type; |
| 47 if (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.OPEN_PAREN |
| type == TokenType.OPEN_SQUARE_BRACKET || type == TokenType.STRING_INTERPOLATIO
N_EXPRESSION) { |
| 48 if (currentToken is! BeginToken) { |
| 49 builder.append("\r\nExpected BeginToken, found "); |
| 50 builder.append(currentToken.runtimeType.toString()); |
| 51 builder.append(" "); |
| 52 _writeToken(builder, currentToken); |
| 53 } |
| 54 } |
| 55 int currentStart = currentToken.offset; |
| 56 int currentLength = currentToken.length; |
| 57 int currentEnd = currentStart + currentLength - 1; |
| 58 if (currentStart <= previousEnd) { |
| 59 builder.append("\r\nInvalid token sequence: "); |
| 60 _writeToken(builder, previousToken); |
| 61 builder.append(" followed by "); |
| 62 _writeToken(builder, currentToken); |
| 63 } |
| 64 previousEnd = currentEnd; |
| 65 previousToken = currentToken; |
| 66 currentToken = currentToken.next; |
| 67 } |
| 68 } |
| 69 |
| 70 void _writeToken(JavaStringBuilder builder, Token token) { |
| 71 builder.append("["); |
| 72 builder.append(token.type); |
| 73 builder.append(", '"); |
| 74 builder.append(token.lexeme); |
| 75 builder.append("', "); |
| 76 builder.append(token.offset); |
| 77 builder.append(", "); |
| 78 builder.append(token.length); |
| 79 builder.append("]"); |
| 68 } | 80 } |
| 69 } | 81 } |
| 70 | 82 |
| 71 class CharSequenceReaderTest extends JUnitTestCase { | 83 class CharSequenceReaderTest extends JUnitTestCase { |
| 72 void test_advance() { | 84 void test_advance() { |
| 73 CharSequenceReader reader = new CharSequenceReader("x"); | 85 CharSequenceReader reader = new CharSequenceReader("x"); |
| 74 JUnitTestCase.assertEquals(0x78, reader.advance()); | 86 JUnitTestCase.assertEquals(0x78, reader.advance()); |
| 75 JUnitTestCase.assertEquals(-1, reader.advance()); | 87 JUnitTestCase.assertEquals(-1, reader.advance()); |
| 76 JUnitTestCase.assertEquals(-1, reader.advance()); | 88 JUnitTestCase.assertEquals(-1, reader.advance()); |
| 77 } | 89 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 runJUnitTest(__test, __test.test_isOperator); | 229 runJUnitTest(__test, __test.test_isOperator); |
| 218 }); | 230 }); |
| 219 _ut.test('test_isUserDefinableOperator', () { | 231 _ut.test('test_isUserDefinableOperator', () { |
| 220 final __test = new TokenTypeTest(); | 232 final __test = new TokenTypeTest(); |
| 221 runJUnitTest(__test, __test.test_isUserDefinableOperator); | 233 runJUnitTest(__test, __test.test_isUserDefinableOperator); |
| 222 }); | 234 }); |
| 223 }); | 235 }); |
| 224 } | 236 } |
| 225 } | 237 } |
| 226 | 238 |
| 227 /** | 239 class IncrementalScannerTest extends EngineTestCase { |
| 228 * The class `TokenFactory` defines utility methods that can be used to create t
okens. | |
| 229 */ | |
| 230 class TokenFactory { | |
| 231 static Token tokenFromKeyword(Keyword keyword) => new KeywordToken(keyword, 0)
; | |
| 232 | |
| 233 static Token tokenFromString(String lexeme) => new StringToken(TokenType.STRIN
G, lexeme, 0); | |
| 234 | |
| 235 static Token tokenFromType(TokenType type) => new Token(type, 0); | |
| 236 | |
| 237 static Token tokenFromTypeAndString(TokenType type, String lexeme) => new Stri
ngToken(type, lexeme, 0); | |
| 238 } | |
| 239 | |
| 240 /** | |
| 241 * Instances of the class `TokenStreamValidator` are used to validate the correc
t construction | |
| 242 * of a stream of tokens. | |
| 243 */ | |
| 244 class TokenStreamValidator { | |
| 245 /** | 240 /** |
| 246 * Validate that the stream of tokens that starts with the given token is corr
ect. | 241 * The first token from the token stream resulting from parsing the original s
ource, or |
| 242 * `null` if [scan] has not been invoked. |
| 243 */ |
| 244 Token _originalTokens; |
| 245 |
| 246 /** |
| 247 * The scanner used to perform incremental scanning, or `null` if [scan] has n
ot been |
| 248 * invoked. |
| 249 */ |
| 250 IncrementalScanner _incrementalScanner; |
| 251 |
| 252 /** |
| 253 * The first token from the token stream resulting from performing an incremen
tal scan, or |
| 254 * `null` if [scan] has not been invoked. |
| 255 */ |
| 256 Token _incrementalTokens; |
| 257 |
| 258 void test_delete_identifier_beginning() { |
| 259 // "abs + b;" |
| 260 // "s + b;") |
| 261 _scan("", "ab", "", "s + b;"); |
| 262 _assertTokens(-1, 1, ["s", "+", "b", ";"]); |
| 263 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 264 } |
| 265 |
| 266 void test_delete_identifier_end() { |
| 267 // "abs + b;" |
| 268 // "a + b;") |
| 269 _scan("a", "bs", "", " + b;"); |
| 270 _assertTokens(-1, 1, ["a", "+", "b", ";"]); |
| 271 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 272 } |
| 273 |
| 274 void test_delete_identifier_middle() { |
| 275 // "abs + b;" |
| 276 // "as + b;") |
| 277 _scan("a", "b", "", "s + b;"); |
| 278 _assertTokens(-1, 1, ["as", "+", "b", ";"]); |
| 279 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 280 } |
| 281 |
| 282 void test_delete_mergeTokens() { |
| 283 // "a + b + c;" |
| 284 // "ac;") |
| 285 _scan("a", " + b + ", "", "c;"); |
| 286 _assertTokens(-1, 1, ["ac", ";"]); |
| 287 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 288 } |
| 289 |
| 290 void test_insert_afterIdentifier1() { |
| 291 // "a + b;" |
| 292 // "abs + b;" |
| 293 _scan("a", "", "bs", " + b;"); |
| 294 _assertTokens(-1, 1, ["abs", "+", "b", ";"]); |
| 295 _assertReplaced(1, "+"); |
| 296 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 297 } |
| 298 |
| 299 void test_insert_afterIdentifier2() { |
| 300 // "a + b;" |
| 301 // "a + by;" |
| 302 _scan("a + b", "", "y", ";"); |
| 303 _assertTokens(1, 3, ["a", "+", "by", ";"]); |
| 304 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 305 } |
| 306 |
| 307 void test_insert_beforeIdentifier() { |
| 308 // "a + b;" |
| 309 // "a + xb;") |
| 310 _scan("a + ", "", "x", "b;"); |
| 311 _assertTokens(1, 3, ["a", "+", "xb", ";"]); |
| 312 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 313 } |
| 314 |
| 315 void test_insert_beforeIdentifier_firstToken() { |
| 316 // "a + b;" |
| 317 // "xa + b;" |
| 318 _scan("", "", "x", "a + b;"); |
| 319 _assertTokens(-1, 1, ["xa", "+", "b", ";"]); |
| 320 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 321 } |
| 322 |
| 323 void test_insert_convertOneFunctionToTwo() { |
| 324 // "f() {}" |
| 325 // "f() => 0; g() {}" |
| 326 _scan("f()", "", " => 0; g()", " {}"); |
| 327 _assertTokens(2, 9, ["f", "(", ")", "=>", "0", ";", "g", "(", ")", "{", "}"]
); |
| 328 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 329 } |
| 330 |
| 331 void test_insert_end() { |
| 332 // "class A {}" |
| 333 // "class A {} class B {}" |
| 334 _scan("class A {}", "", " class B {}", ""); |
| 335 _assertTokens(3, 8, ["class", "A", "{", "}", "class", "B", "{", "}"]); |
| 336 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 337 } |
| 338 |
| 339 void test_insert_insideIdentifier() { |
| 340 // "cob;" |
| 341 // "cow.b;" |
| 342 _scan("co", "", "w.", "b;"); |
| 343 _assertTokens(-1, 3, ["cow", ".", "b", ";"]); |
| 344 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 345 } |
| 346 |
| 347 void test_insert_newIdentifier1() { |
| 348 // "a; c;" |
| 349 // "a; b c;" |
| 350 _scan("a; ", "", "b", " c;"); |
| 351 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); |
| 352 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 353 } |
| 354 |
| 355 void test_insert_newIdentifier2() { |
| 356 // "a; c;" |
| 357 // "a;b c;" |
| 358 _scan("a;", "", "b", " c;"); |
| 359 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); |
| 360 _assertReplaced(1, ";"); |
| 361 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 362 } |
| 363 |
| 364 void test_insert_period() { |
| 365 // "a + b;" |
| 366 // "a + b.;" |
| 367 _scan("a + b", "", ".", ";"); |
| 368 _assertTokens(2, 4, ["a", "+", "b", ".", ";"]); |
| 369 } |
| 370 |
| 371 void test_insert_period_betweenIdentifiers1() { |
| 372 // "a b;" |
| 373 // "a. b;" |
| 374 _scan("a", "", ".", " b;"); |
| 375 _assertTokens(0, 2, ["a", ".", "b", ";"]); |
| 376 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 377 } |
| 378 |
| 379 void test_insert_period_betweenIdentifiers2() { |
| 380 // "a b;" |
| 381 // "a .b;" |
| 382 _scan("a ", "", ".", "b;"); |
| 383 _assertTokens(0, 2, ["a", ".", "b", ";"]); |
| 384 } |
| 385 |
| 386 void test_insert_period_betweenIdentifiers3() { |
| 387 // "a b;" |
| 388 // "a . b;" |
| 389 _scan("a ", "", ".", " b;"); |
| 390 _assertTokens(0, 2, ["a", ".", "b", ";"]); |
| 391 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 392 } |
| 393 |
| 394 void test_insert_period_insideExistingIdentifier() { |
| 395 // "ab;" |
| 396 // "a.b;" |
| 397 _scan("a", "", ".", "b;"); |
| 398 _assertTokens(-1, 3, ["a", ".", "b", ";"]); |
| 399 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 400 } |
| 401 |
| 402 void test_insert_periodAndIdentifier() { |
| 403 // "a + b;" |
| 404 // "a + b.x;" |
| 405 _scan("a + b", "", ".x", ";"); |
| 406 _assertTokens(2, 5, ["a", "+", "b", ".", "x", ";"]); |
| 407 } |
| 408 |
| 409 void test_insert_whitespace_beginning_beforeToken() { |
| 410 // "a + b;" |
| 411 // " a + b;" |
| 412 _scan("", "", " ", "a + b;"); |
| 413 _assertTokens(0, 1, ["a", "+", "b", ";"]); |
| 414 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); |
| 415 } |
| 416 |
| 417 void test_insert_whitespace_betweenTokens() { |
| 418 // "a + b;" |
| 419 // "a + b;" |
| 420 _scan("a ", "", " ", "+ b;"); |
| 421 _assertTokens(1, 2, ["a", "+", "b", ";"]); |
| 422 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); |
| 423 } |
| 424 |
| 425 void test_insert_whitespace_end_afterToken() { |
| 426 // "a + b;" |
| 427 // "a + b; " |
| 428 _scan("a + b;", "", " ", ""); |
| 429 _assertTokens(3, 4, ["a", "+", "b", ";"]); |
| 430 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); |
| 431 } |
| 432 |
| 433 void test_insert_whitespace_end_afterWhitespace() { |
| 434 // "a + b; " |
| 435 // "a + b; " |
| 436 _scan("a + b; ", "", " ", ""); |
| 437 _assertTokens(3, 4, ["a", "+", "b", ";"]); |
| 438 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); |
| 439 } |
| 440 |
| 441 void test_insert_whitespace_withMultipleComments() { |
| 442 // "//comment", "//comment2", "a + b;" |
| 443 // "//comment", "//comment2", "a + b;" |
| 444 _scan(EngineTestCase.createSource(["//comment", "//comment2", "a"]), "", " "
, " + b;"); |
| 445 _assertTokens(1, 2, ["a", "+", "b", ";"]); |
| 446 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); |
| 447 } |
| 448 |
| 449 void test_replace_identifier_beginning() { |
| 450 // "bell + b;" |
| 451 // "fell + b;") |
| 452 _scan("", "b", "f", "ell + b;"); |
| 453 _assertTokens(-1, 1, ["fell", "+", "b", ";"]); |
| 454 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 455 } |
| 456 |
| 457 void test_replace_identifier_end() { |
| 458 // "bell + b;" |
| 459 // "belt + b;") |
| 460 _scan("bel", "l", "t", " + b;"); |
| 461 _assertTokens(-1, 1, ["belt", "+", "b", ";"]); |
| 462 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 463 } |
| 464 |
| 465 void test_replace_identifier_middle() { |
| 466 // "first + b;" |
| 467 // "frost + b;") |
| 468 _scan("f", "ir", "ro", "st + b;"); |
| 469 _assertTokens(-1, 1, ["frost", "+", "b", ";"]); |
| 470 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 471 } |
| 472 |
| 473 void test_replace_multiple_partialFirstAndLast() { |
| 474 // "aa + bb;" |
| 475 // "ab * ab;") |
| 476 _scan("a", "a + b", "b * a", "b;"); |
| 477 _assertTokens(-1, 3, ["ab", "*", "ab", ";"]); |
| 478 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 479 } |
| 480 |
| 481 void test_replace_operator_oneForMany() { |
| 482 // "a + b;" |
| 483 // "a * c - b;") |
| 484 _scan("a ", "+", "* c -", " b;"); |
| 485 _assertTokens(0, 4, ["a", "*", "c", "-", "b", ";"]); |
| 486 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 487 } |
| 488 |
| 489 void test_replace_operator_oneForOne() { |
| 490 // "a + b;" |
| 491 // "a * b;") |
| 492 _scan("a ", "+", "*", " b;"); |
| 493 _assertTokens(0, 2, ["a", "*", "b", ";"]); |
| 494 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); |
| 495 } |
| 496 |
| 497 void test_tokenMap() { |
| 498 // "main() {a + b;}" |
| 499 // "main() { a + b;}" |
| 500 _scan("main() {", "", " ", "a + b;}"); |
| 501 TokenMap tokenMap = _incrementalScanner.tokenMap; |
| 502 Token oldToken = _originalTokens; |
| 503 while (oldToken.type != TokenType.EOF) { |
| 504 Token newToken = tokenMap.get(oldToken); |
| 505 JUnitTestCase.assertNotSame(oldToken, newToken); |
| 506 JUnitTestCase.assertSame(oldToken.type, newToken.type); |
| 507 JUnitTestCase.assertEquals(oldToken.lexeme, newToken.lexeme); |
| 508 oldToken = oldToken.next; |
| 509 } |
| 510 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); |
| 511 } |
| 512 |
| 513 /** |
| 514 * Assert that the token at the given offset was replaced with a new token hav
ing the given |
| 515 * lexeme. |
| 247 * | 516 * |
| 248 * @param token the first token in the stream of tokens to be validated | 517 * @param tokenOffset the offset of the token being tested |
| 518 * @param lexeme the expected lexeme of the new token |
| 249 */ | 519 */ |
| 250 void validate(Token token) { | 520 void _assertReplaced(int tokenOffset, String lexeme) { |
| 251 JavaStringBuilder builder = new JavaStringBuilder(); | 521 Token oldToken = _originalTokens; |
| 252 _validateStream(builder, token); | 522 for (int i = 0; i < tokenOffset; i++) { |
| 253 if (builder.length > 0) { | 523 oldToken = oldToken.next; |
| 254 JUnitTestCase.fail(builder.toString()); | |
| 255 } | 524 } |
| 256 } | 525 JUnitTestCase.assertEquals(lexeme, oldToken.lexeme); |
| 257 | 526 Token newToken = _incrementalScanner.tokenMap.get(oldToken); |
| 258 void _validateStream(JavaStringBuilder builder, Token token) { | 527 JUnitTestCase.assertNotNull(newToken); |
| 259 if (token == null) { | 528 JUnitTestCase.assertEquals(lexeme, newToken.lexeme); |
| 260 return; | 529 JUnitTestCase.assertNotSame(oldToken, newToken); |
| 530 } |
| 531 |
| 532 /** |
| 533 * Assert that the result of the incremental scan matches the given list of le
xemes and that the |
| 534 * left and right tokens correspond to the tokens at the given indices. |
| 535 * |
| 536 * @param leftIndex the expected index of the left token |
| 537 * @param rightIndex the expected index of the right token |
| 538 * @param lexemes the expected lexemes of the resulting tokens |
| 539 */ |
| 540 void _assertTokens(int leftIndex, int rightIndex, List<String> lexemes) { |
| 541 int count = lexemes.length; |
| 542 JUnitTestCase.assertTrueMsg("Invalid left index", leftIndex >= -1 && leftInd
ex < count); |
| 543 JUnitTestCase.assertTrueMsg("Invalid right index", rightIndex >= 0 && rightI
ndex <= count); |
| 544 Token leftToken = null; |
| 545 Token rightToken = null; |
| 546 Token token = _incrementalTokens; |
| 547 if (leftIndex < 0) { |
| 548 leftToken = token.previous; |
| 261 } | 549 } |
| 262 Token previousToken = null; | 550 for (int i = 0; i < count; i++) { |
| 263 int previousEnd = -1; | 551 JUnitTestCase.assertEquals(lexemes[i], token.lexeme); |
| 264 Token currentToken = token; | 552 if (i == leftIndex) { |
| 265 while (currentToken != null && currentToken.type != TokenType.EOF) { | 553 leftToken = token; |
| 266 _validateStream(builder, currentToken.precedingComments); | |
| 267 TokenType type = currentToken.type; | |
| 268 if (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.OPEN_PAREN |
| type == TokenType.OPEN_SQUARE_BRACKET || type == TokenType.STRING_INTERPOLATIO
N_EXPRESSION) { | |
| 269 if (currentToken is! BeginToken) { | |
| 270 builder.append("\r\nExpected BeginToken, found "); | |
| 271 builder.append(currentToken.runtimeType.toString()); | |
| 272 builder.append(" "); | |
| 273 _writeToken(builder, currentToken); | |
| 274 } | |
| 275 } | 554 } |
| 276 int currentStart = currentToken.offset; | 555 if (i == rightIndex) { |
| 277 int currentLength = currentToken.length; | 556 rightToken = token; |
| 278 int currentEnd = currentStart + currentLength - 1; | |
| 279 if (currentStart <= previousEnd) { | |
| 280 builder.append("\r\nInvalid token sequence: "); | |
| 281 _writeToken(builder, previousToken); | |
| 282 builder.append(" followed by "); | |
| 283 _writeToken(builder, currentToken); | |
| 284 } | 557 } |
| 285 previousEnd = currentEnd; | 558 token = token.next; |
| 286 previousToken = currentToken; | |
| 287 currentToken = currentToken.next; | |
| 288 } | 559 } |
| 289 } | 560 if (rightIndex >= count) { |
| 290 | 561 rightToken = token; |
| 291 void _writeToken(JavaStringBuilder builder, Token token) { | 562 } |
| 292 builder.append("["); | 563 JUnitTestCase.assertSameMsg("Too many tokens", TokenType.EOF, token.type); |
| 293 builder.append(token.type); | 564 if (leftIndex >= 0) { |
| 294 builder.append(", '"); | 565 JUnitTestCase.assertNotNull(leftToken); |
| 295 builder.append(token.lexeme); | 566 } |
| 296 builder.append("', "); | 567 JUnitTestCase.assertSameMsg("Invalid left token", leftToken, _incrementalSca
nner.leftToken); |
| 297 builder.append(token.offset); | 568 if (rightIndex >= 0) { |
| 298 builder.append(", "); | 569 JUnitTestCase.assertNotNull(rightToken); |
| 299 builder.append(token.length); | 570 } |
| 300 builder.append("]"); | 571 JUnitTestCase.assertSameMsg("Invalid right token", rightToken, _incrementalS
canner.rightToken); |
| 572 } |
| 573 |
| 574 /** |
| 575 * Given a description of the original and modified contents, perform an incre
mental scan of the |
| 576 * two pieces of text. Verify that the incremental scan produced the same toke
ns as those that |
| 577 * would be produced by a full scan of the new contents. |
| 578 * |
| 579 * @param prefix the unchanged text before the edit region |
| 580 * @param removed the text that was removed from the original contents |
| 581 * @param added the text that was added to the modified contents |
| 582 * @param suffix the unchanged text after the edit region |
| 583 */ |
| 584 void _scan(String prefix, String removed, String added, String suffix) { |
| 585 // |
| 586 // Compute the information needed to perform the test. |
| 587 // |
| 588 String originalContents = "${prefix}${removed}${suffix}"; |
| 589 String modifiedContents = "${prefix}${added}${suffix}"; |
| 590 int replaceStart = prefix.length; |
| 591 Source source = new TestSource(); |
| 592 // |
| 593 // Scan the original contents. |
| 594 // |
| 595 GatheringErrorListener originalListener = new GatheringErrorListener(); |
| 596 Scanner originalScanner = new Scanner(source, new CharSequenceReader(origina
lContents), originalListener); |
| 597 _originalTokens = originalScanner.tokenize(); |
| 598 JUnitTestCase.assertNotNull(_originalTokens); |
| 599 // |
| 600 // Scan the modified contents. |
| 601 // |
| 602 GatheringErrorListener modifiedListener = new GatheringErrorListener(); |
| 603 Scanner modifiedScanner = new Scanner(source, new CharSequenceReader(modifie
dContents), modifiedListener); |
| 604 Token modifiedTokens = modifiedScanner.tokenize(); |
| 605 JUnitTestCase.assertNotNull(modifiedTokens); |
| 606 // |
| 607 // Incrementally scan the modified contents. |
| 608 // |
| 609 GatheringErrorListener incrementalListener = new GatheringErrorListener(); |
| 610 _incrementalScanner = new IncrementalScanner(source, new CharSequenceReader(
modifiedContents), incrementalListener); |
| 611 _incrementalTokens = _incrementalScanner.rescan(_originalTokens, replaceStar
t, removed.length, added.length); |
| 612 // |
| 613 // Validate that the results of the incremental scan are the same as the ful
l scan of the |
| 614 // modified source. |
| 615 // |
| 616 Token incrementalToken = _incrementalTokens; |
| 617 JUnitTestCase.assertNotNull(incrementalToken); |
| 618 while (incrementalToken.type != TokenType.EOF && modifiedTokens.type != Toke
nType.EOF) { |
| 619 JUnitTestCase.assertSameMsg("Wrong type for token", modifiedTokens.type, i
ncrementalToken.type); |
| 620 JUnitTestCase.assertEqualsMsg("Wrong offset for token", modifiedTokens.off
set, incrementalToken.offset); |
| 621 JUnitTestCase.assertEqualsMsg("Wrong length for token", modifiedTokens.len
gth, incrementalToken.length); |
| 622 JUnitTestCase.assertEqualsMsg("Wrong lexeme for token", modifiedTokens.lex
eme, incrementalToken.lexeme); |
| 623 incrementalToken = incrementalToken.next; |
| 624 modifiedTokens = modifiedTokens.next; |
| 625 } |
| 626 JUnitTestCase.assertSameMsg("Too many tokens", TokenType.EOF, incrementalTok
en.type); |
| 627 JUnitTestCase.assertSameMsg("Not enough tokens", TokenType.EOF, modifiedToke
ns.type); |
| 628 } |
| 629 |
| 630 static dartSuite() { |
| 631 _ut.group('IncrementalScannerTest', () { |
| 632 _ut.test('test_delete_identifier_beginning', () { |
| 633 final __test = new IncrementalScannerTest(); |
| 634 runJUnitTest(__test, __test.test_delete_identifier_beginning); |
| 635 }); |
| 636 _ut.test('test_delete_identifier_end', () { |
| 637 final __test = new IncrementalScannerTest(); |
| 638 runJUnitTest(__test, __test.test_delete_identifier_end); |
| 639 }); |
| 640 _ut.test('test_delete_identifier_middle', () { |
| 641 final __test = new IncrementalScannerTest(); |
| 642 runJUnitTest(__test, __test.test_delete_identifier_middle); |
| 643 }); |
| 644 _ut.test('test_delete_mergeTokens', () { |
| 645 final __test = new IncrementalScannerTest(); |
| 646 runJUnitTest(__test, __test.test_delete_mergeTokens); |
| 647 }); |
| 648 _ut.test('test_insert_afterIdentifier1', () { |
| 649 final __test = new IncrementalScannerTest(); |
| 650 runJUnitTest(__test, __test.test_insert_afterIdentifier1); |
| 651 }); |
| 652 _ut.test('test_insert_afterIdentifier2', () { |
| 653 final __test = new IncrementalScannerTest(); |
| 654 runJUnitTest(__test, __test.test_insert_afterIdentifier2); |
| 655 }); |
| 656 _ut.test('test_insert_beforeIdentifier', () { |
| 657 final __test = new IncrementalScannerTest(); |
| 658 runJUnitTest(__test, __test.test_insert_beforeIdentifier); |
| 659 }); |
| 660 _ut.test('test_insert_beforeIdentifier_firstToken', () { |
| 661 final __test = new IncrementalScannerTest(); |
| 662 runJUnitTest(__test, __test.test_insert_beforeIdentifier_firstToken); |
| 663 }); |
| 664 _ut.test('test_insert_convertOneFunctionToTwo', () { |
| 665 final __test = new IncrementalScannerTest(); |
| 666 runJUnitTest(__test, __test.test_insert_convertOneFunctionToTwo); |
| 667 }); |
| 668 _ut.test('test_insert_end', () { |
| 669 final __test = new IncrementalScannerTest(); |
| 670 runJUnitTest(__test, __test.test_insert_end); |
| 671 }); |
| 672 _ut.test('test_insert_insideIdentifier', () { |
| 673 final __test = new IncrementalScannerTest(); |
| 674 runJUnitTest(__test, __test.test_insert_insideIdentifier); |
| 675 }); |
| 676 _ut.test('test_insert_newIdentifier1', () { |
| 677 final __test = new IncrementalScannerTest(); |
| 678 runJUnitTest(__test, __test.test_insert_newIdentifier1); |
| 679 }); |
| 680 _ut.test('test_insert_newIdentifier2', () { |
| 681 final __test = new IncrementalScannerTest(); |
| 682 runJUnitTest(__test, __test.test_insert_newIdentifier2); |
| 683 }); |
| 684 _ut.test('test_insert_period', () { |
| 685 final __test = new IncrementalScannerTest(); |
| 686 runJUnitTest(__test, __test.test_insert_period); |
| 687 }); |
| 688 _ut.test('test_insert_periodAndIdentifier', () { |
| 689 final __test = new IncrementalScannerTest(); |
| 690 runJUnitTest(__test, __test.test_insert_periodAndIdentifier); |
| 691 }); |
| 692 _ut.test('test_insert_period_betweenIdentifiers1', () { |
| 693 final __test = new IncrementalScannerTest(); |
| 694 runJUnitTest(__test, __test.test_insert_period_betweenIdentifiers1); |
| 695 }); |
| 696 _ut.test('test_insert_period_betweenIdentifiers2', () { |
| 697 final __test = new IncrementalScannerTest(); |
| 698 runJUnitTest(__test, __test.test_insert_period_betweenIdentifiers2); |
| 699 }); |
| 700 _ut.test('test_insert_period_betweenIdentifiers3', () { |
| 701 final __test = new IncrementalScannerTest(); |
| 702 runJUnitTest(__test, __test.test_insert_period_betweenIdentifiers3); |
| 703 }); |
| 704 _ut.test('test_insert_period_insideExistingIdentifier', () { |
| 705 final __test = new IncrementalScannerTest(); |
| 706 runJUnitTest(__test, __test.test_insert_period_insideExistingIdentifier)
; |
| 707 }); |
| 708 _ut.test('test_insert_whitespace_beginning_beforeToken', () { |
| 709 final __test = new IncrementalScannerTest(); |
| 710 runJUnitTest(__test, __test.test_insert_whitespace_beginning_beforeToken
); |
| 711 }); |
| 712 _ut.test('test_insert_whitespace_betweenTokens', () { |
| 713 final __test = new IncrementalScannerTest(); |
| 714 runJUnitTest(__test, __test.test_insert_whitespace_betweenTokens); |
| 715 }); |
| 716 _ut.test('test_insert_whitespace_end_afterToken', () { |
| 717 final __test = new IncrementalScannerTest(); |
| 718 runJUnitTest(__test, __test.test_insert_whitespace_end_afterToken); |
| 719 }); |
| 720 _ut.test('test_insert_whitespace_end_afterWhitespace', () { |
| 721 final __test = new IncrementalScannerTest(); |
| 722 runJUnitTest(__test, __test.test_insert_whitespace_end_afterWhitespace); |
| 723 }); |
| 724 _ut.test('test_insert_whitespace_withMultipleComments', () { |
| 725 final __test = new IncrementalScannerTest(); |
| 726 runJUnitTest(__test, __test.test_insert_whitespace_withMultipleComments)
; |
| 727 }); |
| 728 _ut.test('test_replace_identifier_beginning', () { |
| 729 final __test = new IncrementalScannerTest(); |
| 730 runJUnitTest(__test, __test.test_replace_identifier_beginning); |
| 731 }); |
| 732 _ut.test('test_replace_identifier_end', () { |
| 733 final __test = new IncrementalScannerTest(); |
| 734 runJUnitTest(__test, __test.test_replace_identifier_end); |
| 735 }); |
| 736 _ut.test('test_replace_identifier_middle', () { |
| 737 final __test = new IncrementalScannerTest(); |
| 738 runJUnitTest(__test, __test.test_replace_identifier_middle); |
| 739 }); |
| 740 _ut.test('test_replace_multiple_partialFirstAndLast', () { |
| 741 final __test = new IncrementalScannerTest(); |
| 742 runJUnitTest(__test, __test.test_replace_multiple_partialFirstAndLast); |
| 743 }); |
| 744 _ut.test('test_replace_operator_oneForMany', () { |
| 745 final __test = new IncrementalScannerTest(); |
| 746 runJUnitTest(__test, __test.test_replace_operator_oneForMany); |
| 747 }); |
| 748 _ut.test('test_replace_operator_oneForOne', () { |
| 749 final __test = new IncrementalScannerTest(); |
| 750 runJUnitTest(__test, __test.test_replace_operator_oneForOne); |
| 751 }); |
| 752 _ut.test('test_tokenMap', () { |
| 753 final __test = new IncrementalScannerTest(); |
| 754 runJUnitTest(__test, __test.test_tokenMap); |
| 755 }); |
| 756 }); |
| 301 } | 757 } |
| 302 } | 758 } |
| 303 | 759 |
| 304 class ScannerTest extends JUnitTestCase { | 760 class ScannerTest extends JUnitTestCase { |
| 305 void fail_incomplete_string_interpolation() { | 761 void fail_incomplete_string_interpolation() { |
| 306 // https://code.google.com/p/dart/issues/detail?id=18073 | 762 // https://code.google.com/p/dart/issues/detail?id=18073 |
| 307 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "\"fo
o \${bar", [ | 763 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "\"fo
o \${bar", [ |
| 308 new StringToken(TokenType.STRING, "\"foo ", 0), | 764 new StringToken(TokenType.STRING, "\"foo ", 0), |
| 309 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 5), | 765 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 5), |
| 310 new StringToken(TokenType.IDENTIFIER, "bar", 7)]); | 766 new StringToken(TokenType.IDENTIFIER, "bar", 7)]); |
| (...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1919 class ScannerTest_ExpectedLocation { | 2375 class ScannerTest_ExpectedLocation { |
| 1920 final int _offset; | 2376 final int _offset; |
| 1921 | 2377 |
| 1922 final int _lineNumber; | 2378 final int _lineNumber; |
| 1923 | 2379 |
| 1924 final int _columnNumber; | 2380 final int _columnNumber; |
| 1925 | 2381 |
| 1926 ScannerTest_ExpectedLocation(this._offset, this._lineNumber, this._columnNumbe
r); | 2382 ScannerTest_ExpectedLocation(this._offset, this._lineNumber, this._columnNumbe
r); |
| 1927 } | 2383 } |
| 1928 | 2384 |
| 1929 class IncrementalScannerTest extends EngineTestCase { | 2385 class KeywordStateTest extends JUnitTestCase { |
| 1930 /** | 2386 void test_KeywordState() { |
| 1931 * The first token from the token stream resulting from parsing the original s
ource, or | 2387 // |
| 1932 * `null` if [scan] has not been invoked. | 2388 // Generate the test data to be scanned. |
| 1933 */ | 2389 // |
| 1934 Token _originalTokens; | 2390 List<Keyword> keywords = Keyword.values; |
| 1935 | 2391 int keywordCount = keywords.length; |
| 1936 /** | 2392 List<String> textToTest = new List<String>(keywordCount * 3); |
| 1937 * The scanner used to perform incremental scanning, or `null` if [scan] has n
ot been | 2393 for (int i = 0; i < keywordCount; i++) { |
| 1938 * invoked. | 2394 String syntax = keywords[i].syntax; |
| 1939 */ | 2395 textToTest[i] = syntax; |
| 1940 IncrementalScanner _incrementalScanner; | 2396 textToTest[i + keywordCount] = "${syntax}x"; |
| 1941 | 2397 textToTest[i + keywordCount * 2] = syntax.substring(0, syntax.length - 1); |
| 1942 /** | |
| 1943 * The first token from the token stream resulting from performing an incremen
tal scan, or | |
| 1944 * `null` if [scan] has not been invoked. | |
| 1945 */ | |
| 1946 Token _incrementalTokens; | |
| 1947 | |
| 1948 void test_delete_identifier_beginning() { | |
| 1949 // "abs + b;" | |
| 1950 // "s + b;") | |
| 1951 _scan("", "ab", "", "s + b;"); | |
| 1952 _assertTokens(-1, 1, ["s", "+", "b", ";"]); | |
| 1953 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 1954 } | |
| 1955 | |
| 1956 void test_delete_identifier_end() { | |
| 1957 // "abs + b;" | |
| 1958 // "a + b;") | |
| 1959 _scan("a", "bs", "", " + b;"); | |
| 1960 _assertTokens(-1, 1, ["a", "+", "b", ";"]); | |
| 1961 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 1962 } | |
| 1963 | |
| 1964 void test_delete_identifier_middle() { | |
| 1965 // "abs + b;" | |
| 1966 // "as + b;") | |
| 1967 _scan("a", "b", "", "s + b;"); | |
| 1968 _assertTokens(-1, 1, ["as", "+", "b", ";"]); | |
| 1969 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 1970 } | |
| 1971 | |
| 1972 void test_delete_mergeTokens() { | |
| 1973 // "a + b + c;" | |
| 1974 // "ac;") | |
| 1975 _scan("a", " + b + ", "", "c;"); | |
| 1976 _assertTokens(-1, 1, ["ac", ";"]); | |
| 1977 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 1978 } | |
| 1979 | |
| 1980 void test_insert_afterIdentifier1() { | |
| 1981 // "a + b;" | |
| 1982 // "abs + b;" | |
| 1983 _scan("a", "", "bs", " + b;"); | |
| 1984 _assertTokens(-1, 1, ["abs", "+", "b", ";"]); | |
| 1985 _assertReplaced(1, "+"); | |
| 1986 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 1987 } | |
| 1988 | |
| 1989 void test_insert_afterIdentifier2() { | |
| 1990 // "a + b;" | |
| 1991 // "a + by;" | |
| 1992 _scan("a + b", "", "y", ";"); | |
| 1993 _assertTokens(1, 3, ["a", "+", "by", ";"]); | |
| 1994 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 1995 } | |
| 1996 | |
| 1997 void test_insert_beforeIdentifier() { | |
| 1998 // "a + b;" | |
| 1999 // "a + xb;") | |
| 2000 _scan("a + ", "", "x", "b;"); | |
| 2001 _assertTokens(1, 3, ["a", "+", "xb", ";"]); | |
| 2002 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2003 } | |
| 2004 | |
| 2005 void test_insert_beforeIdentifier_firstToken() { | |
| 2006 // "a + b;" | |
| 2007 // "xa + b;" | |
| 2008 _scan("", "", "x", "a + b;"); | |
| 2009 _assertTokens(-1, 1, ["xa", "+", "b", ";"]); | |
| 2010 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2011 } | |
| 2012 | |
| 2013 void test_insert_convertOneFunctionToTwo() { | |
| 2014 // "f() {}" | |
| 2015 // "f() => 0; g() {}" | |
| 2016 _scan("f()", "", " => 0; g()", " {}"); | |
| 2017 _assertTokens(2, 9, ["f", "(", ")", "=>", "0", ";", "g", "(", ")", "{", "}"]
); | |
| 2018 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2019 } | |
| 2020 | |
| 2021 void test_insert_end() { | |
| 2022 // "class A {}" | |
| 2023 // "class A {} class B {}" | |
| 2024 _scan("class A {}", "", " class B {}", ""); | |
| 2025 _assertTokens(3, 8, ["class", "A", "{", "}", "class", "B", "{", "}"]); | |
| 2026 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2027 } | |
| 2028 | |
| 2029 void test_insert_insideIdentifier() { | |
| 2030 // "cob;" | |
| 2031 // "cow.b;" | |
| 2032 _scan("co", "", "w.", "b;"); | |
| 2033 _assertTokens(-1, 3, ["cow", ".", "b", ";"]); | |
| 2034 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2035 } | |
| 2036 | |
| 2037 void test_insert_newIdentifier1() { | |
| 2038 // "a; c;" | |
| 2039 // "a; b c;" | |
| 2040 _scan("a; ", "", "b", " c;"); | |
| 2041 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); | |
| 2042 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2043 } | |
| 2044 | |
| 2045 void test_insert_newIdentifier2() { | |
| 2046 // "a; c;" | |
| 2047 // "a;b c;" | |
| 2048 _scan("a;", "", "b", " c;"); | |
| 2049 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); | |
| 2050 _assertReplaced(1, ";"); | |
| 2051 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2052 } | |
| 2053 | |
| 2054 void test_insert_period() { | |
| 2055 // "a + b;" | |
| 2056 // "a + b.;" | |
| 2057 _scan("a + b", "", ".", ";"); | |
| 2058 _assertTokens(2, 4, ["a", "+", "b", ".", ";"]); | |
| 2059 } | |
| 2060 | |
| 2061 void test_insert_period_betweenIdentifiers1() { | |
| 2062 // "a b;" | |
| 2063 // "a. b;" | |
| 2064 _scan("a", "", ".", " b;"); | |
| 2065 _assertTokens(0, 2, ["a", ".", "b", ";"]); | |
| 2066 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2067 } | |
| 2068 | |
| 2069 void test_insert_period_betweenIdentifiers2() { | |
| 2070 // "a b;" | |
| 2071 // "a .b;" | |
| 2072 _scan("a ", "", ".", "b;"); | |
| 2073 _assertTokens(0, 2, ["a", ".", "b", ";"]); | |
| 2074 } | |
| 2075 | |
| 2076 void test_insert_period_betweenIdentifiers3() { | |
| 2077 // "a b;" | |
| 2078 // "a . b;" | |
| 2079 _scan("a ", "", ".", " b;"); | |
| 2080 _assertTokens(0, 2, ["a", ".", "b", ";"]); | |
| 2081 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2082 } | |
| 2083 | |
| 2084 void test_insert_period_insideExistingIdentifier() { | |
| 2085 // "ab;" | |
| 2086 // "a.b;" | |
| 2087 _scan("a", "", ".", "b;"); | |
| 2088 _assertTokens(-1, 3, ["a", ".", "b", ";"]); | |
| 2089 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2090 } | |
| 2091 | |
| 2092 void test_insert_periodAndIdentifier() { | |
| 2093 // "a + b;" | |
| 2094 // "a + b.x;" | |
| 2095 _scan("a + b", "", ".x", ";"); | |
| 2096 _assertTokens(2, 5, ["a", "+", "b", ".", "x", ";"]); | |
| 2097 } | |
| 2098 | |
| 2099 void test_insert_whitespace_beginning_beforeToken() { | |
| 2100 // "a + b;" | |
| 2101 // " a + b;" | |
| 2102 _scan("", "", " ", "a + b;"); | |
| 2103 _assertTokens(0, 1, ["a", "+", "b", ";"]); | |
| 2104 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); | |
| 2105 } | |
| 2106 | |
| 2107 void test_insert_whitespace_betweenTokens() { | |
| 2108 // "a + b;" | |
| 2109 // "a + b;" | |
| 2110 _scan("a ", "", " ", "+ b;"); | |
| 2111 _assertTokens(1, 2, ["a", "+", "b", ";"]); | |
| 2112 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); | |
| 2113 } | |
| 2114 | |
| 2115 void test_insert_whitespace_end_afterToken() { | |
| 2116 // "a + b;" | |
| 2117 // "a + b; " | |
| 2118 _scan("a + b;", "", " ", ""); | |
| 2119 _assertTokens(3, 4, ["a", "+", "b", ";"]); | |
| 2120 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); | |
| 2121 } | |
| 2122 | |
| 2123 void test_insert_whitespace_end_afterWhitespace() { | |
| 2124 // "a + b; " | |
| 2125 // "a + b; " | |
| 2126 _scan("a + b; ", "", " ", ""); | |
| 2127 _assertTokens(3, 4, ["a", "+", "b", ";"]); | |
| 2128 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); | |
| 2129 } | |
| 2130 | |
| 2131 void test_insert_whitespace_withMultipleComments() { | |
| 2132 // "//comment", "//comment2", "a + b;" | |
| 2133 // "//comment", "//comment2", "a + b;" | |
| 2134 _scan(EngineTestCase.createSource(["//comment", "//comment2", "a"]), "", " "
, " + b;"); | |
| 2135 _assertTokens(1, 2, ["a", "+", "b", ";"]); | |
| 2136 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); | |
| 2137 } | |
| 2138 | |
| 2139 void test_replace_identifier_beginning() { | |
| 2140 // "bell + b;" | |
| 2141 // "fell + b;") | |
| 2142 _scan("", "b", "f", "ell + b;"); | |
| 2143 _assertTokens(-1, 1, ["fell", "+", "b", ";"]); | |
| 2144 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2145 } | |
| 2146 | |
| 2147 void test_replace_identifier_end() { | |
| 2148 // "bell + b;" | |
| 2149 // "belt + b;") | |
| 2150 _scan("bel", "l", "t", " + b;"); | |
| 2151 _assertTokens(-1, 1, ["belt", "+", "b", ";"]); | |
| 2152 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2153 } | |
| 2154 | |
| 2155 void test_replace_identifier_middle() { | |
| 2156 // "first + b;" | |
| 2157 // "frost + b;") | |
| 2158 _scan("f", "ir", "ro", "st + b;"); | |
| 2159 _assertTokens(-1, 1, ["frost", "+", "b", ";"]); | |
| 2160 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2161 } | |
| 2162 | |
| 2163 void test_replace_multiple_partialFirstAndLast() { | |
| 2164 // "aa + bb;" | |
| 2165 // "ab * ab;") | |
| 2166 _scan("a", "a + b", "b * a", "b;"); | |
| 2167 _assertTokens(-1, 3, ["ab", "*", "ab", ";"]); | |
| 2168 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2169 } | |
| 2170 | |
| 2171 void test_replace_operator_oneForMany() { | |
| 2172 // "a + b;" | |
| 2173 // "a * c - b;") | |
| 2174 _scan("a ", "+", "* c -", " b;"); | |
| 2175 _assertTokens(0, 4, ["a", "*", "c", "-", "b", ";"]); | |
| 2176 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2177 } | |
| 2178 | |
| 2179 void test_replace_operator_oneForOne() { | |
| 2180 // "a + b;" | |
| 2181 // "a * b;") | |
| 2182 _scan("a ", "+", "*", " b;"); | |
| 2183 _assertTokens(0, 2, ["a", "*", "b", ";"]); | |
| 2184 JUnitTestCase.assertTrue(_incrementalScanner.hasNonWhitespaceChange); | |
| 2185 } | |
| 2186 | |
| 2187 void test_tokenMap() { | |
| 2188 // "main() {a + b;}" | |
| 2189 // "main() { a + b;}" | |
| 2190 _scan("main() {", "", " ", "a + b;}"); | |
| 2191 TokenMap tokenMap = _incrementalScanner.tokenMap; | |
| 2192 Token oldToken = _originalTokens; | |
| 2193 while (oldToken.type != TokenType.EOF) { | |
| 2194 Token newToken = tokenMap.get(oldToken); | |
| 2195 JUnitTestCase.assertNotSame(oldToken, newToken); | |
| 2196 JUnitTestCase.assertSame(oldToken.type, newToken.type); | |
| 2197 JUnitTestCase.assertEquals(oldToken.lexeme, newToken.lexeme); | |
| 2198 oldToken = oldToken.next; | |
| 2199 } | 2398 } |
| 2200 JUnitTestCase.assertFalse(_incrementalScanner.hasNonWhitespaceChange); | 2399 // |
| 2201 } | 2400 // Scan each of the identifiers. |
| 2202 | 2401 // |
| 2203 /** | 2402 KeywordState firstState = KeywordState.KEYWORD_STATE; |
| 2204 * Assert that the token at the given offset was replaced with a new token hav
ing the given | 2403 for (int i = 0; i < textToTest.length; i++) { |
| 2205 * lexeme. | 2404 String text = textToTest[i]; |
| 2206 * | 2405 int index = 0; |
| 2207 * @param tokenOffset the offset of the token being tested | 2406 int length = text.length; |
| 2208 * @param lexeme the expected lexeme of the new token | 2407 KeywordState state = firstState; |
| 2209 */ | 2408 while (index < length && state != null) { |
| 2210 void _assertReplaced(int tokenOffset, String lexeme) { | 2409 state = state.next(text.codeUnitAt(index)); |
| 2211 Token oldToken = _originalTokens; | 2410 index++; |
| 2212 for (int i = 0; i < tokenOffset; i++) { | 2411 } |
| 2213 oldToken = oldToken.next; | 2412 if (i < keywordCount) { |
| 2413 // keyword |
| 2414 JUnitTestCase.assertNotNull(state); |
| 2415 JUnitTestCase.assertNotNull(state.keyword()); |
| 2416 JUnitTestCase.assertEquals(keywords[i], state.keyword()); |
| 2417 } else if (i < keywordCount * 2) { |
| 2418 // keyword + "x" |
| 2419 JUnitTestCase.assertNull(state); |
| 2420 } else { |
| 2421 // keyword.substring(0, keyword.length() - 1) |
| 2422 JUnitTestCase.assertNotNull(state); |
| 2423 } |
| 2214 } | 2424 } |
| 2215 JUnitTestCase.assertEquals(lexeme, oldToken.lexeme); | |
| 2216 Token newToken = _incrementalScanner.tokenMap.get(oldToken); | |
| 2217 JUnitTestCase.assertNotNull(newToken); | |
| 2218 JUnitTestCase.assertEquals(lexeme, newToken.lexeme); | |
| 2219 JUnitTestCase.assertNotSame(oldToken, newToken); | |
| 2220 } | |
| 2221 | |
| 2222 /** | |
| 2223 * Assert that the result of the incremental scan matches the given list of le
xemes and that the | |
| 2224 * left and right tokens correspond to the tokens at the given indices. | |
| 2225 * | |
| 2226 * @param leftIndex the expected index of the left token | |
| 2227 * @param rightIndex the expected index of the right token | |
| 2228 * @param lexemes the expected lexemes of the resulting tokens | |
| 2229 */ | |
| 2230 void _assertTokens(int leftIndex, int rightIndex, List<String> lexemes) { | |
| 2231 int count = lexemes.length; | |
| 2232 JUnitTestCase.assertTrueMsg("Invalid left index", leftIndex >= -1 && leftInd
ex < count); | |
| 2233 JUnitTestCase.assertTrueMsg("Invalid right index", rightIndex >= 0 && rightI
ndex <= count); | |
| 2234 Token leftToken = null; | |
| 2235 Token rightToken = null; | |
| 2236 Token token = _incrementalTokens; | |
| 2237 if (leftIndex < 0) { | |
| 2238 leftToken = token.previous; | |
| 2239 } | |
| 2240 for (int i = 0; i < count; i++) { | |
| 2241 JUnitTestCase.assertEquals(lexemes[i], token.lexeme); | |
| 2242 if (i == leftIndex) { | |
| 2243 leftToken = token; | |
| 2244 } | |
| 2245 if (i == rightIndex) { | |
| 2246 rightToken = token; | |
| 2247 } | |
| 2248 token = token.next; | |
| 2249 } | |
| 2250 if (rightIndex >= count) { | |
| 2251 rightToken = token; | |
| 2252 } | |
| 2253 JUnitTestCase.assertSameMsg("Too many tokens", TokenType.EOF, token.type); | |
| 2254 if (leftIndex >= 0) { | |
| 2255 JUnitTestCase.assertNotNull(leftToken); | |
| 2256 } | |
| 2257 JUnitTestCase.assertSameMsg("Invalid left token", leftToken, _incrementalSca
nner.leftToken); | |
| 2258 if (rightIndex >= 0) { | |
| 2259 JUnitTestCase.assertNotNull(rightToken); | |
| 2260 } | |
| 2261 JUnitTestCase.assertSameMsg("Invalid right token", rightToken, _incrementalS
canner.rightToken); | |
| 2262 } | |
| 2263 | |
| 2264 /** | |
| 2265 * Given a description of the original and modified contents, perform an incre
mental scan of the | |
| 2266 * two pieces of text. Verify that the incremental scan produced the same toke
ns as those that | |
| 2267 * would be produced by a full scan of the new contents. | |
| 2268 * | |
| 2269 * @param prefix the unchanged text before the edit region | |
| 2270 * @param removed the text that was removed from the original contents | |
| 2271 * @param added the text that was added to the modified contents | |
| 2272 * @param suffix the unchanged text after the edit region | |
| 2273 */ | |
| 2274 void _scan(String prefix, String removed, String added, String suffix) { | |
| 2275 // | |
| 2276 // Compute the information needed to perform the test. | |
| 2277 // | |
| 2278 String originalContents = "${prefix}${removed}${suffix}"; | |
| 2279 String modifiedContents = "${prefix}${added}${suffix}"; | |
| 2280 int replaceStart = prefix.length; | |
| 2281 Source source = new TestSource(); | |
| 2282 // | |
| 2283 // Scan the original contents. | |
| 2284 // | |
| 2285 GatheringErrorListener originalListener = new GatheringErrorListener(); | |
| 2286 Scanner originalScanner = new Scanner(source, new CharSequenceReader(origina
lContents), originalListener); | |
| 2287 _originalTokens = originalScanner.tokenize(); | |
| 2288 JUnitTestCase.assertNotNull(_originalTokens); | |
| 2289 // | |
| 2290 // Scan the modified contents. | |
| 2291 // | |
| 2292 GatheringErrorListener modifiedListener = new GatheringErrorListener(); | |
| 2293 Scanner modifiedScanner = new Scanner(source, new CharSequenceReader(modifie
dContents), modifiedListener); | |
| 2294 Token modifiedTokens = modifiedScanner.tokenize(); | |
| 2295 JUnitTestCase.assertNotNull(modifiedTokens); | |
| 2296 // | |
| 2297 // Incrementally scan the modified contents. | |
| 2298 // | |
| 2299 GatheringErrorListener incrementalListener = new GatheringErrorListener(); | |
| 2300 _incrementalScanner = new IncrementalScanner(source, new CharSequenceReader(
modifiedContents), incrementalListener); | |
| 2301 _incrementalTokens = _incrementalScanner.rescan(_originalTokens, replaceStar
t, removed.length, added.length); | |
| 2302 // | |
| 2303 // Validate that the results of the incremental scan are the same as the ful
l scan of the | |
| 2304 // modified source. | |
| 2305 // | |
| 2306 Token incrementalToken = _incrementalTokens; | |
| 2307 JUnitTestCase.assertNotNull(incrementalToken); | |
| 2308 while (incrementalToken.type != TokenType.EOF && modifiedTokens.type != Toke
nType.EOF) { | |
| 2309 JUnitTestCase.assertSameMsg("Wrong type for token", modifiedTokens.type, i
ncrementalToken.type); | |
| 2310 JUnitTestCase.assertEqualsMsg("Wrong offset for token", modifiedTokens.off
set, incrementalToken.offset); | |
| 2311 JUnitTestCase.assertEqualsMsg("Wrong length for token", modifiedTokens.len
gth, incrementalToken.length); | |
| 2312 JUnitTestCase.assertEqualsMsg("Wrong lexeme for token", modifiedTokens.lex
eme, incrementalToken.lexeme); | |
| 2313 incrementalToken = incrementalToken.next; | |
| 2314 modifiedTokens = modifiedTokens.next; | |
| 2315 } | |
| 2316 JUnitTestCase.assertSameMsg("Too many tokens", TokenType.EOF, incrementalTok
en.type); | |
| 2317 JUnitTestCase.assertSameMsg("Not enough tokens", TokenType.EOF, modifiedToke
ns.type); | |
| 2318 } | 2425 } |
| 2319 | 2426 |
| 2320 static dartSuite() { | 2427 static dartSuite() { |
| 2321 _ut.group('IncrementalScannerTest', () { | 2428 _ut.group('KeywordStateTest', () { |
| 2322 _ut.test('test_delete_identifier_beginning', () { | 2429 _ut.test('test_KeywordState', () { |
| 2323 final __test = new IncrementalScannerTest(); | 2430 final __test = new KeywordStateTest(); |
| 2324 runJUnitTest(__test, __test.test_delete_identifier_beginning); | 2431 runJUnitTest(__test, __test.test_KeywordState); |
| 2325 }); | |
| 2326 _ut.test('test_delete_identifier_end', () { | |
| 2327 final __test = new IncrementalScannerTest(); | |
| 2328 runJUnitTest(__test, __test.test_delete_identifier_end); | |
| 2329 }); | |
| 2330 _ut.test('test_delete_identifier_middle', () { | |
| 2331 final __test = new IncrementalScannerTest(); | |
| 2332 runJUnitTest(__test, __test.test_delete_identifier_middle); | |
| 2333 }); | |
| 2334 _ut.test('test_delete_mergeTokens', () { | |
| 2335 final __test = new IncrementalScannerTest(); | |
| 2336 runJUnitTest(__test, __test.test_delete_mergeTokens); | |
| 2337 }); | |
| 2338 _ut.test('test_insert_afterIdentifier1', () { | |
| 2339 final __test = new IncrementalScannerTest(); | |
| 2340 runJUnitTest(__test, __test.test_insert_afterIdentifier1); | |
| 2341 }); | |
| 2342 _ut.test('test_insert_afterIdentifier2', () { | |
| 2343 final __test = new IncrementalScannerTest(); | |
| 2344 runJUnitTest(__test, __test.test_insert_afterIdentifier2); | |
| 2345 }); | |
| 2346 _ut.test('test_insert_beforeIdentifier', () { | |
| 2347 final __test = new IncrementalScannerTest(); | |
| 2348 runJUnitTest(__test, __test.test_insert_beforeIdentifier); | |
| 2349 }); | |
| 2350 _ut.test('test_insert_beforeIdentifier_firstToken', () { | |
| 2351 final __test = new IncrementalScannerTest(); | |
| 2352 runJUnitTest(__test, __test.test_insert_beforeIdentifier_firstToken); | |
| 2353 }); | |
| 2354 _ut.test('test_insert_convertOneFunctionToTwo', () { | |
| 2355 final __test = new IncrementalScannerTest(); | |
| 2356 runJUnitTest(__test, __test.test_insert_convertOneFunctionToTwo); | |
| 2357 }); | |
| 2358 _ut.test('test_insert_end', () { | |
| 2359 final __test = new IncrementalScannerTest(); | |
| 2360 runJUnitTest(__test, __test.test_insert_end); | |
| 2361 }); | |
| 2362 _ut.test('test_insert_insideIdentifier', () { | |
| 2363 final __test = new IncrementalScannerTest(); | |
| 2364 runJUnitTest(__test, __test.test_insert_insideIdentifier); | |
| 2365 }); | |
| 2366 _ut.test('test_insert_newIdentifier1', () { | |
| 2367 final __test = new IncrementalScannerTest(); | |
| 2368 runJUnitTest(__test, __test.test_insert_newIdentifier1); | |
| 2369 }); | |
| 2370 _ut.test('test_insert_newIdentifier2', () { | |
| 2371 final __test = new IncrementalScannerTest(); | |
| 2372 runJUnitTest(__test, __test.test_insert_newIdentifier2); | |
| 2373 }); | |
| 2374 _ut.test('test_insert_period', () { | |
| 2375 final __test = new IncrementalScannerTest(); | |
| 2376 runJUnitTest(__test, __test.test_insert_period); | |
| 2377 }); | |
| 2378 _ut.test('test_insert_periodAndIdentifier', () { | |
| 2379 final __test = new IncrementalScannerTest(); | |
| 2380 runJUnitTest(__test, __test.test_insert_periodAndIdentifier); | |
| 2381 }); | |
| 2382 _ut.test('test_insert_period_betweenIdentifiers1', () { | |
| 2383 final __test = new IncrementalScannerTest(); | |
| 2384 runJUnitTest(__test, __test.test_insert_period_betweenIdentifiers1); | |
| 2385 }); | |
| 2386 _ut.test('test_insert_period_betweenIdentifiers2', () { | |
| 2387 final __test = new IncrementalScannerTest(); | |
| 2388 runJUnitTest(__test, __test.test_insert_period_betweenIdentifiers2); | |
| 2389 }); | |
| 2390 _ut.test('test_insert_period_betweenIdentifiers3', () { | |
| 2391 final __test = new IncrementalScannerTest(); | |
| 2392 runJUnitTest(__test, __test.test_insert_period_betweenIdentifiers3); | |
| 2393 }); | |
| 2394 _ut.test('test_insert_period_insideExistingIdentifier', () { | |
| 2395 final __test = new IncrementalScannerTest(); | |
| 2396 runJUnitTest(__test, __test.test_insert_period_insideExistingIdentifier)
; | |
| 2397 }); | |
| 2398 _ut.test('test_insert_whitespace_beginning_beforeToken', () { | |
| 2399 final __test = new IncrementalScannerTest(); | |
| 2400 runJUnitTest(__test, __test.test_insert_whitespace_beginning_beforeToken
); | |
| 2401 }); | |
| 2402 _ut.test('test_insert_whitespace_betweenTokens', () { | |
| 2403 final __test = new IncrementalScannerTest(); | |
| 2404 runJUnitTest(__test, __test.test_insert_whitespace_betweenTokens); | |
| 2405 }); | |
| 2406 _ut.test('test_insert_whitespace_end_afterToken', () { | |
| 2407 final __test = new IncrementalScannerTest(); | |
| 2408 runJUnitTest(__test, __test.test_insert_whitespace_end_afterToken); | |
| 2409 }); | |
| 2410 _ut.test('test_insert_whitespace_end_afterWhitespace', () { | |
| 2411 final __test = new IncrementalScannerTest(); | |
| 2412 runJUnitTest(__test, __test.test_insert_whitespace_end_afterWhitespace); | |
| 2413 }); | |
| 2414 _ut.test('test_insert_whitespace_withMultipleComments', () { | |
| 2415 final __test = new IncrementalScannerTest(); | |
| 2416 runJUnitTest(__test, __test.test_insert_whitespace_withMultipleComments)
; | |
| 2417 }); | |
| 2418 _ut.test('test_replace_identifier_beginning', () { | |
| 2419 final __test = new IncrementalScannerTest(); | |
| 2420 runJUnitTest(__test, __test.test_replace_identifier_beginning); | |
| 2421 }); | |
| 2422 _ut.test('test_replace_identifier_end', () { | |
| 2423 final __test = new IncrementalScannerTest(); | |
| 2424 runJUnitTest(__test, __test.test_replace_identifier_end); | |
| 2425 }); | |
| 2426 _ut.test('test_replace_identifier_middle', () { | |
| 2427 final __test = new IncrementalScannerTest(); | |
| 2428 runJUnitTest(__test, __test.test_replace_identifier_middle); | |
| 2429 }); | |
| 2430 _ut.test('test_replace_multiple_partialFirstAndLast', () { | |
| 2431 final __test = new IncrementalScannerTest(); | |
| 2432 runJUnitTest(__test, __test.test_replace_multiple_partialFirstAndLast); | |
| 2433 }); | |
| 2434 _ut.test('test_replace_operator_oneForMany', () { | |
| 2435 final __test = new IncrementalScannerTest(); | |
| 2436 runJUnitTest(__test, __test.test_replace_operator_oneForMany); | |
| 2437 }); | |
| 2438 _ut.test('test_replace_operator_oneForOne', () { | |
| 2439 final __test = new IncrementalScannerTest(); | |
| 2440 runJUnitTest(__test, __test.test_replace_operator_oneForOne); | |
| 2441 }); | |
| 2442 _ut.test('test_tokenMap', () { | |
| 2443 final __test = new IncrementalScannerTest(); | |
| 2444 runJUnitTest(__test, __test.test_tokenMap); | |
| 2445 }); | 2432 }); |
| 2446 }); | 2433 }); |
| 2447 } | 2434 } |
| 2448 } | 2435 } |
| 2449 | 2436 |
| 2437 /** |
| 2438 * The class `TokenFactory` defines utility methods that can be used to create t
okens. |
| 2439 */ |
| 2440 class TokenFactory { |
| 2441 static Token tokenFromKeyword(Keyword keyword) => new KeywordToken(keyword, 0)
; |
| 2442 |
| 2443 static Token tokenFromString(String lexeme) => new StringToken(TokenType.STRIN
G, lexeme, 0); |
| 2444 |
| 2445 static Token tokenFromType(TokenType type) => new Token(type, 0); |
| 2446 |
| 2447 static Token tokenFromTypeAndString(TokenType type, String lexeme) => new Stri
ngToken(type, lexeme, 0); |
| 2448 } |
| 2449 |
| 2450 main() { | 2450 main() { |
| 2451 CharSequenceReaderTest.dartSuite(); | 2451 CharSequenceReaderTest.dartSuite(); |
| 2452 IncrementalScannerTest.dartSuite(); | 2452 IncrementalScannerTest.dartSuite(); |
| 2453 KeywordStateTest.dartSuite(); | 2453 KeywordStateTest.dartSuite(); |
| 2454 ScannerTest.dartSuite(); | 2454 ScannerTest.dartSuite(); |
| 2455 TokenTypeTest.dartSuite(); | 2455 TokenTypeTest.dartSuite(); |
| 2456 } | 2456 } |
| OLD | NEW |