| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of scanner; | 5 part of scanner; |
| 6 | 6 |
| 7 abstract class Scanner { | 7 abstract class Scanner { |
| 8 Token tokenize(); | 8 Token tokenize(); |
| 9 | 9 |
| 10 factory Scanner(SourceFile file, | 10 factory Scanner(SourceFile file, |
| 11 {bool includeComments: false, bool enableNullAwareOperators: false}) { | 11 {bool includeComments: false}) { |
| 12 if (file is Utf8BytesSourceFile) { | 12 if (file is Utf8BytesSourceFile) { |
| 13 return new Utf8BytesScanner(file, includeComments: includeComments, | 13 return new Utf8BytesScanner(file, includeComments: includeComments); |
| 14 enableNullAwareOperators: enableNullAwareOperators); | |
| 15 } else { | 14 } else { |
| 16 return new StringScanner(file, includeComments: includeComments, | 15 return new StringScanner(file, includeComments: includeComments); |
| 17 enableNullAwareOperators: enableNullAwareOperators); | |
| 18 } | 16 } |
| 19 } | 17 } |
| 20 } | 18 } |
| 21 | 19 |
| 22 abstract class AbstractScanner implements Scanner { | 20 abstract class AbstractScanner implements Scanner { |
| 23 // TODO(ahe): Move this class to implementation. | 21 // TODO(ahe): Move this class to implementation. |
| 24 | 22 |
| 25 final bool includeComments; | 23 final bool includeComments; |
| 26 final bool enableNullAwareOperators; | |
| 27 | 24 |
| 28 /** | 25 /** |
| 29 * The string offset for the next token that will be created. | 26 * The string offset for the next token that will be created. |
| 30 * | 27 * |
| 31 * Note that in the [Utf8BytesScanner], [stringOffset] and [scanOffset] values | 28 * Note that in the [Utf8BytesScanner], [stringOffset] and [scanOffset] values |
| 32 * are different. One string character can be encoded using multiple UTF-8 | 29 * are different. One string character can be encoded using multiple UTF-8 |
| 33 * bytes. | 30 * bytes. |
| 34 */ | 31 */ |
| 35 int tokenStart = -1; | 32 int tokenStart = -1; |
| 36 | 33 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 51 /** | 48 /** |
| 52 * The source file that is being scanned. This field can be [:null:]. | 49 * The source file that is being scanned. This field can be [:null:]. |
| 53 * If the source file is available, the scanner assigns its [:lineStarts:] and | 50 * If the source file is available, the scanner assigns its [:lineStarts:] and |
| 54 * [:length:] fields at the end of [tokenize]. | 51 * [:length:] fields at the end of [tokenize]. |
| 55 */ | 52 */ |
| 56 final SourceFile file; | 53 final SourceFile file; |
| 57 | 54 |
| 58 final List<int> lineStarts = <int>[0]; | 55 final List<int> lineStarts = <int>[0]; |
| 59 | 56 |
| 60 AbstractScanner( | 57 AbstractScanner( |
| 61 this.file, this.includeComments, this.enableNullAwareOperators) { | 58 this.file, this.includeComments) { |
| 62 this.tail = this.tokens; | 59 this.tail = this.tokens; |
| 63 } | 60 } |
| 64 | 61 |
| 65 /** | 62 /** |
| 66 * Advances and returns the next character. | 63 * Advances and returns the next character. |
| 67 * | 64 * |
| 68 * If the next character is non-ASCII, then the returned value depends on the | 65 * If the next character is non-ASCII, then the returned value depends on the |
| 69 * scanner implementation. The [Utf8BytesScanner] returns a UTF-8 byte, while | 66 * scanner implementation. The [Utf8BytesScanner] returns a UTF-8 byte, while |
| 70 * the [StringScanner] returns a UTF-16 code unit. | 67 * the [StringScanner] returns a UTF-16 code unit. |
| 71 * | 68 * |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 | 448 |
| 452 int tokenizeCaret(int next) { | 449 int tokenizeCaret(int next) { |
| 453 // ^ ^= | 450 // ^ ^= |
| 454 return select($EQ, CARET_EQ_INFO, CARET_INFO); | 451 return select($EQ, CARET_EQ_INFO, CARET_INFO); |
| 455 } | 452 } |
| 456 | 453 |
| 457 int tokenizeQuestion(int next) { | 454 int tokenizeQuestion(int next) { |
| 458 // ? ?. ?? ??= | 455 // ? ?. ?? ??= |
| 459 next = advance(); | 456 next = advance(); |
| 460 if (identical(next, $QUESTION)) { | 457 if (identical(next, $QUESTION)) { |
| 461 if (enableNullAwareOperators) { | 458 return select($EQ, QUESTION_QUESTION_EQ_INFO, QUESTION_QUESTION_INFO); |
| 462 return select($EQ, QUESTION_QUESTION_EQ_INFO, QUESTION_QUESTION_INFO); | |
| 463 } else { | |
| 464 next = advance(); | |
| 465 PrecedenceInfo info; | |
| 466 if (identical(next, $EQ)) { | |
| 467 info = QUESTION_QUESTION_EQ_INFO; | |
| 468 next = advance(); | |
| 469 } else { | |
| 470 info = QUESTION_QUESTION_INFO; | |
| 471 } | |
| 472 appendErrorToken(new UnsupportedNullAwareToken(info.value, tokenStart)); | |
| 473 return next; | |
| 474 } | |
| 475 } else if (identical(next, $PERIOD)) { | 459 } else if (identical(next, $PERIOD)) { |
| 476 if (enableNullAwareOperators) { | 460 appendPrecedenceToken(QUESTION_PERIOD_INFO); |
| 477 appendPrecedenceToken(QUESTION_PERIOD_INFO); | |
| 478 } else { | |
| 479 appendErrorToken(new UnsupportedNullAwareToken( | |
| 480 QUESTION_PERIOD_INFO.value, tokenStart)); | |
| 481 } | |
| 482 return advance(); | 461 return advance(); |
| 483 } else { | 462 } else { |
| 484 appendPrecedenceToken(QUESTION_INFO); | 463 appendPrecedenceToken(QUESTION_INFO); |
| 485 return next; | 464 return next; |
| 486 } | 465 } |
| 487 } | 466 } |
| 488 | 467 |
| 489 int tokenizeBar(int next) { | 468 int tokenizeBar(int next) { |
| 490 // | || |= | 469 // | || |= |
| 491 next = advance(); | 470 next = advance(); |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 | 1162 |
| 1184 PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) { | 1163 PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) { |
| 1185 return const { | 1164 return const { |
| 1186 '(': CLOSE_PAREN_INFO, | 1165 '(': CLOSE_PAREN_INFO, |
| 1187 '[': CLOSE_SQUARE_BRACKET_INFO, | 1166 '[': CLOSE_SQUARE_BRACKET_INFO, |
| 1188 '{': CLOSE_CURLY_BRACKET_INFO, | 1167 '{': CLOSE_CURLY_BRACKET_INFO, |
| 1189 '<': GT_INFO, | 1168 '<': GT_INFO, |
| 1190 r'${': CLOSE_CURLY_BRACKET_INFO, | 1169 r'${': CLOSE_CURLY_BRACKET_INFO, |
| 1191 }[begin.value]; | 1170 }[begin.value]; |
| 1192 } | 1171 } |
| OLD | NEW |