| 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 library engine.incremental_scanner_test; | 5 library engine.incremental_scanner_test; |
| 6 | 6 |
| 7 import 'package:analyzer/src/generated/incremental_scanner.dart'; | 7 import 'package:analyzer/src/generated/incremental_scanner.dart'; |
| 8 import 'package:analyzer/src/generated/scanner.dart'; | 8 import 'package:analyzer/src/generated/scanner.dart'; |
| 9 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
| 10 import 'package:unittest/unittest.dart'; | 10 import 'package:unittest/unittest.dart'; |
| 11 | 11 |
| 12 import '../reflective_tests.dart'; | 12 import '../reflective_tests.dart'; |
| 13 import 'test_support.dart'; | 13 import 'test_support.dart'; |
| 14 | 14 |
| 15 | |
| 16 main() { | 15 main() { |
| 17 groupSep = ' | '; | 16 groupSep = ' | '; |
| 18 runReflectiveTests(IncrementalScannerTest); | 17 runReflectiveTests(IncrementalScannerTest); |
| 19 } | 18 } |
| 20 | 19 |
| 21 class IncrementalScannerTest extends EngineTestCase { | 20 class IncrementalScannerTest extends EngineTestCase { |
| 22 /** | 21 /** |
| 23 * The first token from the token stream resulting from parsing the original | 22 * The first token from the token stream resulting from parsing the original |
| 24 * source, or `null` if [scan] has not been invoked. | 23 * source, or `null` if [scan] has not been invoked. |
| 25 */ | 24 */ |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 _scan("ca", "", "r", "t;"); | 179 _scan("ca", "", "r", "t;"); |
| 181 _assertTokens(-1, 1, ["cart", ";"]); | 180 _assertTokens(-1, 1, ["cart", ";"]); |
| 182 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 181 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
| 183 } | 182 } |
| 184 | 183 |
| 185 void test_insert_inIdentifier_right_firstToken() { | 184 void test_insert_inIdentifier_right_firstToken() { |
| 186 // "a + b;" | 185 // "a + b;" |
| 187 // "abs + b;" | 186 // "abs + b;" |
| 188 _scan("a", "", "bs", " + b;"); | 187 _scan("a", "", "bs", " + b;"); |
| 189 _assertTokens(-1, 1, ["abs", "+", "b", ";"]); | 188 _assertTokens(-1, 1, ["abs", "+", "b", ";"]); |
| 190 _assertReplaced(1, "+"); | |
| 191 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 189 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
| 192 } | 190 } |
| 193 | 191 |
| 194 void test_insert_inIdentifier_right_lastToken() { | 192 void test_insert_inIdentifier_right_lastToken() { |
| 195 // "a + b" | 193 // "a + b" |
| 196 // "a + bc" | 194 // "a + bc" |
| 197 _scan("a + b", "", "c", ""); | 195 _scan("a + b", "", "c", ""); |
| 198 _assertTokens(1, 3, ["a", "+", "bc"]); | 196 _assertTokens(1, 3, ["a", "+", "bc"]); |
| 199 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 197 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
| 200 } | 198 } |
| 201 | 199 |
| 202 void test_insert_inIdentifier_right_middleToken() { | 200 void test_insert_inIdentifier_right_middleToken() { |
| 203 // "a + b;" | 201 // "a + b;" |
| 204 // "a + by;" | 202 // "a + by;" |
| 205 _scan("a + b", "", "y", ";"); | 203 _scan("a + b", "", "y", ";"); |
| 206 _assertTokens(1, 3, ["a", "+", "by", ";"]); | 204 _assertTokens(1, 3, ["a", "+", "by", ";"]); |
| 207 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 205 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
| 208 } | 206 } |
| 209 | 207 |
| 210 void test_insert_newIdentifier_noSpaceBefore() { | 208 void test_insert_newIdentifier_noSpaceBefore() { |
| 211 // "a; c;" | 209 // "a; c;" |
| 212 // "a;b c;" | 210 // "a;b c;" |
| 213 _scan("a;", "", "b", " c;"); | 211 _scan("a;", "", "b", " c;"); |
| 214 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); | 212 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); |
| 215 _assertReplaced(1, ";"); | |
| 216 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 213 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
| 217 } | 214 } |
| 218 | 215 |
| 219 void test_insert_newIdentifier_spaceBefore() { | 216 void test_insert_newIdentifier_spaceBefore() { |
| 220 // "a; c;" | 217 // "a; c;" |
| 221 // "a; b c;" | 218 // "a; b c;" |
| 222 _scan("a; ", "", "b ", "c;"); | 219 _scan("a; ", "", "b ", "c;"); |
| 223 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); | 220 _assertTokens(1, 3, ["a", ";", "b", "c", ";"]); |
| 224 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 221 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
| 225 } | 222 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 | 300 |
| 304 void test_insert_whitespace_end_afterWhitespace() { | 301 void test_insert_whitespace_end_afterWhitespace() { |
| 305 // "a + b; " | 302 // "a + b; " |
| 306 // "a + b; " | 303 // "a + b; " |
| 307 _scan("a + b; ", "", " ", ""); | 304 _scan("a + b; ", "", " ", ""); |
| 308 _assertTokens(3, 4, ["a", "+", "b", ";"]); | 305 _assertTokens(3, 4, ["a", "+", "b", ";"]); |
| 309 expect(_incrementalScanner.hasNonWhitespaceChange, isFalse); | 306 expect(_incrementalScanner.hasNonWhitespaceChange, isFalse); |
| 310 } | 307 } |
| 311 | 308 |
| 312 void test_insert_whitespace_withMultipleComments() { | 309 void test_insert_whitespace_withMultipleComments() { |
| 313 // "//comment", "//comment2", "a + b;" | 310 // "//comment1", "//comment2", "a + b;" |
| 314 // "//comment", "//comment2", "a + b;" | 311 // "//comment1", "//comment2", "a + b;" |
| 315 _scan(r''' | 312 _scan(r''' |
| 316 //comment | 313 //comment1 |
| 317 //comment2 | 314 //comment2 |
| 318 a''', "", " ", " + b;"); | 315 a''', "", " ", " + b;"); |
| 319 _assertTokens(1, 2, ["a", "+", "b", ";"]); | 316 _assertTokens(1, 2, ["a", "+", "b", ";"]); |
| 320 expect(_incrementalScanner.hasNonWhitespaceChange, isFalse); | 317 expect(_incrementalScanner.hasNonWhitespaceChange, isFalse); |
| 321 } | 318 } |
| 322 | 319 |
| 323 void test_replace_identifier_beginning() { | 320 void test_replace_identifier_beginning() { |
| 324 // "bell + b;" | 321 // "bell + b;" |
| 325 // "fell + b;" | 322 // "fell + b;" |
| 326 _scan("", "b", "f", "ell + b;"); | 323 _scan("", "b", "f", "ell + b;"); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 if (comment != null) { | 394 if (comment != null) { |
| 398 while (comment != null) { | 395 while (comment != null) { |
| 399 count++; | 396 count++; |
| 400 comment = comment.next; | 397 comment = comment.next; |
| 401 } | 398 } |
| 402 fail("Expected ${lexemes.length} comments but found $count"); | 399 fail("Expected ${lexemes.length} comments but found $count"); |
| 403 } | 400 } |
| 404 } | 401 } |
| 405 | 402 |
| 406 /** | 403 /** |
| 407 * Assert that the token at the given [offset] was replaced with a new token | 404 * Assert that the [expected] token is equal to the [actual] token. |
| 408 * having the given [lexeme]. | |
| 409 */ | 405 */ |
| 410 void _assertReplaced(int offset, String lexeme) { | 406 void _assertEqualTokens(Token actual, Token expected) { |
| 411 Token oldToken = _originalTokens; | 407 expect(actual.type, same(expected.type), reason: "Wrong type for token"); |
| 412 for (int i = 0; i < offset; i++) { | 408 expect(actual.lexeme, expected.lexeme, reason: "Wrong lexeme for token"); |
| 413 oldToken = oldToken.next; | 409 expect( |
| 414 } | 410 actual.offset, |
| 415 expect(oldToken.lexeme, lexeme); | 411 expected.offset, |
| 416 Token newToken = _incrementalScanner.tokenMap.get(oldToken); | 412 reason: "Wrong offset for token ('${actual.lexeme}' != '${expected.lexem
e}')"); |
| 417 expect(newToken, isNotNull); | 413 expect( |
| 418 expect(newToken.lexeme, lexeme); | 414 actual.length, |
| 419 expect(newToken, isNot(same(oldToken))); | 415 expected.length, |
| 416 reason: "Wrong length for token ('${actual.lexeme}' != '${expected.lexem
e}')"); |
| 420 } | 417 } |
| 421 | 418 |
| 422 /** | 419 /** |
| 423 * Assert that the result of the incremental scan matches the given list of | 420 * Assert that the result of the incremental scan matches the given list of |
| 424 * [lexemes] and that the left and right tokens correspond to the tokens at | 421 * [lexemes] and that the left and right tokens correspond to the tokens at |
| 425 * the [leftIndex] and [rightIndex]. | 422 * the [leftIndex] and [rightIndex]. |
| 426 */ | 423 */ |
| 427 void _assertTokens(int leftIndex, int rightIndex, List<String> lexemes) { | 424 void _assertTokens(int leftIndex, int rightIndex, List<String> lexemes) { |
| 428 int count = lexemes.length; | 425 int count = lexemes.length; |
| 429 expect( | 426 expect( |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 removed.length, | 519 removed.length, |
| 523 added.length); | 520 added.length); |
| 524 // | 521 // |
| 525 // Validate that the results of the incremental scan are the same as the | 522 // Validate that the results of the incremental scan are the same as the |
| 526 // full scan of the modified source. | 523 // full scan of the modified source. |
| 527 // | 524 // |
| 528 Token incrementalToken = _incrementalTokens; | 525 Token incrementalToken = _incrementalTokens; |
| 529 expect(incrementalToken, isNotNull); | 526 expect(incrementalToken, isNotNull); |
| 530 while (incrementalToken.type != TokenType.EOF && | 527 while (incrementalToken.type != TokenType.EOF && |
| 531 modifiedTokens.type != TokenType.EOF) { | 528 modifiedTokens.type != TokenType.EOF) { |
| 529 _assertEqualTokens(incrementalToken, modifiedTokens); |
| 530 Token incrementalComment = incrementalToken.precedingComments; |
| 531 Token modifiedComment = modifiedTokens.precedingComments; |
| 532 while (incrementalComment != null && modifiedComment != null) { |
| 533 _assertEqualTokens(incrementalComment, modifiedComment); |
| 534 incrementalComment = incrementalComment.next; |
| 535 modifiedComment = modifiedComment.next; |
| 536 } |
| 532 expect( | 537 expect( |
| 533 incrementalToken.type, | 538 incrementalComment, |
| 534 same(modifiedTokens.type), | 539 isNull, |
| 535 reason: "Wrong type for token"); | 540 reason: "Too many comment tokens preceeding '${incrementalToken.lexeme
}'"); |
| 536 expect( | 541 expect( |
| 537 incrementalToken.offset, | 542 modifiedComment, |
| 538 modifiedTokens.offset, | 543 isNull, |
| 539 reason: | 544 reason: "Not enough comment tokens preceeding '${incrementalToken.lexe
me}'"); |
| 540 "Wrong offset for token (${incrementalToken.lexeme} != ${modifiedT
okens.lexeme})"); | |
| 541 expect( | |
| 542 incrementalToken.length, | |
| 543 modifiedTokens.length, | |
| 544 reason: | |
| 545 "Wrong length for token (${incrementalToken.lexeme} != ${modifiedT
okens.lexeme})"); | |
| 546 expect( | |
| 547 incrementalToken.lexeme, | |
| 548 modifiedTokens.lexeme, | |
| 549 reason: "Wrong lexeme for token"); | |
| 550 incrementalToken = incrementalToken.next; | 545 incrementalToken = incrementalToken.next; |
| 551 modifiedTokens = modifiedTokens.next; | 546 modifiedTokens = modifiedTokens.next; |
| 552 } | 547 } |
| 553 expect( | 548 expect( |
| 554 incrementalToken.type, | 549 incrementalToken.type, |
| 555 same(TokenType.EOF), | 550 same(TokenType.EOF), |
| 556 reason: "Too many tokens"); | 551 reason: "Too many tokens"); |
| 557 expect( | 552 expect( |
| 558 modifiedTokens.type, | 553 modifiedTokens.type, |
| 559 same(TokenType.EOF), | 554 same(TokenType.EOF), |
| 560 reason: "Not enough tokens"); | 555 reason: "Not enough tokens"); |
| 561 // TODO(brianwilkerson) Verify that the errors are correct? | 556 // TODO(brianwilkerson) Verify that the errors are correct? |
| 562 } | 557 } |
| 563 } | 558 } |
| OLD | NEW |