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/source.dart'; | |
11 import 'package:analyzer/src/generated/error.dart'; | 10 import 'package:analyzer/src/generated/error.dart'; |
12 import 'package:analyzer/src/generated/scanner.dart'; | 11 import 'package:analyzer/src/generated/scanner.dart'; |
| 12 import 'package:analyzer/src/generated/source.dart'; |
13 import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap; | 13 import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap; |
14 import 'package:unittest/unittest.dart'; | 14 import 'package:unittest/unittest.dart'; |
| 15 |
| 16 import '../reflective_tests.dart'; |
15 import 'test_support.dart'; | 17 import 'test_support.dart'; |
16 import '../reflective_tests.dart'; | |
17 | 18 |
18 | 19 |
| 20 main() { |
| 21 groupSep = ' | '; |
| 22 runReflectiveTests(CharSequenceReaderTest); |
| 23 runReflectiveTests(IncrementalScannerTest); |
| 24 runReflectiveTests(KeywordStateTest); |
| 25 runReflectiveTests(ScannerTest); |
| 26 runReflectiveTests(TokenTypeTest); |
| 27 } |
| 28 |
19 class CharSequenceReaderTest { | 29 class CharSequenceReaderTest { |
20 void test_advance() { | 30 void test_advance() { |
21 CharSequenceReader reader = new CharSequenceReader("x"); | 31 CharSequenceReader reader = new CharSequenceReader("x"); |
22 expect(reader.advance(), 0x78); | 32 expect(reader.advance(), 0x78); |
23 expect(reader.advance(), -1); | 33 expect(reader.advance(), -1); |
24 expect(reader.advance(), -1); | 34 expect(reader.advance(), -1); |
25 } | 35 } |
26 | 36 |
27 void test_creation() { | 37 void test_creation() { |
28 expect(new CharSequenceReader("x"), isNotNull); | 38 expect(new CharSequenceReader("x"), isNotNull); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 IncrementalScanner _incrementalScanner; | 87 IncrementalScanner _incrementalScanner; |
78 | 88 |
79 /** | 89 /** |
80 * The first token from the token stream resulting from performing an | 90 * The first token from the token stream resulting from performing an |
81 * incremental scan, or `null` if [scan] has not been invoked. | 91 * incremental scan, or `null` if [scan] has not been invoked. |
82 */ | 92 */ |
83 Token _incrementalTokens; | 93 Token _incrementalTokens; |
84 | 94 |
85 void fail_insert_beginning() { | 95 void fail_insert_beginning() { |
86 // This is currently reporting the changed range as being from 0 to 5, but | 96 // This is currently reporting the changed range as being from 0 to 5, but |
87 // that would force us to re-parse both classes, which is clearly sub-optima
l. | 97 // that would force us to re-parse both classes, which is clearly |
| 98 // sub-optimal. |
88 // | 99 // |
89 // "class B {}" | 100 // "class B {}" |
90 // "class A {} class B {}" | 101 // "class A {} class B {}" |
91 _scan("", "", "class A {} ", "class B {}"); | 102 _scan("", "", "class A {} ", "class B {}"); |
92 _assertTokens(-1, 4, ["class", "A", "{", "}", "class", "B", "{", "}"]); | 103 _assertTokens(-1, 4, ["class", "A", "{", "}", "class", "B", "{", "}"]); |
93 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 104 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
94 } | 105 } |
95 | 106 |
96 void test_delete_identifier_beginning() { | 107 void test_delete_identifier_beginning() { |
97 // "abs + b;" | 108 // "abs + b;" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 // "xa + b;" | 182 // "xa + b;" |
172 _scan("", "", "x", "a + b;"); | 183 _scan("", "", "x", "a + b;"); |
173 _assertTokens(-1, 1, ["xa", "+", "b", ";"]); | 184 _assertTokens(-1, 1, ["xa", "+", "b", ";"]); |
174 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 185 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
175 } | 186 } |
176 | 187 |
177 void test_insert_convertOneFunctionToTwo() { | 188 void test_insert_convertOneFunctionToTwo() { |
178 // "f() {}" | 189 // "f() {}" |
179 // "f() => 0; g() {}" | 190 // "f() => 0; g() {}" |
180 _scan("f()", "", " => 0; g()", " {}"); | 191 _scan("f()", "", " => 0; g()", " {}"); |
181 _assertTokens(2, 9, ["f", "(", ")", "=>", "0", ";", "g", "(", ")", "{", "}"]
); | 192 _assertTokens( |
| 193 2, |
| 194 9, |
| 195 ["f", "(", ")", "=>", "0", ";", "g", "(", ")", "{", "}"]); |
182 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 196 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
183 } | 197 } |
184 | 198 |
185 void test_insert_convertOneFunctionToTwo_overlap() { | 199 void test_insert_convertOneFunctionToTwo_overlap() { |
186 // "f() {}" | 200 // "f() {}" |
187 // "f() {} g() {}" | 201 // "f() {} g() {}" |
188 _scan("f() {", "", "} g() {", "}"); | 202 _scan("f() {", "", "} g() {", "}"); |
189 _assertTokens(4, 10, ["f", "(", ")", "{", "}", "g", "(", ")", "{", "}"]); | 203 _assertTokens(4, 10, ["f", "(", ")", "{", "}", "g", "(", ")", "{", "}"]); |
190 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); | 204 expect(_incrementalScanner.hasNonWhitespaceChange, isTrue); |
191 } | 205 } |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 _originalTokens, | 506 _originalTokens, |
493 replaceStart, | 507 replaceStart, |
494 removed.length, | 508 removed.length, |
495 added.length); | 509 added.length); |
496 // | 510 // |
497 // Validate that the results of the incremental scan are the same as the | 511 // Validate that the results of the incremental scan are the same as the |
498 // full scan of the modified source. | 512 // full scan of the modified source. |
499 // | 513 // |
500 Token incrementalToken = _incrementalTokens; | 514 Token incrementalToken = _incrementalTokens; |
501 expect(incrementalToken, isNotNull); | 515 expect(incrementalToken, isNotNull); |
502 while (incrementalToken.type != TokenType.EOF | 516 while (incrementalToken.type != TokenType.EOF && |
503 && modifiedTokens.type != TokenType.EOF) { | 517 modifiedTokens.type != TokenType.EOF) { |
504 expect( | 518 expect( |
505 incrementalToken.type, | 519 incrementalToken.type, |
506 same(modifiedTokens.type), | 520 same(modifiedTokens.type), |
507 reason: "Wrong type for token"); | 521 reason: "Wrong type for token"); |
508 expect( | 522 expect( |
509 incrementalToken.offset, | 523 incrementalToken.offset, |
510 modifiedTokens.offset, | 524 modifiedTokens.offset, |
511 reason: "Wrong offset for token"); | 525 reason: "Wrong offset for token"); |
512 expect( | 526 expect( |
513 incrementalToken.length, | 527 incrementalToken.length, |
514 modifiedTokens.length, | 528 modifiedTokens.length, |
515 reason: "Wrong length for token"); | 529 reason: "Wrong length for token"); |
516 expect( | 530 expect( |
517 incrementalToken.lexeme, | 531 incrementalToken.lexeme, |
518 modifiedTokens.lexeme, | 532 modifiedTokens.lexeme, |
519 reason: "Wrong lexeme for token"); | 533 reason: "Wrong lexeme for token"); |
520 incrementalToken = incrementalToken.next; | 534 incrementalToken = incrementalToken.next; |
521 modifiedTokens = modifiedTokens.next; | 535 modifiedTokens = modifiedTokens.next; |
522 } | 536 } |
523 expect( | 537 expect( |
524 incrementalToken.type, | 538 incrementalToken.type, |
525 same(TokenType.EOF), | 539 same(TokenType.EOF), |
526 reason: "Too many tokens"); | 540 reason: "Too many tokens"); |
527 expect( | 541 expect( |
528 modifiedTokens.type, | 542 modifiedTokens.type, |
529 same(TokenType.EOF), | 543 same(TokenType.EOF), |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 // keyword.substring(0, keyword.length() - 1) | 585 // keyword.substring(0, keyword.length() - 1) |
572 expect(state, isNotNull); | 586 expect(state, isNotNull); |
573 } | 587 } |
574 } | 588 } |
575 } | 589 } |
576 } | 590 } |
577 | 591 |
578 class ScannerTest { | 592 class ScannerTest { |
579 void fail_incomplete_string_interpolation() { | 593 void fail_incomplete_string_interpolation() { |
580 // https://code.google.com/p/dart/issues/detail?id=18073 | 594 // https://code.google.com/p/dart/issues/detail?id=18073 |
581 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "\"fo
o \${bar", [ | 595 _assertErrorAndTokens( |
582 new StringToken(TokenType.STRING, "\"foo ", 0), | 596 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
583 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 5), | 597 9, |
584 new StringToken(TokenType.IDENTIFIER, "bar", 7)]); | 598 "\"foo \${bar", |
| 599 [ |
| 600 new StringToken(TokenType.STRING, "\"foo ", 0), |
| 601 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 5)
, |
| 602 new StringToken(TokenType.IDENTIFIER, "bar", 7)]); |
585 } | 603 } |
586 | 604 |
587 void test_ampersand() { | 605 void test_ampersand() { |
588 _assertToken(TokenType.AMPERSAND, "&"); | 606 _assertToken(TokenType.AMPERSAND, "&"); |
589 } | 607 } |
590 | 608 |
591 void test_ampersand_ampersand() { | 609 void test_ampersand_ampersand() { |
592 _assertToken(TokenType.AMPERSAND_AMPERSAND, "&&"); | 610 _assertToken(TokenType.AMPERSAND_AMPERSAND, "&&"); |
593 } | 611 } |
594 | 612 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 | 668 |
651 void test_colon() { | 669 void test_colon() { |
652 _assertToken(TokenType.COLON, ":"); | 670 _assertToken(TokenType.COLON, ":"); |
653 } | 671 } |
654 | 672 |
655 void test_comma() { | 673 void test_comma() { |
656 _assertToken(TokenType.COMMA, ","); | 674 _assertToken(TokenType.COMMA, ","); |
657 } | 675 } |
658 | 676 |
659 void test_comment_disabled_multi() { | 677 void test_comment_disabled_multi() { |
660 Scanner scanner = new Scanner(null, new CharSequenceReader("/* comment */ ")
, AnalysisErrorListener.NULL_LISTENER); | 678 Scanner scanner = new Scanner( |
| 679 null, |
| 680 new CharSequenceReader("/* comment */ "), |
| 681 AnalysisErrorListener.NULL_LISTENER); |
661 scanner.preserveComments = false; | 682 scanner.preserveComments = false; |
662 Token token = scanner.tokenize(); | 683 Token token = scanner.tokenize(); |
663 expect(token, isNotNull); | 684 expect(token, isNotNull); |
664 expect(token.precedingComments, isNull); | 685 expect(token.precedingComments, isNull); |
665 } | 686 } |
666 | 687 |
667 void test_comment_multi() { | 688 void test_comment_multi() { |
668 _assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment */"); | 689 _assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment */"); |
669 } | 690 } |
670 | 691 |
671 void test_comment_multi_unterminated() { | 692 void test_comment_multi_unterminated() { |
672 _assertError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, 3, "/* x"); | 693 _assertError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, 3, "/* x"); |
673 } | 694 } |
674 | 695 |
675 void test_comment_nested() { | 696 void test_comment_nested() { |
676 _assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment /* within a */ comm
ent */"); | 697 _assertComment( |
| 698 TokenType.MULTI_LINE_COMMENT, |
| 699 "/* comment /* within a */ comment */"); |
677 } | 700 } |
678 | 701 |
679 void test_comment_single() { | 702 void test_comment_single() { |
680 _assertComment(TokenType.SINGLE_LINE_COMMENT, "// comment"); | 703 _assertComment(TokenType.SINGLE_LINE_COMMENT, "// comment"); |
681 } | 704 } |
682 | 705 |
683 void test_double_both_e() { | 706 void test_double_both_e() { |
684 _assertToken(TokenType.DOUBLE, "0.123e4"); | 707 _assertToken(TokenType.DOUBLE, "0.123e4"); |
685 } | 708 } |
686 | 709 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 void test_keyword_while() { | 994 void test_keyword_while() { |
972 _assertKeywordToken("while"); | 995 _assertKeywordToken("while"); |
973 } | 996 } |
974 | 997 |
975 void test_keyword_with() { | 998 void test_keyword_with() { |
976 _assertKeywordToken("with"); | 999 _assertKeywordToken("with"); |
977 } | 1000 } |
978 | 1001 |
979 void test_lineInfo_multilineComment() { | 1002 void test_lineInfo_multilineComment() { |
980 String source = "/*\r *\r */"; | 1003 String source = "/*\r *\r */"; |
981 _assertLineInfo(source, [ | 1004 _assertLineInfo( |
982 new ScannerTest_ExpectedLocation(0, 1, 1), | 1005 source, |
983 new ScannerTest_ExpectedLocation(4, 2, 2), | 1006 [ |
984 new ScannerTest_ExpectedLocation(source.length - 1, 3, 3)]); | 1007 new ScannerTest_ExpectedLocation(0, 1, 1), |
| 1008 new ScannerTest_ExpectedLocation(4, 2, 2), |
| 1009 new ScannerTest_ExpectedLocation(source.length - 1, 3, 3)]); |
985 } | 1010 } |
986 | 1011 |
987 void test_lineInfo_multilineString() { | 1012 void test_lineInfo_multilineString() { |
988 String source = "'''a\r\nbc\r\nd'''"; | 1013 String source = "'''a\r\nbc\r\nd'''"; |
989 _assertLineInfo(source, [ | 1014 _assertLineInfo( |
990 new ScannerTest_ExpectedLocation(0, 1, 1), | 1015 source, |
991 new ScannerTest_ExpectedLocation(7, 2, 2), | 1016 [ |
992 new ScannerTest_ExpectedLocation(source.length - 1, 3, 4)]); | 1017 new ScannerTest_ExpectedLocation(0, 1, 1), |
| 1018 new ScannerTest_ExpectedLocation(7, 2, 2), |
| 1019 new ScannerTest_ExpectedLocation(source.length - 1, 3, 4)]); |
993 } | 1020 } |
994 | 1021 |
995 void test_lineInfo_simpleClass() { | 1022 void test_lineInfo_simpleClass() { |
996 String source = "class Test {\r\n String s = '...';\r\n int get x => s
.MISSING_GETTER;\r\n}"; | 1023 String source = |
997 _assertLineInfo(source, [ | 1024 "class Test {\r\n String s = '...';\r\n int get x => s.MISSING_GET
TER;\r\n}"; |
998 new ScannerTest_ExpectedLocation(0, 1, 1), | 1025 _assertLineInfo( |
999 new ScannerTest_ExpectedLocation(source.indexOf("MISSING_GETTER"), 3, 20
), | 1026 source, |
1000 new ScannerTest_ExpectedLocation(source.length - 1, 4, 1)]); | 1027 [ |
| 1028 new ScannerTest_ExpectedLocation(0, 1, 1), |
| 1029 new ScannerTest_ExpectedLocation(source.indexOf("MISSING_GETTER"), 3
, 20), |
| 1030 new ScannerTest_ExpectedLocation(source.length - 1, 4, 1)]); |
1001 } | 1031 } |
1002 | 1032 |
1003 void test_lineInfo_slashN() { | 1033 void test_lineInfo_slashN() { |
1004 String source = "class Test {\n}"; | 1034 String source = "class Test {\n}"; |
1005 _assertLineInfo(source, [ | 1035 _assertLineInfo( |
1006 new ScannerTest_ExpectedLocation(0, 1, 1), | 1036 source, |
1007 new ScannerTest_ExpectedLocation(source.indexOf("}"), 2, 1)]); | 1037 [ |
| 1038 new ScannerTest_ExpectedLocation(0, 1, 1), |
| 1039 new ScannerTest_ExpectedLocation(source.indexOf("}"), 2, 1)]); |
1008 } | 1040 } |
1009 | 1041 |
1010 void test_lt() { | 1042 void test_lt() { |
1011 _assertToken(TokenType.LT, "<"); | 1043 _assertToken(TokenType.LT, "<"); |
1012 } | 1044 } |
1013 | 1045 |
1014 void test_lt_eq() { | 1046 void test_lt_eq() { |
1015 _assertToken(TokenType.LT_EQ, "<="); | 1047 _assertToken(TokenType.LT_EQ, "<="); |
1016 } | 1048 } |
1017 | 1049 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 | 1097 |
1066 void test_period_period() { | 1098 void test_period_period() { |
1067 _assertToken(TokenType.PERIOD_PERIOD, ".."); | 1099 _assertToken(TokenType.PERIOD_PERIOD, ".."); |
1068 } | 1100 } |
1069 | 1101 |
1070 void test_period_period_period() { | 1102 void test_period_period_period() { |
1071 _assertToken(TokenType.PERIOD_PERIOD_PERIOD, "..."); | 1103 _assertToken(TokenType.PERIOD_PERIOD_PERIOD, "..."); |
1072 } | 1104 } |
1073 | 1105 |
1074 void test_periodAfterNumberNotIncluded_identifier() { | 1106 void test_periodAfterNumberNotIncluded_identifier() { |
1075 _assertTokens("42.isEven()", [ | 1107 _assertTokens( |
1076 new StringToken(TokenType.INT, "42", 0), | 1108 "42.isEven()", |
1077 new Token(TokenType.PERIOD, 2), | 1109 [ |
1078 new StringToken(TokenType.IDENTIFIER, "isEven", 3), | 1110 new StringToken(TokenType.INT, "42", 0), |
1079 new Token(TokenType.OPEN_PAREN, 9), | 1111 new Token(TokenType.PERIOD, 2), |
1080 new Token(TokenType.CLOSE_PAREN, 10)]); | 1112 new StringToken(TokenType.IDENTIFIER, "isEven", 3), |
| 1113 new Token(TokenType.OPEN_PAREN, 9), |
| 1114 new Token(TokenType.CLOSE_PAREN, 10)]); |
1081 } | 1115 } |
1082 | 1116 |
1083 void test_periodAfterNumberNotIncluded_period() { | 1117 void test_periodAfterNumberNotIncluded_period() { |
1084 _assertTokens("42..isEven()", [ | 1118 _assertTokens( |
1085 new StringToken(TokenType.INT, "42", 0), | 1119 "42..isEven()", |
1086 new Token(TokenType.PERIOD_PERIOD, 2), | 1120 [ |
1087 new StringToken(TokenType.IDENTIFIER, "isEven", 4), | 1121 new StringToken(TokenType.INT, "42", 0), |
1088 new Token(TokenType.OPEN_PAREN, 10), | 1122 new Token(TokenType.PERIOD_PERIOD, 2), |
1089 new Token(TokenType.CLOSE_PAREN, 11)]); | 1123 new StringToken(TokenType.IDENTIFIER, "isEven", 4), |
| 1124 new Token(TokenType.OPEN_PAREN, 10), |
| 1125 new Token(TokenType.CLOSE_PAREN, 11)]); |
1090 } | 1126 } |
1091 | 1127 |
1092 void test_plus() { | 1128 void test_plus() { |
1093 _assertToken(TokenType.PLUS, "+"); | 1129 _assertToken(TokenType.PLUS, "+"); |
1094 } | 1130 } |
1095 | 1131 |
1096 void test_plus_eq() { | 1132 void test_plus_eq() { |
1097 _assertToken(TokenType.PLUS_EQ, "+="); | 1133 _assertToken(TokenType.PLUS_EQ, "+="); |
1098 } | 1134 } |
1099 | 1135 |
(...skipping 17 matching lines...) Expand all Loading... |
1117 _assertToken(TokenType.SCRIPT_TAG, "#! /bin/dart"); | 1153 _assertToken(TokenType.SCRIPT_TAG, "#! /bin/dart"); |
1118 } | 1154 } |
1119 | 1155 |
1120 void test_semicolon() { | 1156 void test_semicolon() { |
1121 _assertToken(TokenType.SEMICOLON, ";"); | 1157 _assertToken(TokenType.SEMICOLON, ";"); |
1122 } | 1158 } |
1123 | 1159 |
1124 void test_setSourceStart() { | 1160 void test_setSourceStart() { |
1125 int offsetDelta = 42; | 1161 int offsetDelta = 42; |
1126 GatheringErrorListener listener = new GatheringErrorListener(); | 1162 GatheringErrorListener listener = new GatheringErrorListener(); |
1127 Scanner scanner = new Scanner(null, new SubSequenceReader("a", offsetDelta),
listener); | 1163 Scanner scanner = |
| 1164 new Scanner(null, new SubSequenceReader("a", offsetDelta), listener); |
1128 scanner.setSourceStart(3, 9); | 1165 scanner.setSourceStart(3, 9); |
1129 scanner.tokenize(); | 1166 scanner.tokenize(); |
1130 List<int> lineStarts = scanner.lineStarts; | 1167 List<int> lineStarts = scanner.lineStarts; |
1131 expect(lineStarts, isNotNull); | 1168 expect(lineStarts, isNotNull); |
1132 expect(lineStarts.length, 3); | 1169 expect(lineStarts.length, 3); |
1133 expect(lineStarts[2], 33); | 1170 expect(lineStarts[2], 33); |
1134 } | 1171 } |
1135 | 1172 |
1136 void test_slash() { | 1173 void test_slash() { |
1137 _assertToken(TokenType.SLASH, "/"); | 1174 _assertToken(TokenType.SLASH, "/"); |
(...skipping 27 matching lines...) Expand all Loading... |
1165 | 1202 |
1166 void test_string_multi_embeddedQuotes() { | 1203 void test_string_multi_embeddedQuotes() { |
1167 _assertToken(TokenType.STRING, "\"\"\"line1\n\"\"\nline2\"\"\""); | 1204 _assertToken(TokenType.STRING, "\"\"\"line1\n\"\"\nline2\"\"\""); |
1168 } | 1205 } |
1169 | 1206 |
1170 void test_string_multi_embeddedQuotes_escapedChar() { | 1207 void test_string_multi_embeddedQuotes_escapedChar() { |
1171 _assertToken(TokenType.STRING, "\"\"\"a\"\"\\tb\"\"\""); | 1208 _assertToken(TokenType.STRING, "\"\"\"a\"\"\\tb\"\"\""); |
1172 } | 1209 } |
1173 | 1210 |
1174 void test_string_multi_interpolation_block() { | 1211 void test_string_multi_interpolation_block() { |
1175 _assertTokens("\"Hello \${name}!\"", [ | 1212 _assertTokens( |
1176 new StringToken(TokenType.STRING, "\"Hello ", 0), | 1213 "\"Hello \${name}!\"", |
1177 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7), | 1214 [ |
1178 new StringToken(TokenType.IDENTIFIER, "name", 9), | 1215 new StringToken(TokenType.STRING, "\"Hello ", 0), |
1179 new Token(TokenType.CLOSE_CURLY_BRACKET, 13), | 1216 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7)
, |
1180 new StringToken(TokenType.STRING, "!\"", 14)]); | 1217 new StringToken(TokenType.IDENTIFIER, "name", 9), |
| 1218 new Token(TokenType.CLOSE_CURLY_BRACKET, 13), |
| 1219 new StringToken(TokenType.STRING, "!\"", 14)]); |
1181 } | 1220 } |
1182 | 1221 |
1183 void test_string_multi_interpolation_identifier() { | 1222 void test_string_multi_interpolation_identifier() { |
1184 _assertTokens("\"Hello \$name!\"", [ | 1223 _assertTokens( |
1185 new StringToken(TokenType.STRING, "\"Hello ", 0), | 1224 "\"Hello \$name!\"", |
1186 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7), | 1225 [ |
1187 new StringToken(TokenType.IDENTIFIER, "name", 8), | 1226 new StringToken(TokenType.STRING, "\"Hello ", 0), |
1188 new StringToken(TokenType.STRING, "!\"", 12)]); | 1227 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7), |
| 1228 new StringToken(TokenType.IDENTIFIER, "name", 8), |
| 1229 new StringToken(TokenType.STRING, "!\"", 12)]); |
1189 } | 1230 } |
1190 | 1231 |
1191 void test_string_multi_single() { | 1232 void test_string_multi_single() { |
1192 _assertToken(TokenType.STRING, "'''string'''"); | 1233 _assertToken(TokenType.STRING, "'''string'''"); |
1193 } | 1234 } |
1194 | 1235 |
1195 void test_string_multi_slashEnter() { | 1236 void test_string_multi_slashEnter() { |
1196 _assertToken(TokenType.STRING, "'''\\\n'''"); | 1237 _assertToken(TokenType.STRING, "'''\\\n'''"); |
1197 } | 1238 } |
1198 | 1239 |
1199 void test_string_multi_unterminated() { | 1240 void test_string_multi_unterminated() { |
1200 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "'''s
tring", [new StringToken(TokenType.STRING, "'''string", 0)]); | 1241 _assertErrorAndTokens( |
| 1242 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
| 1243 8, |
| 1244 "'''string", |
| 1245 [new StringToken(TokenType.STRING, "'''string", 0)]); |
1201 } | 1246 } |
1202 | 1247 |
1203 void test_string_multi_unterminated_interpolation_block() { | 1248 void test_string_multi_unterminated_interpolation_block() { |
1204 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "'''\
${name", [ | 1249 _assertErrorAndTokens( |
1205 new StringToken(TokenType.STRING, "'''", 0), | 1250 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
1206 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 3), | 1251 8, |
1207 new StringToken(TokenType.IDENTIFIER, "name", 5), | 1252 "'''\${name", |
1208 new StringToken(TokenType.STRING, "", 9)]); | 1253 [ |
| 1254 new StringToken(TokenType.STRING, "'''", 0), |
| 1255 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 3)
, |
| 1256 new StringToken(TokenType.IDENTIFIER, "name", 5), |
| 1257 new StringToken(TokenType.STRING, "", 9)]); |
1209 } | 1258 } |
1210 | 1259 |
1211 void test_string_multi_unterminated_interpolation_identifier() { | 1260 void test_string_multi_unterminated_interpolation_identifier() { |
1212 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "'''\
$name", [ | 1261 _assertErrorAndTokens( |
1213 new StringToken(TokenType.STRING, "'''", 0), | 1262 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
1214 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3), | 1263 7, |
1215 new StringToken(TokenType.IDENTIFIER, "name", 4), | 1264 "'''\$name", |
1216 new StringToken(TokenType.STRING, "", 8)]); | 1265 [ |
| 1266 new StringToken(TokenType.STRING, "'''", 0), |
| 1267 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3), |
| 1268 new StringToken(TokenType.IDENTIFIER, "name", 4), |
| 1269 new StringToken(TokenType.STRING, "", 8)]); |
1217 } | 1270 } |
1218 | 1271 |
1219 void test_string_raw_multi_double() { | 1272 void test_string_raw_multi_double() { |
1220 _assertToken(TokenType.STRING, "r\"\"\"line1\nline2\"\"\""); | 1273 _assertToken(TokenType.STRING, "r\"\"\"line1\nline2\"\"\""); |
1221 } | 1274 } |
1222 | 1275 |
1223 void test_string_raw_multi_single() { | 1276 void test_string_raw_multi_single() { |
1224 _assertToken(TokenType.STRING, "r'''string'''"); | 1277 _assertToken(TokenType.STRING, "r'''string'''"); |
1225 } | 1278 } |
1226 | 1279 |
1227 void test_string_raw_multi_unterminated() { | 1280 void test_string_raw_multi_unterminated() { |
1228 String source = "r'''string"; | 1281 String source = "r'''string"; |
1229 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, sourc
e, [new StringToken(TokenType.STRING, source, 0)]); | 1282 _assertErrorAndTokens( |
| 1283 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
| 1284 9, |
| 1285 source, |
| 1286 [new StringToken(TokenType.STRING, source, 0)]); |
1230 } | 1287 } |
1231 | 1288 |
1232 void test_string_raw_simple_double() { | 1289 void test_string_raw_simple_double() { |
1233 _assertToken(TokenType.STRING, "r\"string\""); | 1290 _assertToken(TokenType.STRING, "r\"string\""); |
1234 } | 1291 } |
1235 | 1292 |
1236 void test_string_raw_simple_single() { | 1293 void test_string_raw_simple_single() { |
1237 _assertToken(TokenType.STRING, "r'string'"); | 1294 _assertToken(TokenType.STRING, "r'string'"); |
1238 } | 1295 } |
1239 | 1296 |
1240 void test_string_raw_simple_unterminated_eof() { | 1297 void test_string_raw_simple_unterminated_eof() { |
1241 String source = "r'string"; | 1298 String source = "r'string"; |
1242 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, sourc
e, [new StringToken(TokenType.STRING, source, 0)]); | 1299 _assertErrorAndTokens( |
| 1300 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
| 1301 7, |
| 1302 source, |
| 1303 [new StringToken(TokenType.STRING, source, 0)]); |
1243 } | 1304 } |
1244 | 1305 |
1245 void test_string_raw_simple_unterminated_eol() { | 1306 void test_string_raw_simple_unterminated_eol() { |
1246 String source = "r'string"; | 1307 String source = "r'string"; |
1247 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "$sou
rce\n", [new StringToken(TokenType.STRING, source, 0)]); | 1308 _assertErrorAndTokens( |
| 1309 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
| 1310 8, |
| 1311 "$source\n", |
| 1312 [new StringToken(TokenType.STRING, source, 0)]); |
1248 } | 1313 } |
1249 | 1314 |
1250 void test_string_simple_double() { | 1315 void test_string_simple_double() { |
1251 _assertToken(TokenType.STRING, "\"string\""); | 1316 _assertToken(TokenType.STRING, "\"string\""); |
1252 } | 1317 } |
1253 | 1318 |
1254 void test_string_simple_escapedDollar() { | 1319 void test_string_simple_escapedDollar() { |
1255 _assertToken(TokenType.STRING, "'a\\\$b'"); | 1320 _assertToken(TokenType.STRING, "'a\\\$b'"); |
1256 } | 1321 } |
1257 | 1322 |
1258 void test_string_simple_interpolation_adjacentIdentifiers() { | 1323 void test_string_simple_interpolation_adjacentIdentifiers() { |
1259 _assertTokens("'\$a\$b'", [ | 1324 _assertTokens( |
1260 new StringToken(TokenType.STRING, "'", 0), | 1325 "'\$a\$b'", |
1261 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), | 1326 [ |
1262 new StringToken(TokenType.IDENTIFIER, "a", 2), | 1327 new StringToken(TokenType.STRING, "'", 0), |
1263 new StringToken(TokenType.STRING, "", 3), | 1328 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), |
1264 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3), | 1329 new StringToken(TokenType.IDENTIFIER, "a", 2), |
1265 new StringToken(TokenType.IDENTIFIER, "b", 4), | 1330 new StringToken(TokenType.STRING, "", 3), |
1266 new StringToken(TokenType.STRING, "'", 5)]); | 1331 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3), |
| 1332 new StringToken(TokenType.IDENTIFIER, "b", 4), |
| 1333 new StringToken(TokenType.STRING, "'", 5)]); |
1267 } | 1334 } |
1268 | 1335 |
1269 void test_string_simple_interpolation_block() { | 1336 void test_string_simple_interpolation_block() { |
1270 _assertTokens("'Hello \${name}!'", [ | 1337 _assertTokens( |
1271 new StringToken(TokenType.STRING, "'Hello ", 0), | 1338 "'Hello \${name}!'", |
1272 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7), | 1339 [ |
1273 new StringToken(TokenType.IDENTIFIER, "name", 9), | 1340 new StringToken(TokenType.STRING, "'Hello ", 0), |
1274 new Token(TokenType.CLOSE_CURLY_BRACKET, 13), | 1341 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7)
, |
1275 new StringToken(TokenType.STRING, "!'", 14)]); | 1342 new StringToken(TokenType.IDENTIFIER, "name", 9), |
| 1343 new Token(TokenType.CLOSE_CURLY_BRACKET, 13), |
| 1344 new StringToken(TokenType.STRING, "!'", 14)]); |
1276 } | 1345 } |
1277 | 1346 |
1278 void test_string_simple_interpolation_blockWithNestedMap() { | 1347 void test_string_simple_interpolation_blockWithNestedMap() { |
1279 _assertTokens("'a \${f({'b' : 'c'})} d'", [ | 1348 _assertTokens( |
1280 new StringToken(TokenType.STRING, "'a ", 0), | 1349 "'a \${f({'b' : 'c'})} d'", |
1281 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 3), | 1350 [ |
1282 new StringToken(TokenType.IDENTIFIER, "f", 5), | 1351 new StringToken(TokenType.STRING, "'a ", 0), |
1283 new Token(TokenType.OPEN_PAREN, 6), | 1352 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 3)
, |
1284 new Token(TokenType.OPEN_CURLY_BRACKET, 7), | 1353 new StringToken(TokenType.IDENTIFIER, "f", 5), |
1285 new StringToken(TokenType.STRING, "'b'", 8), | 1354 new Token(TokenType.OPEN_PAREN, 6), |
1286 new Token(TokenType.COLON, 12), | 1355 new Token(TokenType.OPEN_CURLY_BRACKET, 7), |
1287 new StringToken(TokenType.STRING, "'c'", 14), | 1356 new StringToken(TokenType.STRING, "'b'", 8), |
1288 new Token(TokenType.CLOSE_CURLY_BRACKET, 17), | 1357 new Token(TokenType.COLON, 12), |
1289 new Token(TokenType.CLOSE_PAREN, 18), | 1358 new StringToken(TokenType.STRING, "'c'", 14), |
1290 new Token(TokenType.CLOSE_CURLY_BRACKET, 19), | 1359 new Token(TokenType.CLOSE_CURLY_BRACKET, 17), |
1291 new StringToken(TokenType.STRING, " d'", 20)]); | 1360 new Token(TokenType.CLOSE_PAREN, 18), |
| 1361 new Token(TokenType.CLOSE_CURLY_BRACKET, 19), |
| 1362 new StringToken(TokenType.STRING, " d'", 20)]); |
1292 } | 1363 } |
1293 | 1364 |
1294 void test_string_simple_interpolation_firstAndLast() { | 1365 void test_string_simple_interpolation_firstAndLast() { |
1295 _assertTokens("'\$greeting \$name'", [ | 1366 _assertTokens( |
1296 new StringToken(TokenType.STRING, "'", 0), | 1367 "'\$greeting \$name'", |
1297 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), | 1368 [ |
1298 new StringToken(TokenType.IDENTIFIER, "greeting", 2), | 1369 new StringToken(TokenType.STRING, "'", 0), |
1299 new StringToken(TokenType.STRING, " ", 10), | 1370 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), |
1300 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 11), | 1371 new StringToken(TokenType.IDENTIFIER, "greeting", 2), |
1301 new StringToken(TokenType.IDENTIFIER, "name", 12), | 1372 new StringToken(TokenType.STRING, " ", 10), |
1302 new StringToken(TokenType.STRING, "'", 16)]); | 1373 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 11)
, |
| 1374 new StringToken(TokenType.IDENTIFIER, "name", 12), |
| 1375 new StringToken(TokenType.STRING, "'", 16)]); |
1303 } | 1376 } |
1304 | 1377 |
1305 void test_string_simple_interpolation_identifier() { | 1378 void test_string_simple_interpolation_identifier() { |
1306 _assertTokens("'Hello \$name!'", [ | 1379 _assertTokens( |
1307 new StringToken(TokenType.STRING, "'Hello ", 0), | 1380 "'Hello \$name!'", |
1308 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7), | 1381 [ |
1309 new StringToken(TokenType.IDENTIFIER, "name", 8), | 1382 new StringToken(TokenType.STRING, "'Hello ", 0), |
1310 new StringToken(TokenType.STRING, "!'", 12)]); | 1383 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7), |
| 1384 new StringToken(TokenType.IDENTIFIER, "name", 8), |
| 1385 new StringToken(TokenType.STRING, "!'", 12)]); |
1311 } | 1386 } |
1312 | 1387 |
1313 void test_string_simple_interpolation_missingIdentifier() { | 1388 void test_string_simple_interpolation_missingIdentifier() { |
1314 _assertTokens("'\$x\$'", [ | 1389 _assertTokens( |
1315 new StringToken(TokenType.STRING, "'", 0), | 1390 "'\$x\$'", |
1316 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), | 1391 [ |
1317 new StringToken(TokenType.IDENTIFIER, "x", 2), | 1392 new StringToken(TokenType.STRING, "'", 0), |
1318 new StringToken(TokenType.STRING, "", 3), | 1393 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), |
1319 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3), | 1394 new StringToken(TokenType.IDENTIFIER, "x", 2), |
1320 new StringToken(TokenType.STRING, "'", 4)]); | 1395 new StringToken(TokenType.STRING, "", 3), |
| 1396 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3), |
| 1397 new StringToken(TokenType.STRING, "'", 4)]); |
1321 } | 1398 } |
1322 | 1399 |
1323 void test_string_simple_interpolation_nonIdentifier() { | 1400 void test_string_simple_interpolation_nonIdentifier() { |
1324 _assertTokens("'\$1'", [ | 1401 _assertTokens( |
1325 new StringToken(TokenType.STRING, "'", 0), | 1402 "'\$1'", |
1326 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), | 1403 [ |
1327 new StringToken(TokenType.STRING, "1'", 2)]); | 1404 new StringToken(TokenType.STRING, "'", 0), |
| 1405 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), |
| 1406 new StringToken(TokenType.STRING, "1'", 2)]); |
1328 } | 1407 } |
1329 | 1408 |
1330 void test_string_simple_single() { | 1409 void test_string_simple_single() { |
1331 _assertToken(TokenType.STRING, "'string'"); | 1410 _assertToken(TokenType.STRING, "'string'"); |
1332 } | 1411 } |
1333 | 1412 |
1334 void test_string_simple_unterminated_eof() { | 1413 void test_string_simple_unterminated_eof() { |
1335 String source = "'string"; | 1414 String source = "'string"; |
1336 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 6, sourc
e, [new StringToken(TokenType.STRING, source, 0)]); | 1415 _assertErrorAndTokens( |
| 1416 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
| 1417 6, |
| 1418 source, |
| 1419 [new StringToken(TokenType.STRING, source, 0)]); |
1337 } | 1420 } |
1338 | 1421 |
1339 void test_string_simple_unterminated_eol() { | 1422 void test_string_simple_unterminated_eol() { |
1340 String source = "'string"; | 1423 String source = "'string"; |
1341 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "$sou
rce\r", [new StringToken(TokenType.STRING, source, 0)]); | 1424 _assertErrorAndTokens( |
| 1425 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
| 1426 7, |
| 1427 "$source\r", |
| 1428 [new StringToken(TokenType.STRING, source, 0)]); |
1342 } | 1429 } |
1343 | 1430 |
1344 void test_string_simple_unterminated_interpolation_block() { | 1431 void test_string_simple_unterminated_interpolation_block() { |
1345 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 6, "'\${
name", [ | 1432 _assertErrorAndTokens( |
1346 new StringToken(TokenType.STRING, "'", 0), | 1433 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
1347 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 1), | 1434 6, |
1348 new StringToken(TokenType.IDENTIFIER, "name", 3), | 1435 "'\${name", |
1349 new StringToken(TokenType.STRING, "", 7)]); | 1436 [ |
| 1437 new StringToken(TokenType.STRING, "'", 0), |
| 1438 new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 1)
, |
| 1439 new StringToken(TokenType.IDENTIFIER, "name", 3), |
| 1440 new StringToken(TokenType.STRING, "", 7)]); |
1350 } | 1441 } |
1351 | 1442 |
1352 void test_string_simple_unterminated_interpolation_identifier() { | 1443 void test_string_simple_unterminated_interpolation_identifier() { |
1353 _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 5, "'\$n
ame", [ | 1444 _assertErrorAndTokens( |
1354 new StringToken(TokenType.STRING, "'", 0), | 1445 ScannerErrorCode.UNTERMINATED_STRING_LITERAL, |
1355 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), | 1446 5, |
1356 new StringToken(TokenType.IDENTIFIER, "name", 2), | 1447 "'\$name", |
1357 new StringToken(TokenType.STRING, "", 6)]); | 1448 [ |
| 1449 new StringToken(TokenType.STRING, "'", 0), |
| 1450 new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1), |
| 1451 new StringToken(TokenType.IDENTIFIER, "name", 2), |
| 1452 new StringToken(TokenType.STRING, "", 6)]); |
1358 } | 1453 } |
1359 | 1454 |
1360 void test_tilde() { | 1455 void test_tilde() { |
1361 _assertToken(TokenType.TILDE, "~"); | 1456 _assertToken(TokenType.TILDE, "~"); |
1362 } | 1457 } |
1363 | 1458 |
1364 void test_tilde_slash() { | 1459 void test_tilde_slash() { |
1365 _assertToken(TokenType.TILDE_SLASH, "~/"); | 1460 _assertToken(TokenType.TILDE_SLASH, "~/"); |
1366 } | 1461 } |
1367 | 1462 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 expect(comment.lexeme, source); | 1496 expect(comment.lexeme, source); |
1402 } | 1497 } |
1403 | 1498 |
1404 /** | 1499 /** |
1405 * Assert that scanning the given source produces an error with the given code
. | 1500 * Assert that scanning the given source produces an error with the given code
. |
1406 * | 1501 * |
1407 * @param expectedError the error that should be produced | 1502 * @param expectedError the error that should be produced |
1408 * @param expectedOffset the string offset that should be associated with the
error | 1503 * @param expectedOffset the string offset that should be associated with the
error |
1409 * @param source the source to be scanned to produce the error | 1504 * @param source the source to be scanned to produce the error |
1410 */ | 1505 */ |
1411 void _assertError(ScannerErrorCode expectedError, int expectedOffset, String s
ource) { | 1506 void _assertError(ScannerErrorCode expectedError, int expectedOffset, |
| 1507 String source) { |
1412 GatheringErrorListener listener = new GatheringErrorListener(); | 1508 GatheringErrorListener listener = new GatheringErrorListener(); |
1413 _scanWithListener(source, listener); | 1509 _scanWithListener(source, listener); |
1414 listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expec
tedError, [source.codeUnitAt(expectedOffset)])]); | 1510 listener.assertErrors( |
| 1511 [ |
| 1512 new AnalysisError.con2( |
| 1513 null, |
| 1514 expectedOffset, |
| 1515 1, |
| 1516 expectedError, |
| 1517 [source.codeUnitAt(expectedOffset)])]); |
1415 } | 1518 } |
1416 | 1519 |
1417 /** | 1520 /** |
1418 * Assert that scanning the given source produces an error with the given code
, and also produces | 1521 * Assert that scanning the given source produces an error with the given code
, and also produces |
1419 * the given tokens. | 1522 * the given tokens. |
1420 * | 1523 * |
1421 * @param expectedError the error that should be produced | 1524 * @param expectedError the error that should be produced |
1422 * @param expectedOffset the string offset that should be associated with the
error | 1525 * @param expectedOffset the string offset that should be associated with the
error |
1423 * @param source the source to be scanned to produce the error | 1526 * @param source the source to be scanned to produce the error |
1424 * @param expectedTokens the tokens that are expected to be in the source | 1527 * @param expectedTokens the tokens that are expected to be in the source |
1425 */ | 1528 */ |
1426 void _assertErrorAndTokens(ScannerErrorCode expectedError, int expectedOffset,
String source, List<Token> expectedTokens) { | 1529 void _assertErrorAndTokens(ScannerErrorCode expectedError, int expectedOffset, |
| 1530 String source, List<Token> expectedTokens) { |
1427 GatheringErrorListener listener = new GatheringErrorListener(); | 1531 GatheringErrorListener listener = new GatheringErrorListener(); |
1428 Token token = _scanWithListener(source, listener); | 1532 Token token = _scanWithListener(source, listener); |
1429 listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expec
tedError, [source.codeUnitAt(expectedOffset)])]); | 1533 listener.assertErrors( |
| 1534 [ |
| 1535 new AnalysisError.con2( |
| 1536 null, |
| 1537 expectedOffset, |
| 1538 1, |
| 1539 expectedError, |
| 1540 [source.codeUnitAt(expectedOffset)])]); |
1430 _checkTokens(token, expectedTokens); | 1541 _checkTokens(token, expectedTokens); |
1431 } | 1542 } |
1432 | 1543 |
1433 /** | 1544 /** |
1434 * Assert that when scanned the given source contains a single keyword token w
ith the same lexeme | 1545 * Assert that when scanned the given source contains a single keyword token w
ith the same lexeme |
1435 * as the original source. | 1546 * as the original source. |
1436 * | 1547 * |
1437 * @param source the source to be scanned | 1548 * @param source the source to be scanned |
1438 */ | 1549 */ |
1439 void _assertKeywordToken(String source) { | 1550 void _assertKeywordToken(String source) { |
(...skipping 11 matching lines...) Expand all Loading... |
1451 expect(token.type, TokenType.KEYWORD); | 1562 expect(token.type, TokenType.KEYWORD); |
1452 expect(token.offset, 1); | 1563 expect(token.offset, 1); |
1453 expect(token.length, source.length); | 1564 expect(token.length, source.length); |
1454 expect(token.lexeme, source); | 1565 expect(token.lexeme, source); |
1455 value = token.value(); | 1566 value = token.value(); |
1456 expect(value is Keyword, isTrue); | 1567 expect(value is Keyword, isTrue); |
1457 expect((value as Keyword).syntax, source); | 1568 expect((value as Keyword).syntax, source); |
1458 expect(token.next.type, TokenType.EOF); | 1569 expect(token.next.type, TokenType.EOF); |
1459 } | 1570 } |
1460 | 1571 |
1461 void _assertLineInfo(String source, List<ScannerTest_ExpectedLocation> expecte
dLocations) { | 1572 void _assertLineInfo(String source, |
| 1573 List<ScannerTest_ExpectedLocation> expectedLocations) { |
1462 GatheringErrorListener listener = new GatheringErrorListener(); | 1574 GatheringErrorListener listener = new GatheringErrorListener(); |
1463 _scanWithListener(source, listener); | 1575 _scanWithListener(source, listener); |
1464 listener.assertNoErrors(); | 1576 listener.assertNoErrors(); |
1465 LineInfo info = listener.getLineInfo(new TestSource()); | 1577 LineInfo info = listener.getLineInfo(new TestSource()); |
1466 expect(info, isNotNull); | 1578 expect(info, isNotNull); |
1467 for (ScannerTest_ExpectedLocation expectedLocation in expectedLocations) { | 1579 for (ScannerTest_ExpectedLocation expectedLocation in expectedLocations) { |
1468 LineInfo_Location location = info.getLocation(expectedLocation._offset); | 1580 LineInfo_Location location = info.getLocation(expectedLocation._offset); |
1469 expect(location.lineNumber, expectedLocation._lineNumber); | 1581 expect(location.lineNumber, expectedLocation._lineNumber); |
1470 expect(location.columnNumber, expectedLocation._columnNumber); | 1582 expect(location.columnNumber, expectedLocation._columnNumber); |
1471 } | 1583 } |
1472 } | 1584 } |
1473 | 1585 |
1474 /** | 1586 /** |
1475 * Assert that the token scanned from the given source has the expected type. | 1587 * Assert that the token scanned from the given source has the expected type. |
1476 * | 1588 * |
1477 * @param expectedType the expected type of the token | 1589 * @param expectedType the expected type of the token |
1478 * @param source the source to be scanned to produce the actual token | 1590 * @param source the source to be scanned to produce the actual token |
1479 */ | 1591 */ |
1480 Token _assertToken(TokenType expectedType, String source) { | 1592 Token _assertToken(TokenType expectedType, String source) { |
1481 Token originalToken = _scan(source); | 1593 Token originalToken = _scan(source); |
1482 expect(originalToken, isNotNull); | 1594 expect(originalToken, isNotNull); |
1483 expect(originalToken.type, expectedType); | 1595 expect(originalToken.type, expectedType); |
1484 expect(originalToken.offset, 0); | 1596 expect(originalToken.offset, 0); |
1485 expect(originalToken.length, source.length); | 1597 expect(originalToken.length, source.length); |
1486 expect(originalToken.lexeme, source); | 1598 expect(originalToken.lexeme, source); |
1487 if (expectedType == TokenType.SCRIPT_TAG) { | 1599 if (expectedType == TokenType.SCRIPT_TAG) { |
1488 // Adding space before the script tag is not allowed, and adding text at t
he end changes nothing. | 1600 // Adding space before the script tag is not allowed, and adding text at |
| 1601 // the end changes nothing. |
1489 return originalToken; | 1602 return originalToken; |
1490 } else if (expectedType == TokenType.SINGLE_LINE_COMMENT) { | 1603 } else if (expectedType == TokenType.SINGLE_LINE_COMMENT) { |
1491 // Adding space to an end-of-line comment changes the comment. | 1604 // Adding space to an end-of-line comment changes the comment. |
1492 Token tokenWithSpaces = _scan(" $source"); | 1605 Token tokenWithSpaces = _scan(" $source"); |
1493 expect(tokenWithSpaces, isNotNull); | 1606 expect(tokenWithSpaces, isNotNull); |
1494 expect(tokenWithSpaces.type, expectedType); | 1607 expect(tokenWithSpaces.type, expectedType); |
1495 expect(tokenWithSpaces.offset, 1); | 1608 expect(tokenWithSpaces.offset, 1); |
1496 expect(tokenWithSpaces.length, source.length); | 1609 expect(tokenWithSpaces.length, source.length); |
1497 expect(tokenWithSpaces.lexeme, source); | 1610 expect(tokenWithSpaces.lexeme, source); |
1498 return originalToken; | 1611 return originalToken; |
1499 } else if (expectedType == TokenType.INT || expectedType == TokenType.DOUBLE
) { | 1612 } else if (expectedType == TokenType.INT || |
| 1613 expectedType == TokenType.DOUBLE) { |
1500 Token tokenWithLowerD = _scan("${source}d"); | 1614 Token tokenWithLowerD = _scan("${source}d"); |
1501 expect(tokenWithLowerD, isNotNull); | 1615 expect(tokenWithLowerD, isNotNull); |
1502 expect(tokenWithLowerD.type, expectedType); | 1616 expect(tokenWithLowerD.type, expectedType); |
1503 expect(tokenWithLowerD.offset, 0); | 1617 expect(tokenWithLowerD.offset, 0); |
1504 expect(tokenWithLowerD.length, source.length); | 1618 expect(tokenWithLowerD.length, source.length); |
1505 expect(tokenWithLowerD.lexeme, source); | 1619 expect(tokenWithLowerD.lexeme, source); |
1506 Token tokenWithUpperD = _scan("${source}D"); | 1620 Token tokenWithUpperD = _scan("${source}D"); |
1507 expect(tokenWithUpperD, isNotNull); | 1621 expect(tokenWithUpperD, isNotNull); |
1508 expect(tokenWithUpperD.type, expectedType); | 1622 expect(tokenWithUpperD.type, expectedType); |
1509 expect(tokenWithUpperD.offset, 0); | 1623 expect(tokenWithUpperD.offset, 0); |
(...skipping 21 matching lines...) Expand all Loading... |
1531 Token token = _scan(source); | 1645 Token token = _scan(source); |
1532 _checkTokens(token, expectedTokens); | 1646 _checkTokens(token, expectedTokens); |
1533 } | 1647 } |
1534 | 1648 |
1535 void _checkTokens(Token firstToken, List<Token> expectedTokens) { | 1649 void _checkTokens(Token firstToken, List<Token> expectedTokens) { |
1536 expect(firstToken, isNotNull); | 1650 expect(firstToken, isNotNull); |
1537 Token token = firstToken; | 1651 Token token = firstToken; |
1538 for (int i = 0; i < expectedTokens.length; i++) { | 1652 for (int i = 0; i < expectedTokens.length; i++) { |
1539 Token expectedToken = expectedTokens[i]; | 1653 Token expectedToken = expectedTokens[i]; |
1540 expect(token.type, expectedToken.type, reason: "Wrong type for token $i"); | 1654 expect(token.type, expectedToken.type, reason: "Wrong type for token $i"); |
1541 expect(token.offset, expectedToken.offset, reason: "Wrong offset for token
$i"); | 1655 expect( |
1542 expect(token.length, expectedToken.length, reason: "Wrong length for token
$i"); | 1656 token.offset, |
1543 expect(token.lexeme, expectedToken.lexeme, reason: "Wrong lexeme for token
$i"); | 1657 expectedToken.offset, |
| 1658 reason: "Wrong offset for token $i"); |
| 1659 expect( |
| 1660 token.length, |
| 1661 expectedToken.length, |
| 1662 reason: "Wrong length for token $i"); |
| 1663 expect( |
| 1664 token.lexeme, |
| 1665 expectedToken.lexeme, |
| 1666 reason: "Wrong lexeme for token $i"); |
1544 token = token.next; | 1667 token = token.next; |
1545 expect(token, isNotNull); | 1668 expect(token, isNotNull); |
1546 } | 1669 } |
1547 expect(token.type, TokenType.EOF); | 1670 expect(token.type, TokenType.EOF); |
1548 } | 1671 } |
1549 | 1672 |
1550 Token _scan(String source) { | 1673 Token _scan(String source) { |
1551 GatheringErrorListener listener = new GatheringErrorListener(); | 1674 GatheringErrorListener listener = new GatheringErrorListener(); |
1552 Token token = _scanWithListener(source, listener); | 1675 Token token = _scanWithListener(source, listener); |
1553 listener.assertNoErrors(); | 1676 listener.assertNoErrors(); |
1554 return token; | 1677 return token; |
1555 } | 1678 } |
1556 | 1679 |
1557 Token _scanWithListener(String source, GatheringErrorListener listener) { | 1680 Token _scanWithListener(String source, GatheringErrorListener listener) { |
1558 Scanner scanner = new Scanner(null, new CharSequenceReader(source), listener
); | 1681 Scanner scanner = |
| 1682 new Scanner(null, new CharSequenceReader(source), listener); |
1559 Token result = scanner.tokenize(); | 1683 Token result = scanner.tokenize(); |
1560 listener.setLineInfo(new TestSource(), scanner.lineStarts); | 1684 listener.setLineInfo(new TestSource(), scanner.lineStarts); |
1561 return result; | 1685 return result; |
1562 } | 1686 } |
1563 } | 1687 } |
1564 | 1688 |
1565 /** | 1689 /** |
1566 * Instances of the class `ExpectedLocation` encode information about the expect
ed location | 1690 * Instances of the class `ExpectedLocation` encode information about the expect
ed location |
1567 * of a given offset in source code. | 1691 * of a given offset in source code. |
1568 */ | 1692 */ |
1569 class ScannerTest_ExpectedLocation { | 1693 class ScannerTest_ExpectedLocation { |
1570 final int _offset; | 1694 final int _offset; |
1571 | 1695 |
1572 final int _lineNumber; | 1696 final int _lineNumber; |
1573 | 1697 |
1574 final int _columnNumber; | 1698 final int _columnNumber; |
1575 | 1699 |
1576 ScannerTest_ExpectedLocation(this._offset, this._lineNumber, this._columnNumbe
r); | 1700 ScannerTest_ExpectedLocation(this._offset, this._lineNumber, |
| 1701 this._columnNumber); |
1577 } | 1702 } |
1578 | 1703 |
1579 /** | 1704 /** |
1580 * Instances of the class `TokenStreamValidator` are used to validate the correc
t construction | 1705 * Instances of the class `TokenStreamValidator` are used to validate the correc
t construction |
1581 * of a stream of tokens. | 1706 * of a stream of tokens. |
1582 */ | 1707 */ |
1583 class TokenStreamValidator { | 1708 class TokenStreamValidator { |
1584 /** | 1709 /** |
1585 * Validate that the stream of tokens that starts with the given token is corr
ect. | 1710 * Validate that the stream of tokens that starts with the given token is corr
ect. |
1586 * | 1711 * |
(...skipping 10 matching lines...) Expand all Loading... |
1597 void _validateStream(StringBuffer buffer, Token token) { | 1722 void _validateStream(StringBuffer buffer, Token token) { |
1598 if (token == null) { | 1723 if (token == null) { |
1599 return; | 1724 return; |
1600 } | 1725 } |
1601 Token previousToken = null; | 1726 Token previousToken = null; |
1602 int previousEnd = -1; | 1727 int previousEnd = -1; |
1603 Token currentToken = token; | 1728 Token currentToken = token; |
1604 while (currentToken != null && currentToken.type != TokenType.EOF) { | 1729 while (currentToken != null && currentToken.type != TokenType.EOF) { |
1605 _validateStream(buffer, currentToken.precedingComments); | 1730 _validateStream(buffer, currentToken.precedingComments); |
1606 TokenType type = currentToken.type; | 1731 TokenType type = currentToken.type; |
1607 if (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.OPEN_PAREN |
| type == TokenType.OPEN_SQUARE_BRACKET || type == TokenType.STRING_INTERPOLATIO
N_EXPRESSION) { | 1732 if (type == TokenType.OPEN_CURLY_BRACKET || |
| 1733 type == TokenType.OPEN_PAREN || |
| 1734 type == TokenType.OPEN_SQUARE_BRACKET || |
| 1735 type == TokenType.STRING_INTERPOLATION_EXPRESSION) { |
1608 if (currentToken is! BeginToken) { | 1736 if (currentToken is! BeginToken) { |
1609 buffer.write("\r\nExpected BeginToken, found "); | 1737 buffer.write("\r\nExpected BeginToken, found "); |
1610 buffer.write(currentToken.runtimeType.toString()); | 1738 buffer.write(currentToken.runtimeType.toString()); |
1611 buffer.write(" "); | 1739 buffer.write(" "); |
1612 _writeToken(buffer, currentToken); | 1740 _writeToken(buffer, currentToken); |
1613 } | 1741 } |
1614 } | 1742 } |
1615 int currentStart = currentToken.offset; | 1743 int currentStart = currentToken.offset; |
1616 int currentLength = currentToken.length; | 1744 int currentLength = currentToken.length; |
1617 int currentEnd = currentStart + currentLength - 1; | 1745 int currentEnd = currentStart + currentLength - 1; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1699 expect(TokenType.LT_LT.isUserDefinableOperator, isTrue); | 1827 expect(TokenType.LT_LT.isUserDefinableOperator, isTrue); |
1700 expect(TokenType.MINUS.isUserDefinableOperator, isTrue); | 1828 expect(TokenType.MINUS.isUserDefinableOperator, isTrue); |
1701 expect(TokenType.PERCENT.isUserDefinableOperator, isTrue); | 1829 expect(TokenType.PERCENT.isUserDefinableOperator, isTrue); |
1702 expect(TokenType.PLUS.isUserDefinableOperator, isTrue); | 1830 expect(TokenType.PLUS.isUserDefinableOperator, isTrue); |
1703 expect(TokenType.SLASH.isUserDefinableOperator, isTrue); | 1831 expect(TokenType.SLASH.isUserDefinableOperator, isTrue); |
1704 expect(TokenType.STAR.isUserDefinableOperator, isTrue); | 1832 expect(TokenType.STAR.isUserDefinableOperator, isTrue); |
1705 expect(TokenType.TILDE.isUserDefinableOperator, isTrue); | 1833 expect(TokenType.TILDE.isUserDefinableOperator, isTrue); |
1706 expect(TokenType.TILDE_SLASH.isUserDefinableOperator, isTrue); | 1834 expect(TokenType.TILDE_SLASH.isUserDefinableOperator, isTrue); |
1707 } | 1835 } |
1708 } | 1836 } |
1709 | |
1710 main() { | |
1711 groupSep = ' | '; | |
1712 runReflectiveTests(CharSequenceReaderTest); | |
1713 runReflectiveTests(IncrementalScannerTest); | |
1714 runReflectiveTests(KeywordStateTest); | |
1715 runReflectiveTests(ScannerTest); | |
1716 runReflectiveTests(TokenTypeTest); | |
1717 } | |
OLD | NEW |