| 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; | 8 library engine.scanner; |
| 9 | 9 |
| 10 import "dart:math" as math; | 10 import "dart:math" as math; |
| 11 import 'dart:collection'; | 11 import 'dart:collection'; |
| 12 | 12 |
| 13 import 'error.dart'; | 13 import 'error.dart'; |
| 14 import 'instrumentation.dart'; | 14 import 'instrumentation.dart'; |
| 15 import 'java_core.dart'; | |
| 16 import 'java_engine.dart'; | 15 import 'java_engine.dart'; |
| 17 import 'source.dart'; | 16 import 'source.dart'; |
| 18 import 'utilities_collection.dart' show TokenMap; | 17 import 'utilities_collection.dart' show TokenMap; |
| 19 | 18 |
| 20 /** | 19 /** |
| 21 * Instances of the class `BeginToken` represent the opening half of a grouping
pair of | 20 * A `BeginToken` is the opening half of a grouping pair of tokens. This is used |
| 22 * tokens. This is used for curly brackets ('{'), parentheses ('('), and square
brackets ('['). | 21 * for curly brackets ('{'), parentheses ('('), and square brackets ('['). |
| 23 */ | 22 */ |
| 24 class BeginToken extends Token { | 23 class BeginToken extends Token { |
| 25 /** | 24 /** |
| 26 * The token that corresponds to this token. | 25 * The token that corresponds to this token. |
| 27 */ | 26 */ |
| 28 Token endToken; | 27 Token endToken; |
| 29 | 28 |
| 30 /** | 29 /** |
| 31 * Initialize a newly created token representing the opening half of a groupin
g pair of tokens. | 30 * Initialize a newly created token to have the given [type] at the given |
| 32 * | 31 * [offset]. |
| 33 * @param type the type of the token | |
| 34 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 35 */ | 32 */ |
| 36 BeginToken(TokenType type, int offset) : super(type, offset) { | 33 BeginToken(TokenType type, int offset) : super(type, offset) { |
| 37 assert((type == TokenType.OPEN_CURLY_BRACKET || | 34 assert(type == TokenType.OPEN_CURLY_BRACKET || |
| 38 type == TokenType.OPEN_PAREN || | 35 type == TokenType.OPEN_PAREN || |
| 39 type == TokenType.OPEN_SQUARE_BRACKET || | 36 type == TokenType.OPEN_SQUARE_BRACKET || |
| 40 type == TokenType.STRING_INTERPOLATION_EXPRESSION)); | 37 type == TokenType.STRING_INTERPOLATION_EXPRESSION); |
| 41 } | 38 } |
| 42 | 39 |
| 43 @override | 40 @override |
| 44 Token copy() => new BeginToken(type, offset); | 41 Token copy() => new BeginToken(type, offset); |
| 45 } | 42 } |
| 46 | 43 |
| 47 /** | 44 /** |
| 48 * Instances of the class `BeginTokenWithComment` represent a begin token that i
s preceded by | 45 * A `BeginTokenWithComment` is a begin token that is preceded by comments. |
| 49 * comments. | |
| 50 */ | 46 */ |
| 51 class BeginTokenWithComment extends BeginToken { | 47 class BeginTokenWithComment extends BeginToken { |
| 52 /** | 48 /** |
| 53 * The first comment in the list of comments that precede this token. | 49 * The first comment in the list of comments that precede this token. |
| 54 */ | 50 */ |
| 55 final Token _precedingComment; | 51 final Token _precedingComment; |
| 56 | 52 |
| 57 /** | 53 /** |
| 58 * Initialize a newly created token to have the given type and offset and to b
e preceded by the | 54 * Initialize a newly created token to have the given [type] at the given |
| 59 * comments reachable from the given comment. | 55 * [offset] and to be preceded by the comments reachable from the given |
| 60 * | 56 * [comment]. |
| 61 * @param type the type of the token | |
| 62 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 63 * @param precedingComment the first comment in the list of comments that prec
ede this token | |
| 64 */ | 57 */ |
| 65 BeginTokenWithComment(TokenType type, int offset, this._precedingComment) | 58 BeginTokenWithComment(TokenType type, int offset, this._precedingComment) |
| 66 : super(type, offset); | 59 : super(type, offset); |
| 67 | 60 |
| 68 @override | 61 @override |
| 69 Token get precedingComments => _precedingComment; | 62 Token get precedingComments => _precedingComment; |
| 70 | 63 |
| 71 @override | 64 @override |
| 72 void applyDelta(int delta) { | 65 void applyDelta(int delta) { |
| 73 super.applyDelta(delta); | 66 super.applyDelta(delta); |
| 74 Token token = _precedingComment; | 67 Token token = _precedingComment; |
| 75 while (token != null) { | 68 while (token != null) { |
| 76 token.applyDelta(delta); | 69 token.applyDelta(delta); |
| 77 token = token.next; | 70 token = token.next; |
| 78 } | 71 } |
| 79 } | 72 } |
| 80 | 73 |
| 81 @override | 74 @override |
| 82 Token copy() => | 75 Token copy() => |
| 83 new BeginTokenWithComment(type, offset, copyComments(_precedingComment)); | 76 new BeginTokenWithComment(type, offset, copyComments(_precedingComment)); |
| 84 } | 77 } |
| 85 | 78 |
| 86 /** | 79 /** |
| 87 * The interface `CharacterReader` | 80 * A `CharSequenceReader` is a [CharacterReader] that reads characters from a |
| 88 */ | 81 * character sequence. |
| 89 abstract class CharacterReader { | |
| 90 /** | |
| 91 * Return the current offset relative to the beginning of the source. Return t
he initial offset if | |
| 92 * the scanner has not yet scanned the source code, and one (1) past the end o
f the source code if | |
| 93 * the entire source code has been scanned. | |
| 94 * | |
| 95 * @return the current offset of the scanner in the source | |
| 96 */ | |
| 97 int get offset; | |
| 98 | |
| 99 /** | |
| 100 * Set the current offset relative to the beginning of the source. The new off
set must be between | |
| 101 * the initial offset and one (1) past the end of the source code. | |
| 102 * | |
| 103 * @param offset the new offset in the source | |
| 104 */ | |
| 105 void set offset(int offset); | |
| 106 | |
| 107 /** | |
| 108 * Advance the current position and return the character at the new current po
sition. | |
| 109 * | |
| 110 * @return the character at the new current position | |
| 111 */ | |
| 112 int advance(); | |
| 113 | |
| 114 /** | |
| 115 * Return the substring of the source code between the start offset and the mo
dified current | |
| 116 * position. The current position is modified by adding the end delta. | |
| 117 * | |
| 118 * @param start the offset to the beginning of the string, relative to the sta
rt of the file | |
| 119 * @param endDelta the number of characters after the current location to be i
ncluded in the | |
| 120 * string, or the number of characters before the current location to
be excluded if the | |
| 121 * offset is negative | |
| 122 * @return the specified substring of the source code | |
| 123 */ | |
| 124 String getString(int start, int endDelta); | |
| 125 | |
| 126 /** | |
| 127 * Return the character at the current position without changing the current p
osition. | |
| 128 * | |
| 129 * @return the character at the current position | |
| 130 */ | |
| 131 int peek(); | |
| 132 } | |
| 133 | |
| 134 /** | |
| 135 * Instances of the class `CharSequenceReader` implement a [CharacterReader] tha
t reads | |
| 136 * characters from a character sequence. | |
| 137 */ | 82 */ |
| 138 class CharSequenceReader implements CharacterReader { | 83 class CharSequenceReader implements CharacterReader { |
| 139 /** | 84 /** |
| 140 * The sequence from which characters will be read. | 85 * The sequence from which characters will be read. |
| 141 */ | 86 */ |
| 142 final String _sequence; | 87 final String _sequence; |
| 143 | 88 |
| 144 /** | 89 /** |
| 145 * The number of characters in the string. | 90 * The number of characters in the string. |
| 146 */ | 91 */ |
| 147 int _stringLength = 0; | 92 int _stringLength = 0; |
| 148 | 93 |
| 149 /** | 94 /** |
| 150 * The index, relative to the string, of the last character that was read. | 95 * The index, relative to the string, of the last character that was read. |
| 151 */ | 96 */ |
| 152 int _charOffset = 0; | 97 int _charOffset = 0; |
| 153 | 98 |
| 154 /** | 99 /** |
| 155 * Initialize a newly created reader to read the characters in the given seque
nce. | 100 * Initialize a newly created reader to read the characters in the given |
| 156 * | 101 * [_sequence]. |
| 157 * @param sequence the sequence from which characters will be read | |
| 158 */ | 102 */ |
| 159 CharSequenceReader(this._sequence) { | 103 CharSequenceReader(this._sequence) { |
| 160 this._stringLength = _sequence.length; | 104 this._stringLength = _sequence.length; |
| 161 this._charOffset = -1; | 105 this._charOffset = -1; |
| 162 } | 106 } |
| 163 | 107 |
| 164 @override | 108 @override |
| 165 int get offset => _charOffset; | 109 int get offset => _charOffset; |
| 166 | 110 |
| 167 @override | 111 @override |
| (...skipping 16 matching lines...) Expand all Loading... |
| 184 @override | 128 @override |
| 185 int peek() { | 129 int peek() { |
| 186 if (_charOffset + 1 >= _stringLength) { | 130 if (_charOffset + 1 >= _stringLength) { |
| 187 return -1; | 131 return -1; |
| 188 } | 132 } |
| 189 return _sequence.codeUnitAt(_charOffset + 1); | 133 return _sequence.codeUnitAt(_charOffset + 1); |
| 190 } | 134 } |
| 191 } | 135 } |
| 192 | 136 |
| 193 /** | 137 /** |
| 138 * A `CharacterRangeReader` is a [CharacterReader] that reads a range of |
| 139 * characters from another character reader. |
| 140 */ |
| 141 class CharacterRangeReader extends CharacterReader { |
| 142 /** |
| 143 * The reader from which the characters are actually being read. |
| 144 */ |
| 145 final CharacterReader baseReader; |
| 146 |
| 147 /** |
| 148 * The last character to be read. |
| 149 */ |
| 150 final int endIndex; |
| 151 |
| 152 /** |
| 153 * Initialize a newly created reader to read the characters from the given |
| 154 * [baseReader] between the [startIndex] inclusive to [endIndex] exclusive. |
| 155 */ |
| 156 CharacterRangeReader(this.baseReader, int startIndex, this.endIndex) { |
| 157 baseReader.offset = startIndex - 1; |
| 158 } |
| 159 |
| 160 @override |
| 161 int get offset => baseReader.offset; |
| 162 |
| 163 @override |
| 164 void set offset(int offset) { |
| 165 baseReader.offset = offset; |
| 166 } |
| 167 |
| 168 @override |
| 169 int advance() { |
| 170 if (baseReader.offset + 1 >= endIndex) { |
| 171 return -1; |
| 172 } |
| 173 return baseReader.advance(); |
| 174 } |
| 175 |
| 176 @override |
| 177 String getString(int start, int endDelta) => |
| 178 baseReader.getString(start, endDelta); |
| 179 |
| 180 @override |
| 181 int peek() { |
| 182 if (baseReader.offset + 1 >= endIndex) { |
| 183 return -1; |
| 184 } |
| 185 return baseReader.peek(); |
| 186 } |
| 187 } |
| 188 |
| 189 /** |
| 190 * A `CharacterReader` is used by the scanner to read the characters to be |
| 191 * scanned. |
| 192 */ |
| 193 abstract class CharacterReader { |
| 194 /** |
| 195 * The current offset relative to the beginning of the source. Return the |
| 196 * initial offset if the scanner has not yet scanned the source code, and one |
| 197 * (1) past the end of the source code if the entire source code has been |
| 198 * scanned. |
| 199 */ |
| 200 int get offset; |
| 201 |
| 202 /** |
| 203 * Set the current offset relative to the beginning of the source to the given |
| 204 * [offset]. The new offset must be between the initial offset and one (1) |
| 205 * past the end of the source code. |
| 206 */ |
| 207 void set offset(int offset); |
| 208 |
| 209 /** |
| 210 * Advance the current position and return the character at the new current |
| 211 * position. |
| 212 */ |
| 213 int advance(); |
| 214 |
| 215 /** |
| 216 * Return the substring of the source code between the [start] offset and the |
| 217 * modified current position. The current position is modified by adding the |
| 218 * [endDelta], which is the number of characters after the current location to |
| 219 * be included in the string, or the number of characters before the current |
| 220 * location to be excluded if the offset is negative. |
| 221 */ |
| 222 String getString(int start, int endDelta); |
| 223 |
| 224 /** |
| 225 * Return the character at the current position without changing the current |
| 226 * position. |
| 227 */ |
| 228 int peek(); |
| 229 } |
| 230 |
| 231 /** |
| 194 * Instances of the class `IncrementalScanner` implement a scanner that scans a
subset of a | 232 * Instances of the class `IncrementalScanner` implement a scanner that scans a
subset of a |
| 195 * string and inserts the resulting tokens into the middle of an existing token
stream. | 233 * string and inserts the resulting tokens into the middle of an existing token
stream. |
| 196 */ | 234 */ |
| 197 class IncrementalScanner extends Scanner { | 235 class IncrementalScanner extends Scanner { |
| 198 /** | 236 /** |
| 199 * The reader used to access the characters in the source. | 237 * The reader used to access the characters in the source. |
| 200 */ | 238 */ |
| 201 CharacterReader _reader; | 239 CharacterReader _reader; |
| 202 | 240 |
| 203 /** | 241 /** |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 // when we're copying the begin tokens). This could have implications for | 437 // when we're copying the begin tokens). This could have implications for |
| 400 // parsing. | 438 // parsing. |
| 401 // TODO(brianwilkerson) Update the lineInfo. | 439 // TODO(brianwilkerson) Update the lineInfo. |
| 402 // | 440 // |
| 403 return firstToken; | 441 return firstToken; |
| 404 } | 442 } |
| 405 | 443 |
| 406 Token _copyAndAdvance(Token originalToken, int delta) { | 444 Token _copyAndAdvance(Token originalToken, int delta) { |
| 407 Token copiedToken = originalToken.copy(); | 445 Token copiedToken = originalToken.copy(); |
| 408 _tokenMap.put(originalToken, copiedToken); | 446 _tokenMap.put(originalToken, copiedToken); |
| 409 copiedToken.applyDelta(delta); | 447 copiedToken.offset += delta; |
| 410 appendToken(copiedToken); | 448 appendToken(copiedToken); |
| 411 Token originalComment = originalToken.precedingComments; | 449 Token originalComment = originalToken.precedingComments; |
| 412 Token copiedComment = originalToken.precedingComments; | 450 Token copiedComment = originalToken.precedingComments; |
| 413 while (originalComment != null) { | 451 while (originalComment != null) { |
| 414 _tokenMap.put(originalComment, copiedComment); | 452 _tokenMap.put(originalComment, copiedComment); |
| 415 originalComment = originalComment.next; | 453 originalComment = originalComment.next; |
| 416 copiedComment = copiedComment.next; | 454 copiedComment = copiedComment.next; |
| 417 } | 455 } |
| 418 return originalToken.next; | 456 return originalToken.next; |
| 419 } | 457 } |
| 420 | 458 |
| 421 /** | 459 /** |
| 422 * Return `true` if the two tokens are equal to each other. For the purposes o
f the | 460 * Return `true` if the two tokens are equal to each other. For the purposes o
f the |
| 423 * incremental scanner, two tokens are equal if they have the same type and le
xeme. | 461 * incremental scanner, two tokens are equal if they have the same type and le
xeme. |
| 424 * | 462 * |
| 425 * @param oldToken the token from the old stream that is being compared | 463 * @param oldToken the token from the old stream that is being compared |
| 426 * @param newToken the token from the new stream that is being compared | 464 * @param newToken the token from the new stream that is being compared |
| 427 * @return `true` if the two tokens are equal to each other | 465 * @return `true` if the two tokens are equal to each other |
| 428 */ | 466 */ |
| 429 bool _equalTokens(Token oldToken, Token newToken) => | 467 bool _equalTokens(Token oldToken, Token newToken) => |
| 430 oldToken.type == newToken.type && | 468 oldToken.type == newToken.type && |
| 431 oldToken.length == newToken.length && | 469 oldToken.length == newToken.length && |
| 432 oldToken.lexeme == newToken.lexeme; | 470 oldToken.lexeme == newToken.lexeme; |
| 433 } | 471 } |
| 434 | 472 |
| 435 /** | 473 /** |
| 436 * The enumeration `Keyword` defines the keywords in the Dart programming langua
ge. | 474 * The enumeration `Keyword` defines the keywords in the Dart programming |
| 475 * language. |
| 437 */ | 476 */ |
| 438 class Keyword extends Enum<Keyword> { | 477 class Keyword { |
| 439 static const Keyword ASSERT = const Keyword.con1('ASSERT', 0, "assert"); | 478 static const Keyword ASSERT = const Keyword('ASSERT', "assert"); |
| 440 | 479 |
| 441 static const Keyword BREAK = const Keyword.con1('BREAK', 1, "break"); | 480 static const Keyword BREAK = const Keyword('BREAK', "break"); |
| 442 | 481 |
| 443 static const Keyword CASE = const Keyword.con1('CASE', 2, "case"); | 482 static const Keyword CASE = const Keyword('CASE', "case"); |
| 444 | 483 |
| 445 static const Keyword CATCH = const Keyword.con1('CATCH', 3, "catch"); | 484 static const Keyword CATCH = const Keyword('CATCH', "catch"); |
| 446 | 485 |
| 447 static const Keyword CLASS = const Keyword.con1('CLASS', 4, "class"); | 486 static const Keyword CLASS = const Keyword('CLASS', "class"); |
| 448 | 487 |
| 449 static const Keyword CONST = const Keyword.con1('CONST', 5, "const"); | 488 static const Keyword CONST = const Keyword('CONST', "const"); |
| 450 | 489 |
| 451 static const Keyword CONTINUE = const Keyword.con1('CONTINUE', 6, "continue"); | 490 static const Keyword CONTINUE = const Keyword('CONTINUE', "continue"); |
| 452 | 491 |
| 453 static const Keyword DEFAULT = const Keyword.con1('DEFAULT', 7, "default"); | 492 static const Keyword DEFAULT = const Keyword('DEFAULT', "default"); |
| 454 | 493 |
| 455 static const Keyword DO = const Keyword.con1('DO', 8, "do"); | 494 static const Keyword DO = const Keyword('DO', "do"); |
| 456 | 495 |
| 457 static const Keyword ELSE = const Keyword.con1('ELSE', 9, "else"); | 496 static const Keyword ELSE = const Keyword('ELSE', "else"); |
| 458 | 497 |
| 459 static const Keyword ENUM = const Keyword.con1('ENUM', 10, "enum"); | 498 static const Keyword ENUM = const Keyword('ENUM', "enum"); |
| 460 | 499 |
| 461 static const Keyword EXTENDS = const Keyword.con1('EXTENDS', 11, "extends"); | 500 static const Keyword EXTENDS = const Keyword('EXTENDS', "extends"); |
| 462 | 501 |
| 463 static const Keyword FALSE = const Keyword.con1('FALSE', 12, "false"); | 502 static const Keyword FALSE = const Keyword('FALSE', "false"); |
| 464 | 503 |
| 465 static const Keyword FINAL = const Keyword.con1('FINAL', 13, "final"); | 504 static const Keyword FINAL = const Keyword('FINAL', "final"); |
| 466 | 505 |
| 467 static const Keyword FINALLY = const Keyword.con1('FINALLY', 14, "finally"); | 506 static const Keyword FINALLY = const Keyword('FINALLY', "finally"); |
| 468 | 507 |
| 469 static const Keyword FOR = const Keyword.con1('FOR', 15, "for"); | 508 static const Keyword FOR = const Keyword('FOR', "for"); |
| 470 | 509 |
| 471 static const Keyword IF = const Keyword.con1('IF', 16, "if"); | 510 static const Keyword IF = const Keyword('IF', "if"); |
| 472 | 511 |
| 473 static const Keyword IN = const Keyword.con1('IN', 17, "in"); | 512 static const Keyword IN = const Keyword('IN', "in"); |
| 474 | 513 |
| 475 static const Keyword IS = const Keyword.con1('IS', 18, "is"); | 514 static const Keyword IS = const Keyword('IS', "is"); |
| 476 | 515 |
| 477 static const Keyword NEW = const Keyword.con1('NEW', 19, "new"); | 516 static const Keyword NEW = const Keyword('NEW', "new"); |
| 478 | 517 |
| 479 static const Keyword NULL = const Keyword.con1('NULL', 20, "null"); | 518 static const Keyword NULL = const Keyword('NULL', "null"); |
| 480 | 519 |
| 481 static const Keyword RETHROW = const Keyword.con1('RETHROW', 21, "rethrow"); | 520 static const Keyword RETHROW = const Keyword('RETHROW', "rethrow"); |
| 482 | 521 |
| 483 static const Keyword RETURN = const Keyword.con1('RETURN', 22, "return"); | 522 static const Keyword RETURN = const Keyword('RETURN', "return"); |
| 484 | 523 |
| 485 static const Keyword SUPER = const Keyword.con1('SUPER', 23, "super"); | 524 static const Keyword SUPER = const Keyword('SUPER', "super"); |
| 486 | 525 |
| 487 static const Keyword SWITCH = const Keyword.con1('SWITCH', 24, "switch"); | 526 static const Keyword SWITCH = const Keyword('SWITCH', "switch"); |
| 488 | 527 |
| 489 static const Keyword THIS = const Keyword.con1('THIS', 25, "this"); | 528 static const Keyword THIS = const Keyword('THIS', "this"); |
| 490 | 529 |
| 491 static const Keyword THROW = const Keyword.con1('THROW', 26, "throw"); | 530 static const Keyword THROW = const Keyword('THROW', "throw"); |
| 492 | 531 |
| 493 static const Keyword TRUE = const Keyword.con1('TRUE', 27, "true"); | 532 static const Keyword TRUE = const Keyword('TRUE', "true"); |
| 494 | 533 |
| 495 static const Keyword TRY = const Keyword.con1('TRY', 28, "try"); | 534 static const Keyword TRY = const Keyword('TRY', "try"); |
| 496 | 535 |
| 497 static const Keyword VAR = const Keyword.con1('VAR', 29, "var"); | 536 static const Keyword VAR = const Keyword('VAR', "var"); |
| 498 | 537 |
| 499 static const Keyword VOID = const Keyword.con1('VOID', 30, "void"); | 538 static const Keyword VOID = const Keyword('VOID', "void"); |
| 500 | 539 |
| 501 static const Keyword WHILE = const Keyword.con1('WHILE', 31, "while"); | 540 static const Keyword WHILE = const Keyword('WHILE', "while"); |
| 502 | 541 |
| 503 static const Keyword WITH = const Keyword.con1('WITH', 32, "with"); | 542 static const Keyword WITH = const Keyword('WITH', "with"); |
| 504 | 543 |
| 505 static const Keyword ABSTRACT = | 544 static const Keyword ABSTRACT = const Keyword('ABSTRACT', "abstract", true); |
| 506 const Keyword.con2('ABSTRACT', 33, "abstract", true); | |
| 507 | 545 |
| 508 static const Keyword AS = const Keyword.con2('AS', 34, "as", true); | 546 static const Keyword AS = const Keyword('AS', "as", true); |
| 509 | 547 |
| 510 static const Keyword DEFERRED = | 548 static const Keyword DEFERRED = const Keyword('DEFERRED', "deferred", true); |
| 511 const Keyword.con2('DEFERRED', 35, "deferred", true); | |
| 512 | 549 |
| 513 static const Keyword DYNAMIC = | 550 static const Keyword DYNAMIC = const Keyword('DYNAMIC', "dynamic", true); |
| 514 const Keyword.con2('DYNAMIC', 36, "dynamic", true); | |
| 515 | 551 |
| 516 static const Keyword EXPORT = | 552 static const Keyword EXPORT = const Keyword('EXPORT', "export", true); |
| 517 const Keyword.con2('EXPORT', 37, "export", true); | |
| 518 | 553 |
| 519 static const Keyword EXTERNAL = | 554 static const Keyword EXTERNAL = const Keyword('EXTERNAL', "external", true); |
| 520 const Keyword.con2('EXTERNAL', 38, "external", true); | |
| 521 | 555 |
| 522 static const Keyword FACTORY = | 556 static const Keyword FACTORY = const Keyword('FACTORY', "factory", true); |
| 523 const Keyword.con2('FACTORY', 39, "factory", true); | |
| 524 | 557 |
| 525 static const Keyword GET = const Keyword.con2('GET', 40, "get", true); | 558 static const Keyword GET = const Keyword('GET', "get", true); |
| 526 | 559 |
| 527 static const Keyword IMPLEMENTS = | 560 static const Keyword IMPLEMENTS = |
| 528 const Keyword.con2('IMPLEMENTS', 41, "implements", true); | 561 const Keyword('IMPLEMENTS', "implements", true); |
| 529 | 562 |
| 530 static const Keyword IMPORT = | 563 static const Keyword IMPORT = const Keyword('IMPORT', "import", true); |
| 531 const Keyword.con2('IMPORT', 42, "import", true); | |
| 532 | 564 |
| 533 static const Keyword LIBRARY = | 565 static const Keyword LIBRARY = const Keyword('LIBRARY', "library", true); |
| 534 const Keyword.con2('LIBRARY', 43, "library", true); | |
| 535 | 566 |
| 536 static const Keyword OPERATOR = | 567 static const Keyword OPERATOR = const Keyword('OPERATOR', "operator", true); |
| 537 const Keyword.con2('OPERATOR', 44, "operator", true); | |
| 538 | 568 |
| 539 static const Keyword PART = const Keyword.con2('PART', 45, "part", true); | 569 static const Keyword PART = const Keyword('PART', "part", true); |
| 540 | 570 |
| 541 static const Keyword SET = const Keyword.con2('SET', 46, "set", true); | 571 static const Keyword SET = const Keyword('SET', "set", true); |
| 542 | 572 |
| 543 static const Keyword STATIC = | 573 static const Keyword STATIC = const Keyword('STATIC', "static", true); |
| 544 const Keyword.con2('STATIC', 47, "static", true); | |
| 545 | 574 |
| 546 static const Keyword TYPEDEF = | 575 static const Keyword TYPEDEF = const Keyword('TYPEDEF', "typedef", true); |
| 547 const Keyword.con2('TYPEDEF', 48, "typedef", true); | |
| 548 | 576 |
| 549 static const List<Keyword> values = const [ | 577 static const List<Keyword> values = const [ |
| 550 ASSERT, | 578 ASSERT, |
| 551 BREAK, | 579 BREAK, |
| 552 CASE, | 580 CASE, |
| 553 CATCH, | 581 CATCH, |
| 554 CLASS, | 582 CLASS, |
| 555 CONST, | 583 CONST, |
| 556 CONTINUE, | 584 CONTINUE, |
| 557 DEFAULT, | 585 DEFAULT, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 LIBRARY, | 621 LIBRARY, |
| 594 OPERATOR, | 622 OPERATOR, |
| 595 PART, | 623 PART, |
| 596 SET, | 624 SET, |
| 597 STATIC, | 625 STATIC, |
| 598 TYPEDEF]; | 626 TYPEDEF]; |
| 599 | 627 |
| 600 /** | 628 /** |
| 601 * A table mapping the lexemes of keywords to the corresponding keyword. | 629 * A table mapping the lexemes of keywords to the corresponding keyword. |
| 602 */ | 630 */ |
| 603 static Map<String, Keyword> keywords = _createKeywordMap(); | 631 static final Map<String, Keyword> keywords = _createKeywordMap(); |
| 632 |
| 633 /** |
| 634 * The name of the keyword type. |
| 635 */ |
| 636 final String name; |
| 604 | 637 |
| 605 /** | 638 /** |
| 606 * The lexeme for the keyword. | 639 * The lexeme for the keyword. |
| 607 */ | 640 */ |
| 608 final String syntax; | 641 final String syntax; |
| 609 | 642 |
| 610 /** | 643 /** |
| 611 * A flag indicating whether the keyword is a pseudo-keyword. Pseudo keywords
can be used as | 644 * A flag indicating whether the keyword is a pseudo-keyword. Pseudo keywords |
| 612 * identifiers. | 645 * can be used as identifiers. |
| 613 */ | 646 */ |
| 614 final bool isPseudoKeyword; | 647 final bool isPseudoKeyword; |
| 615 | 648 |
| 616 /** | 649 /** |
| 617 * Initialize a newly created keyword to have the given syntax. The keyword is
not a | 650 * Initialize a newly created keyword to have the given [name] and [syntax]. |
| 618 * pseudo-keyword. | 651 * The keyword is a pseudo-keyword if the [isPseudoKeyword] flag is `true`. |
| 619 * | |
| 620 * @param syntax the lexeme for the keyword | |
| 621 */ | 652 */ |
| 622 const Keyword.con1(String name, int ordinal, String syntax) | 653 const Keyword(this.name, this.syntax, [this.isPseudoKeyword = false]); |
| 623 : this.con2(name, ordinal, syntax, false); | |
| 624 | 654 |
| 625 /** | 655 /** |
| 626 * Initialize a newly created keyword to have the given syntax. The keyword is
a pseudo-keyword if | 656 * Create a table mapping the lexemes of keywords to the corresponding keyword |
| 627 * the given flag is `true`. | 657 * and return the table that was created. |
| 628 * | |
| 629 * @param syntax the lexeme for the keyword | |
| 630 * @param isPseudoKeyword `true` if this keyword is a pseudo-keyword | |
| 631 */ | |
| 632 const Keyword.con2(String name, int ordinal, this.syntax, | |
| 633 this.isPseudoKeyword) | |
| 634 : super(name, ordinal); | |
| 635 | |
| 636 /** | |
| 637 * Create a table mapping the lexemes of keywords to the corresponding keyword
. | |
| 638 * | |
| 639 * @return the table that was created | |
| 640 */ | 658 */ |
| 641 static Map<String, Keyword> _createKeywordMap() { | 659 static Map<String, Keyword> _createKeywordMap() { |
| 642 LinkedHashMap<String, Keyword> result = | 660 LinkedHashMap<String, Keyword> result = |
| 643 new LinkedHashMap<String, Keyword>(); | 661 new LinkedHashMap<String, Keyword>(); |
| 644 for (Keyword keyword in values) { | 662 for (Keyword keyword in values) { |
| 645 result[keyword.syntax] = keyword; | 663 result[keyword.syntax] = keyword; |
| 646 } | 664 } |
| 647 return result; | 665 return result; |
| 648 } | 666 } |
| 649 } | 667 } |
| 650 | 668 |
| 651 /** | 669 /** |
| 652 * Instances of the abstract class `KeywordState` represent a state in a state m
achine used to | 670 * A `KeywordState` is a state in a state machine used to scan keywords. |
| 653 * scan keywords. | |
| 654 */ | 671 */ |
| 655 class KeywordState { | 672 class KeywordState { |
| 656 /** | 673 /** |
| 657 * An empty transition table used by leaf states. | 674 * An empty transition table used by leaf states. |
| 658 */ | 675 */ |
| 659 static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26); | 676 static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>(26); |
| 660 | 677 |
| 661 /** | 678 /** |
| 662 * The initial state in the state machine. | 679 * The initial state in the state machine. |
| 663 */ | 680 */ |
| 664 static KeywordState KEYWORD_STATE = _createKeywordStateTable(); | 681 static final KeywordState KEYWORD_STATE = _createKeywordStateTable(); |
| 665 | 682 |
| 666 /** | 683 /** |
| 667 * A table mapping characters to the states to which those characters will tra
nsition. (The index | 684 * A table mapping characters to the states to which those characters will |
| 668 * into the array is the offset from the character `'a'` to the transitioning
character.) | 685 * transition. (The index into the array is the offset from the character |
| 686 * `'a'` to the transitioning character.) |
| 669 */ | 687 */ |
| 670 final List<KeywordState> _table; | 688 final List<KeywordState> _table; |
| 671 | 689 |
| 672 /** | 690 /** |
| 673 * The keyword that is recognized by this state, or `null` if this state is no
t a terminal | 691 * The keyword that is recognized by this state, or `null` if this state is |
| 674 * state. | 692 * not a terminal state. |
| 675 */ | 693 */ |
| 676 Keyword _keyword; | 694 Keyword _keyword; |
| 677 | 695 |
| 678 /** | 696 /** |
| 679 * Initialize a newly created state to have the given transitions and to recog
nize the keyword | 697 * Initialize a newly created state to have the given transitions and to |
| 680 * with the given syntax. | 698 * recognize the keyword with the given [syntax]. |
| 681 * | |
| 682 * @param table a table mapping characters to the states to which those charac
ters will transition | |
| 683 * @param syntax the syntax of the keyword that is recognized by the state | |
| 684 */ | 699 */ |
| 685 KeywordState(this._table, String syntax) { | 700 KeywordState(this._table, String syntax) { |
| 686 this._keyword = (syntax == null) ? null : Keyword.keywords[syntax]; | 701 this._keyword = (syntax == null) ? null : Keyword.keywords[syntax]; |
| 687 } | 702 } |
| 688 | 703 |
| 689 /** | 704 /** |
| 690 * Return the keyword that was recognized by this state, or `null` if this sta
te does not | 705 * Return the keyword that was recognized by this state, or `null` if this |
| 691 * recognized a keyword. | 706 * state does not recognized a keyword. |
| 692 * | |
| 693 * @return the keyword that was matched by reaching this state | |
| 694 */ | 707 */ |
| 695 Keyword keyword() => _keyword; | 708 Keyword keyword() => _keyword; |
| 696 | 709 |
| 697 /** | 710 /** |
| 698 * Return the state that follows this state on a transition of the given chara
cter, or | 711 * Return the state that follows this state on a transition of the given |
| 699 * `null` if there is no valid state reachable from this state with such a tra
nsition. | 712 * [character], or `null` if there is no valid state reachable from this state |
| 700 * | 713 * with such a transition. |
| 701 * @param c the character used to transition from this state to another state | |
| 702 * @return the state that follows this state on a transition of the given char
acter | |
| 703 */ | 714 */ |
| 704 KeywordState next(int c) => _table[c - 0x61]; | 715 KeywordState next(int character) => _table[character - 0x61]; |
| 705 | 716 |
| 706 /** | 717 /** |
| 707 * Create the next state in the state machine where we have already recognized
the subset of | 718 * Create the next state in the state machine where we have already recognized |
| 708 * strings in the given array of strings starting at the given offset and havi
ng the given length. | 719 * the subset of strings in the given array of [strings] starting at the given |
| 709 * All of these strings have a common prefix and the next character is at the
given start index. | 720 * [offset] and having the given [length]. All of these strings have a common |
| 721 * prefix and the next character is at the given [start] index. |
| 710 * | 722 * |
| 711 * @param start the index of the character in the strings used to transition t
o a new state | 723 * [start] the index of the character in the strings used to transition to a |
| 712 * @param strings an array containing all of the strings that will be recogniz
ed by the state | 724 * new state |
| 713 * machine | 725 * [strings] an array containing all of the strings that will be recognized by |
| 714 * @param offset the offset of the first string in the array that has the pref
ix that is assumed | 726 * the state machine |
| 715 * to have been recognized by the time we reach the state being built | 727 * [offset] the offset of the first string in the array that has the prefix |
| 716 * @param length the number of strings in the array that pass through the stat
e being built | 728 * that is assumed to have been recognized by the time we reach the state |
| 717 * @return the state that was created | 729 * being built |
| 730 * [length] the number of strings in the array that pass through the state |
| 731 * being built |
| 718 */ | 732 */ |
| 719 static KeywordState _computeKeywordStateTable(int start, List<String> strings, | 733 static KeywordState _computeKeywordStateTable(int start, List<String> strings, |
| 720 int offset, int length) { | 734 int offset, int length) { |
| 721 List<KeywordState> result = new List<KeywordState>(26); | 735 List<KeywordState> result = new List<KeywordState>(26); |
| 722 assert(length != 0); | 736 assert(length != 0); |
| 723 int chunk = 0x0; | 737 int chunk = 0x0; |
| 724 int chunkStart = -1; | 738 int chunkStart = -1; |
| 725 bool isLeaf = false; | 739 bool isLeaf = false; |
| 726 for (int i = offset; i < offset + length; i++) { | 740 for (int i = offset; i < offset + length; i++) { |
| 727 if (strings[i].length == start) { | 741 if (strings[i].length == start) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 752 return new KeywordState(_EMPTY_TABLE, strings[offset]); | 766 return new KeywordState(_EMPTY_TABLE, strings[offset]); |
| 753 } | 767 } |
| 754 if (isLeaf) { | 768 if (isLeaf) { |
| 755 return new KeywordState(result, strings[offset]); | 769 return new KeywordState(result, strings[offset]); |
| 756 } else { | 770 } else { |
| 757 return new KeywordState(result, null); | 771 return new KeywordState(result, null); |
| 758 } | 772 } |
| 759 } | 773 } |
| 760 | 774 |
| 761 /** | 775 /** |
| 762 * Create the initial state in the state machine. | 776 * Create and return the initial state in the state machine. |
| 763 * | |
| 764 * @return the state that was created | |
| 765 */ | 777 */ |
| 766 static KeywordState _createKeywordStateTable() { | 778 static KeywordState _createKeywordStateTable() { |
| 767 List<Keyword> values = Keyword.values; | 779 List<Keyword> values = Keyword.values; |
| 768 List<String> strings = new List<String>(values.length); | 780 List<String> strings = new List<String>(values.length); |
| 769 for (int i = 0; i < values.length; i++) { | 781 for (int i = 0; i < values.length; i++) { |
| 770 strings[i] = values[i].syntax; | 782 strings[i] = values[i].syntax; |
| 771 } | 783 } |
| 772 strings.sort(); | 784 strings.sort(); |
| 773 return _computeKeywordStateTable(0, strings, 0, strings.length); | 785 return _computeKeywordStateTable(0, strings, 0, strings.length); |
| 774 } | 786 } |
| 775 } | 787 } |
| 776 | 788 |
| 777 /** | 789 /** |
| 778 * Instances of the class `KeywordToken` represent a keyword in the language. | 790 * A `KeywordToken` is a keyword in the language. |
| 779 */ | 791 */ |
| 780 class KeywordToken extends Token { | 792 class KeywordToken extends Token { |
| 781 /** | 793 /** |
| 782 * The keyword being represented by this token. | 794 * The keyword being represented by this token. |
| 783 */ | 795 */ |
| 784 final Keyword keyword; | 796 final Keyword keyword; |
| 785 | 797 |
| 786 /** | 798 /** |
| 787 * Initialize a newly created token to represent the given keyword. | 799 * Initialize a newly created token to represent the given [keyword] at the |
| 788 * | 800 * given [offset]. |
| 789 * @param keyword the keyword being represented by this token | |
| 790 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 791 */ | 801 */ |
| 792 KeywordToken(this.keyword, int offset) : super(TokenType.KEYWORD, offset); | 802 KeywordToken(this.keyword, int offset) : super(TokenType.KEYWORD, offset); |
| 793 | 803 |
| 794 @override | 804 @override |
| 795 String get lexeme => keyword.syntax; | 805 String get lexeme => keyword.syntax; |
| 796 | 806 |
| 797 @override | 807 @override |
| 798 Token copy() => new KeywordToken(keyword, offset); | 808 Token copy() => new KeywordToken(keyword, offset); |
| 799 | 809 |
| 800 @override | 810 @override |
| 801 Keyword value() => keyword; | 811 Keyword value() => keyword; |
| 802 } | 812 } |
| 803 | 813 |
| 804 /** | 814 /** |
| 805 * Instances of the class `KeywordTokenWithComment` implement a keyword token th
at is preceded | 815 * A `KeywordTokenWithComment` is a keyword token that is preceded by comments. |
| 806 * by comments. | |
| 807 */ | 816 */ |
| 808 class KeywordTokenWithComment extends KeywordToken { | 817 class KeywordTokenWithComment extends KeywordToken { |
| 809 /** | 818 /** |
| 810 * The first comment in the list of comments that precede this token. | 819 * The first comment in the list of comments that precede this token. |
| 811 */ | 820 */ |
| 812 final Token _precedingComment; | 821 final Token _precedingComment; |
| 813 | 822 |
| 814 /** | 823 /** |
| 815 * Initialize a newly created token to to represent the given keyword and to b
e preceded by the | 824 * Initialize a newly created token to to represent the given [keyword] at the |
| 816 * comments reachable from the given comment. | 825 * given [offset] and to be preceded by the comments reachable from the given |
| 817 * | 826 * [comment]. |
| 818 * @param keyword the keyword being represented by this token | |
| 819 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 820 * @param precedingComment the first comment in the list of comments that prec
ede this token | |
| 821 */ | 827 */ |
| 822 KeywordTokenWithComment(Keyword keyword, int offset, this._precedingComment) | 828 KeywordTokenWithComment(Keyword keyword, int offset, this._precedingComment) |
| 823 : super(keyword, offset); | 829 : super(keyword, offset); |
| 824 | 830 |
| 825 @override | 831 @override |
| 826 Token get precedingComments => _precedingComment; | 832 Token get precedingComments => _precedingComment; |
| 827 | 833 |
| 828 @override | 834 @override |
| 829 void applyDelta(int delta) { | 835 void applyDelta(int delta) { |
| 830 super.applyDelta(delta); | 836 super.applyDelta(delta); |
| 831 Token token = _precedingComment; | 837 Token token = _precedingComment; |
| 832 while (token != null) { | 838 while (token != null) { |
| 833 token.applyDelta(delta); | 839 token.applyDelta(delta); |
| 834 token = token.next; | 840 token = token.next; |
| 835 } | 841 } |
| 836 } | 842 } |
| 837 | 843 |
| 838 @override | 844 @override |
| 839 Token copy() => | 845 Token copy() => |
| 840 new KeywordTokenWithComment(keyword, offset, copyComments(_precedingCommen
t)); | 846 new KeywordTokenWithComment(keyword, offset, copyComments(_precedingCommen
t)); |
| 841 } | 847 } |
| 842 | 848 |
| 843 /** | 849 /** |
| 844 * The class `Scanner` implements a scanner for Dart code. | 850 * The class `Scanner` implements a scanner for Dart code. |
| 845 * | 851 * |
| 846 * The lexical structure of Dart is ambiguous without knowledge of the context i
n which a token is | 852 * The lexical structure of Dart is ambiguous without knowledge of the context |
| 847 * being scanned. For example, without context we cannot determine whether sourc
e of the form "<<" | 853 * in which a token is being scanned. For example, without context we cannot |
| 848 * should be scanned as a single left-shift operator or as two left angle bracke
ts. This scanner | 854 * determine whether source of the form "<<" should be scanned as a single |
| 849 * does not have any context, so it always resolves such conflicts by scanning t
he longest possible | 855 * left-shift operator or as two left angle brackets. This scanner does not have |
| 850 * token. | 856 * any context, so it always resolves such conflicts by scanning the longest |
| 857 * possible token. |
| 851 */ | 858 */ |
| 852 class Scanner { | 859 class Scanner { |
| 853 /** | 860 /** |
| 854 * The source being scanned. | 861 * The source being scanned. |
| 855 */ | 862 */ |
| 856 final Source source; | 863 final Source source; |
| 857 | 864 |
| 858 /** | 865 /** |
| 859 * The reader used to access the characters in the source. | 866 * The reader used to access the characters in the source. |
| 860 */ | 867 */ |
| 861 final CharacterReader _reader; | 868 final CharacterReader _reader; |
| 862 | 869 |
| 863 /** | 870 /** |
| 864 * The error listener that will be informed of any errors that are found durin
g the scan. | 871 * The error listener that will be informed of any errors that are found |
| 872 * during the scan. |
| 865 */ | 873 */ |
| 866 final AnalysisErrorListener _errorListener; | 874 final AnalysisErrorListener _errorListener; |
| 867 | 875 |
| 868 /** | 876 /** |
| 869 * The flag specifying if documentation comments should be parsed. | 877 * The flag specifying whether documentation comments should be parsed. |
| 870 */ | 878 */ |
| 871 bool _preserveComments = true; | 879 bool _preserveComments = true; |
| 872 | 880 |
| 873 /** | 881 /** |
| 874 * The token pointing to the head of the linked list of tokens. | 882 * The token pointing to the head of the linked list of tokens. |
| 875 */ | 883 */ |
| 876 Token _tokens; | 884 Token _tokens; |
| 877 | 885 |
| 878 /** | 886 /** |
| 879 * The last token that was scanned. | 887 * The last token that was scanned. |
| 880 */ | 888 */ |
| 881 Token _tail; | 889 Token _tail; |
| 882 | 890 |
| 883 /** | 891 /** |
| 884 * The first token in the list of comment tokens found since the last non-comm
ent token. | 892 * The first token in the list of comment tokens found since the last |
| 893 * non-comment token. |
| 885 */ | 894 */ |
| 886 Token _firstComment; | 895 Token _firstComment; |
| 887 | 896 |
| 888 /** | 897 /** |
| 889 * The last token in the list of comment tokens found since the last non-comme
nt token. | 898 * The last token in the list of comment tokens found since the last |
| 899 * non-comment token. |
| 890 */ | 900 */ |
| 891 Token _lastComment; | 901 Token _lastComment; |
| 892 | 902 |
| 893 /** | 903 /** |
| 894 * The index of the first character of the current token. | 904 * The index of the first character of the current token. |
| 895 */ | 905 */ |
| 896 int _tokenStart = 0; | 906 int _tokenStart = 0; |
| 897 | 907 |
| 898 /** | 908 /** |
| 899 * A list containing the offsets of the first character of each line in the so
urce code. | 909 * A list containing the offsets of the first character of each line in the |
| 910 * source code. |
| 900 */ | 911 */ |
| 901 List<int> _lineStarts = new List<int>(); | 912 List<int> _lineStarts = new List<int>(); |
| 902 | 913 |
| 903 /** | 914 /** |
| 904 * A list, treated something like a stack, of tokens representing the beginnin
g of a matched pair. | 915 * A list, treated something like a stack, of tokens representing the |
| 905 * It is used to pair the end tokens with the begin tokens. | 916 * beginning of a matched pair. It is used to pair the end tokens with the |
| 917 * begin tokens. |
| 906 */ | 918 */ |
| 907 List<BeginToken> _groupingStack = new List<BeginToken>(); | 919 List<BeginToken> _groupingStack = new List<BeginToken>(); |
| 908 | 920 |
| 909 /** | 921 /** |
| 910 * The index of the last item in the [groupingStack], or `-1` if the stack is
empty. | 922 * The index of the last item in the [_groupingStack], or `-1` if the stack is |
| 923 * empty. |
| 911 */ | 924 */ |
| 912 int _stackEnd = -1; | 925 int _stackEnd = -1; |
| 913 | 926 |
| 914 /** | 927 /** |
| 915 * A flag indicating whether any unmatched groups were found during the parse. | 928 * A flag indicating whether any unmatched groups were found during the parse. |
| 916 */ | 929 */ |
| 917 bool _hasUnmatchedGroups = false; | 930 bool _hasUnmatchedGroups = false; |
| 918 | 931 |
| 919 /** | 932 /** |
| 920 * Initialize a newly created scanner. | 933 * Initialize a newly created scanner to scan characters from the given |
| 921 * | 934 * [source]. The given character [_reader] will be used to read the characters |
| 922 * @param source the source being scanned | 935 * in the source. The given [_errorListener] will be informed of any errors |
| 923 * @param reader the character reader used to read the characters in the sourc
e | 936 * that are found. |
| 924 * @param errorListener the error listener that will be informed of any errors
that are found | |
| 925 */ | 937 */ |
| 926 Scanner(this.source, this._reader, this._errorListener) { | 938 Scanner(this.source, this._reader, this._errorListener) { |
| 927 _tokens = new Token(TokenType.EOF, -1); | 939 _tokens = new Token(TokenType.EOF, -1); |
| 928 _tokens.setNext(_tokens); | 940 _tokens.setNext(_tokens); |
| 929 _tail = _tokens; | 941 _tail = _tokens; |
| 930 _tokenStart = -1; | 942 _tokenStart = -1; |
| 931 _lineStarts.add(0); | 943 _lineStarts.add(0); |
| 932 } | 944 } |
| 933 | 945 |
| 934 /** | 946 /** |
| 935 * Return the first token in the token stream that was scanned. | 947 * Return the first token in the token stream that was scanned. |
| 936 * | |
| 937 * @return the first token in the token stream that was scanned | |
| 938 */ | 948 */ |
| 939 Token get firstToken => _tokens.next; | 949 Token get firstToken => _tokens.next; |
| 940 | 950 |
| 941 /** | 951 /** |
| 942 * Return `true` if any unmatched groups were found during the parse. | 952 * Return `true` if any unmatched groups were found during the parse. |
| 943 * | |
| 944 * @return `true` if any unmatched groups were found during the parse | |
| 945 */ | 953 */ |
| 946 bool get hasUnmatchedGroups => _hasUnmatchedGroups; | 954 bool get hasUnmatchedGroups => _hasUnmatchedGroups; |
| 947 | 955 |
| 948 /** | 956 /** |
| 949 * Return an array containing the offsets of the first character of each line
in the source code. | 957 * Return an array containing the offsets of the first character of each line |
| 950 * | 958 * in the source code. |
| 951 * @return an array containing the offsets of the first character of each line
in the source code | |
| 952 */ | 959 */ |
| 953 List<int> get lineStarts => _lineStarts; | 960 List<int> get lineStarts => _lineStarts; |
| 954 | 961 |
| 955 /** | 962 /** |
| 956 * Set whether documentation tokens should be scanned. | 963 * Set whether documentation tokens should be preserved. |
| 957 * | |
| 958 * @param preserveComments `true` if documentation tokens should be scanned | |
| 959 */ | 964 */ |
| 960 void set preserveComments(bool preserveComments) { | 965 void set preserveComments(bool preserveComments) { |
| 961 this._preserveComments = preserveComments; | 966 this._preserveComments = preserveComments; |
| 962 } | 967 } |
| 963 | 968 |
| 964 /** | 969 /** |
| 965 * Return the last token that was scanned. | 970 * Return the last token that was scanned. |
| 966 * | |
| 967 * @return the last token that was scanned | |
| 968 */ | 971 */ |
| 969 Token get tail => _tail; | 972 Token get tail => _tail; |
| 970 | 973 |
| 971 /** | 974 /** |
| 972 * Append the given token to the end of the token stream being scanned. This m
ethod is intended to | 975 * Append the given [token] to the end of the token stream being scanned. This |
| 973 * be used by subclasses that copy existing tokens and should not normally be
used because it will | 976 * method is intended to be used by subclasses that copy existing tokens and |
| 974 * fail to correctly associate any comments with the token being passed in. | 977 * should not normally be used because it will fail to correctly associate any |
| 975 * | 978 * comments with the token being passed in. |
| 976 * @param token the token to be appended | |
| 977 */ | 979 */ |
| 978 void appendToken(Token token) { | 980 void appendToken(Token token) { |
| 979 _tail = _tail.setNext(token); | 981 _tail = _tail.setNext(token); |
| 980 } | 982 } |
| 981 | 983 |
| 982 int bigSwitch(int next) { | 984 int bigSwitch(int next) { |
| 983 _beginToken(); | 985 _beginToken(); |
| 984 if (next == 0xD) { | 986 if (next == 0xD) { |
| 985 next = _reader.advance(); | 987 next = _reader.advance(); |
| 986 if (next == 0xA) { | 988 if (next == 0xA) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 } | 1127 } |
| 1126 | 1128 |
| 1127 /** | 1129 /** |
| 1128 * Record the fact that we are at the beginning of a new line in the source. | 1130 * Record the fact that we are at the beginning of a new line in the source. |
| 1129 */ | 1131 */ |
| 1130 void recordStartOfLine() { | 1132 void recordStartOfLine() { |
| 1131 _lineStarts.add(_reader.offset); | 1133 _lineStarts.add(_reader.offset); |
| 1132 } | 1134 } |
| 1133 | 1135 |
| 1134 /** | 1136 /** |
| 1135 * Record that the source begins on the given line and column at the current o
ffset as given by | 1137 * Record that the source begins on the given [line] and [column] at the |
| 1136 * the reader. The line starts for lines before the given line will not be cor
rect. | 1138 * current offset as given by the reader. The line starts for lines before the |
| 1139 * given line will not be correct. |
| 1137 * | 1140 * |
| 1138 * This method must be invoked at most one time and must be invoked before sca
nning begins. The | 1141 * This method must be invoked at most one time and must be invoked before |
| 1139 * values provided must be sensible. The results are undefined if these condit
ions are violated. | 1142 * scanning begins. The values provided must be sensible. The results are |
| 1143 * undefined if these conditions are violated. |
| 1140 * | 1144 * |
| 1141 * @param line the one-based index of the line containing the first character
of the source | 1145 * [line] the one-based index of the line containing the first character of |
| 1142 * @param column the one-based index of the column in which the first characte
r of the source | 1146 * the source |
| 1143 * occurs | 1147 * [column] the one-based index of the column in which the first character of |
| 1148 * the source occurs |
| 1144 */ | 1149 */ |
| 1145 void setSourceStart(int line, int column) { | 1150 void setSourceStart(int line, int column) { |
| 1146 int offset = _reader.offset; | 1151 int offset = _reader.offset; |
| 1147 if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) { | 1152 if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) { |
| 1148 return; | 1153 return; |
| 1149 } | 1154 } |
| 1150 for (int i = 2; i < line; i++) { | 1155 for (int i = 2; i < line; i++) { |
| 1151 _lineStarts.add(1); | 1156 _lineStarts.add(1); |
| 1152 } | 1157 } |
| 1153 _lineStarts.add(offset - column + 1); | 1158 _lineStarts.add(offset - column + 1); |
| 1154 } | 1159 } |
| 1155 | 1160 |
| 1156 /** | 1161 /** |
| 1157 * Scan the source code to produce a list of tokens representing the source. | 1162 * Scan the source code to produce a list of tokens representing the source, |
| 1158 * | 1163 * and return the first token in the list of tokens that were produced. |
| 1159 * @return the first token in the list of tokens that were produced | |
| 1160 */ | 1164 */ |
| 1161 Token tokenize() { | 1165 Token tokenize() { |
| 1162 InstrumentationBuilder instrumentation = | 1166 InstrumentationBuilder instrumentation = |
| 1163 Instrumentation.builder2("dart.engine.AbstractScanner.tokenize"); | 1167 Instrumentation.builder2("dart.engine.AbstractScanner.tokenize"); |
| 1164 int tokenCounter = 0; | 1168 int tokenCounter = 0; |
| 1165 try { | 1169 try { |
| 1166 int next = _reader.advance(); | 1170 int next = _reader.advance(); |
| 1167 while (next != -1) { | 1171 while (next != -1) { |
| 1168 tokenCounter++; | 1172 tokenCounter++; |
| 1169 next = bigSwitch(next); | 1173 next = bigSwitch(next); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1297 _firstComment = null; | 1301 _firstComment = null; |
| 1298 _lastComment = null; | 1302 _lastComment = null; |
| 1299 } | 1303 } |
| 1300 } | 1304 } |
| 1301 | 1305 |
| 1302 void _beginToken() { | 1306 void _beginToken() { |
| 1303 _tokenStart = _reader.offset; | 1307 _tokenStart = _reader.offset; |
| 1304 } | 1308 } |
| 1305 | 1309 |
| 1306 /** | 1310 /** |
| 1307 * Return the beginning token corresponding to a closing brace that was found
while scanning | 1311 * Return the beginning token corresponding to a closing brace that was found |
| 1308 * inside a string interpolation expression. Tokens that cannot be matched wit
h the closing brace | 1312 * while scanning inside a string interpolation expression. Tokens that cannot |
| 1309 * will be dropped from the stack. | 1313 * be matched with the closing brace will be dropped from the stack. |
| 1310 * | |
| 1311 * @return the token to be paired with the closing brace | |
| 1312 */ | 1314 */ |
| 1313 BeginToken _findTokenMatchingClosingBraceInInterpolationExpression() { | 1315 BeginToken _findTokenMatchingClosingBraceInInterpolationExpression() { |
| 1314 while (_stackEnd >= 0) { | 1316 while (_stackEnd >= 0) { |
| 1315 BeginToken begin = _groupingStack[_stackEnd]; | 1317 BeginToken begin = _groupingStack[_stackEnd]; |
| 1316 if (begin.type == TokenType.OPEN_CURLY_BRACKET || | 1318 if (begin.type == TokenType.OPEN_CURLY_BRACKET || |
| 1317 begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) { | 1319 begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) { |
| 1318 return begin; | 1320 return begin; |
| 1319 } | 1321 } |
| 1320 _hasUnmatchedGroups = true; | 1322 _hasUnmatchedGroups = true; |
| 1321 _groupingStack.removeAt(_stackEnd--); | 1323 _groupingStack.removeAt(_stackEnd--); |
| 1322 } | 1324 } |
| 1323 // | 1325 // |
| 1324 // We should never get to this point because we wouldn't be inside a string | 1326 // We should never get to this point because we wouldn't be inside a string |
| 1325 // interpolation expression unless we had previously found the start of the | 1327 // interpolation expression unless we had previously found the start of the |
| 1326 // expression. | 1328 // expression. |
| 1327 // | 1329 // |
| 1328 return null; | 1330 return null; |
| 1329 } | 1331 } |
| 1330 | 1332 |
| 1331 /** | 1333 /** |
| 1332 * Report an error at the current offset. | 1334 * Report an error at the current offset. |
| 1333 * | 1335 * |
| 1334 * @param errorCode the error code indicating the nature of the error | 1336 * [errorCode] the error code indicating the nature of the error |
| 1335 * @param arguments any arguments needed to complete the error message | 1337 * [arguments] any arguments needed to complete the error message |
| 1336 */ | 1338 */ |
| 1337 void _reportError(ScannerErrorCode errorCode, [List<Object> arguments]) { | 1339 void _reportError(ScannerErrorCode errorCode, [List<Object> arguments]) { |
| 1338 _errorListener.onError( | 1340 _errorListener.onError( |
| 1339 new AnalysisError.con2(source, _reader.offset, 1, errorCode, arguments))
; | 1341 new AnalysisError.con2(source, _reader.offset, 1, errorCode, arguments))
; |
| 1340 } | 1342 } |
| 1341 | 1343 |
| 1342 int _select(int choice, TokenType yesType, TokenType noType) { | 1344 int _select(int choice, TokenType yesType, TokenType noType) { |
| 1343 int next = _reader.advance(); | 1345 int next = _reader.advance(); |
| 1344 if (next == choice) { | 1346 if (next == choice) { |
| 1345 _appendTokenOfType(yesType); | 1347 _appendTokenOfType(yesType); |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 : super(name, message, correction); | 2024 : super(name, message, correction); |
| 2023 | 2025 |
| 2024 @override | 2026 @override |
| 2025 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; | 2027 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; |
| 2026 | 2028 |
| 2027 @override | 2029 @override |
| 2028 ErrorType get type => ErrorType.SYNTACTIC_ERROR; | 2030 ErrorType get type => ErrorType.SYNTACTIC_ERROR; |
| 2029 } | 2031 } |
| 2030 | 2032 |
| 2031 /** | 2033 /** |
| 2032 * Instances of the class `StringToken` represent a token whose value is indepen
dent of it's | 2034 * A `StringToken` is a token whose value is independent of it's type. |
| 2033 * type. | |
| 2034 */ | 2035 */ |
| 2035 class StringToken extends Token { | 2036 class StringToken extends Token { |
| 2036 /** | 2037 /** |
| 2037 * The lexeme represented by this token. | 2038 * The lexeme represented by this token. |
| 2038 */ | 2039 */ |
| 2039 String _value; | 2040 String _value; |
| 2040 | 2041 |
| 2041 /** | 2042 /** |
| 2042 * Initialize a newly created token to represent a token of the given type wit
h the given value. | 2043 * Initialize a newly created token to represent a token of the given [type] |
| 2043 * | 2044 * with the given [value] at the given [offset]. |
| 2044 * @param type the type of the token | |
| 2045 * @param value the lexeme represented by this token | |
| 2046 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 2047 */ | 2045 */ |
| 2048 StringToken(TokenType type, String value, int offset) : super(type, offset) { | 2046 StringToken(TokenType type, String value, int offset) : super(type, offset) { |
| 2049 this._value = StringUtilities.intern(value); | 2047 this._value = StringUtilities.intern(value); |
| 2050 } | 2048 } |
| 2051 | 2049 |
| 2052 @override | 2050 @override |
| 2053 String get lexeme => _value; | 2051 String get lexeme => _value; |
| 2054 | 2052 |
| 2055 @override | 2053 @override |
| 2056 Token copy() => new StringToken(type, _value, offset); | 2054 Token copy() => new StringToken(type, _value, offset); |
| 2057 | 2055 |
| 2058 @override | 2056 @override |
| 2059 String value() => _value; | 2057 String value() => _value; |
| 2060 } | 2058 } |
| 2061 | 2059 |
| 2062 /** | 2060 /** |
| 2063 * Instances of the class `TokenWithComment` represent a string token that is pr
eceded by | 2061 * A `StringTokenWithComment` is a string token that is preceded by comments. |
| 2064 * comments. | |
| 2065 */ | 2062 */ |
| 2066 class StringTokenWithComment extends StringToken { | 2063 class StringTokenWithComment extends StringToken { |
| 2067 /** | 2064 /** |
| 2068 * The first comment in the list of comments that precede this token. | 2065 * The first comment in the list of comments that precede this token. |
| 2069 */ | 2066 */ |
| 2070 final Token _precedingComment; | 2067 final Token _precedingComment; |
| 2071 | 2068 |
| 2072 /** | 2069 /** |
| 2073 * Initialize a newly created token to have the given type and offset and to b
e preceded by the | 2070 * Initialize a newly created token to have the given [type] at the given |
| 2074 * comments reachable from the given comment. | 2071 * [offset] and to be preceded by the comments reachable from the given |
| 2075 * | 2072 * [comment]. |
| 2076 * @param type the type of the token | |
| 2077 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 2078 * @param precedingComment the first comment in the list of comments that prec
ede this token | |
| 2079 */ | 2073 */ |
| 2080 StringTokenWithComment(TokenType type, String value, int offset, | 2074 StringTokenWithComment(TokenType type, String value, int offset, |
| 2081 this._precedingComment) | 2075 this._precedingComment) |
| 2082 : super(type, value, offset); | 2076 : super(type, value, offset); |
| 2083 | 2077 |
| 2084 @override | 2078 @override |
| 2085 Token get precedingComments => _precedingComment; | 2079 Token get precedingComments => _precedingComment; |
| 2086 | 2080 |
| 2087 @override | 2081 @override |
| 2088 void applyDelta(int delta) { | 2082 void applyDelta(int delta) { |
| 2089 super.applyDelta(delta); | 2083 super.applyDelta(delta); |
| 2090 Token token = _precedingComment; | 2084 Token token = _precedingComment; |
| 2091 while (token != null) { | 2085 while (token != null) { |
| 2092 token.applyDelta(delta); | 2086 token.applyDelta(delta); |
| 2093 token = token.next; | 2087 token = token.next; |
| 2094 } | 2088 } |
| 2095 } | 2089 } |
| 2096 | 2090 |
| 2097 @override | 2091 @override |
| 2098 Token copy() => | 2092 Token copy() => |
| 2099 new StringTokenWithComment( | 2093 new StringTokenWithComment( |
| 2100 type, | 2094 type, |
| 2101 lexeme, | 2095 lexeme, |
| 2102 offset, | 2096 offset, |
| 2103 copyComments(_precedingComment)); | 2097 copyComments(_precedingComment)); |
| 2104 } | 2098 } |
| 2105 | 2099 |
| 2106 /** | 2100 /** |
| 2107 * Instances of the class `SubSequenceReader` implement a [CharacterReader] that
reads | 2101 * A `SubSequenceReader` is a [CharacterReader] that reads characters from a |
| 2108 * characters from a character sequence, but adds a delta when reporting the cur
rent character | 2102 * character sequence, but adds a delta when reporting the current character |
| 2109 * offset so that the character sequence can be a subsequence from a larger sequ
ence. | 2103 * offset so that the character sequence can be a subsequence from a larger |
| 2104 * sequence. |
| 2110 */ | 2105 */ |
| 2111 class SubSequenceReader extends CharSequenceReader { | 2106 class SubSequenceReader extends CharSequenceReader { |
| 2112 /** | 2107 /** |
| 2113 * The offset from the beginning of the file to the beginning of the source be
ing scanned. | 2108 * The offset from the beginning of the file to the beginning of the source |
| 2109 * being scanned. |
| 2114 */ | 2110 */ |
| 2115 final int _offsetDelta; | 2111 final int _offsetDelta; |
| 2116 | 2112 |
| 2117 /** | 2113 /** |
| 2118 * Initialize a newly created reader to read the characters in the given seque
nce. | 2114 * Initialize a newly created reader to read the characters in the given |
| 2119 * | 2115 * [sequence]. The [_offsetDelta] is the offset from the beginning of the file |
| 2120 * @param sequence the sequence from which characters will be read | 2116 * to the beginning of the source being scanned |
| 2121 * @param offsetDelta the offset from the beginning of the file to the beginni
ng of the source | |
| 2122 * being scanned | |
| 2123 */ | 2117 */ |
| 2124 SubSequenceReader(String sequence, this._offsetDelta) : super(sequence); | 2118 SubSequenceReader(String sequence, this._offsetDelta) : super(sequence); |
| 2125 | 2119 |
| 2126 @override | 2120 @override |
| 2127 int get offset => _offsetDelta + super.offset; | 2121 int get offset => _offsetDelta + super.offset; |
| 2128 | 2122 |
| 2129 @override | 2123 @override |
| 2130 void set offset(int offset) { | 2124 void set offset(int offset) { |
| 2131 super.offset = offset - _offsetDelta; | 2125 super.offset = offset - _offsetDelta; |
| 2132 } | 2126 } |
| 2133 | 2127 |
| 2134 @override | 2128 @override |
| 2135 String getString(int start, int endDelta) => | 2129 String getString(int start, int endDelta) => |
| 2136 super.getString(start - _offsetDelta, endDelta); | 2130 super.getString(start - _offsetDelta, endDelta); |
| 2137 } | 2131 } |
| 2138 | 2132 |
| 2139 /** | 2133 /** |
| 2140 * Synthetic `StringToken` represent a token whose value is independent of it's
type. | 2134 * A `SyntheticStringToken` is a token whose value is independent of it's type. |
| 2141 */ | 2135 */ |
| 2142 class SyntheticStringToken extends StringToken { | 2136 class SyntheticStringToken extends StringToken { |
| 2143 /** | 2137 /** |
| 2144 * Initialize a newly created token to represent a token of the given type wit
h the given value. | 2138 * Initialize a newly created token to represent a token of the given [type] |
| 2145 * | 2139 * with the given [value] at the given [offset]. |
| 2146 * @param type the type of the token | |
| 2147 * @param value the lexeme represented by this token | |
| 2148 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 2149 */ | 2140 */ |
| 2150 SyntheticStringToken(TokenType type, String value, int offset) | 2141 SyntheticStringToken(TokenType type, String value, int offset) |
| 2151 : super(type, value, offset); | 2142 : super(type, value, offset); |
| 2152 | 2143 |
| 2153 @override | 2144 @override |
| 2154 bool get isSynthetic => true; | 2145 bool get isSynthetic => true; |
| 2155 } | 2146 } |
| 2156 | 2147 |
| 2157 /** | 2148 /** |
| 2158 * Instances of the class `Token` represent a token that was scanned from the in
put. Each | 2149 * Instances of the class `Token` represent a token that was scanned from the |
| 2159 * token knows which token follows it, acting as the head of a linked list of to
kens. | 2150 * input. Each token knows which tokens preceed and follow it, acting as a link |
| 2151 * in a doubly linked list of tokens. |
| 2160 */ | 2152 */ |
| 2161 class Token { | 2153 class Token { |
| 2162 /** | 2154 /** |
| 2163 * The type of the token. | 2155 * The type of the token. |
| 2164 */ | 2156 */ |
| 2165 final TokenType type; | 2157 final TokenType type; |
| 2166 | 2158 |
| 2167 /** | 2159 /** |
| 2168 * The offset from the beginning of the file to the first character in the tok
en. | 2160 * The offset from the beginning of the file to the first character in the |
| 2161 * token. |
| 2169 */ | 2162 */ |
| 2170 int offset = 0; | 2163 int offset = 0; |
| 2171 | 2164 |
| 2172 /** | 2165 /** |
| 2173 * The previous token in the token stream. | 2166 * The previous token in the token stream. |
| 2174 */ | 2167 */ |
| 2175 Token previous; | 2168 Token previous; |
| 2176 | 2169 |
| 2177 /** | 2170 /** |
| 2178 * The next token in the token stream. | 2171 * The next token in the token stream. |
| 2179 */ | 2172 */ |
| 2180 Token _next; | 2173 Token _next; |
| 2181 | 2174 |
| 2182 /** | 2175 /** |
| 2183 * Initialize a newly created token to have the given type and offset. | 2176 * Initialize a newly created token to have the given [type] and [offset]. |
| 2184 * | |
| 2185 * @param type the type of the token | |
| 2186 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 2187 */ | 2177 */ |
| 2188 Token(this.type, int offset) { | 2178 Token(this.type, int offset) { |
| 2189 this.offset = offset; | 2179 this.offset = offset; |
| 2190 } | 2180 } |
| 2191 | 2181 |
| 2192 | |
| 2193 /** | 2182 /** |
| 2194 * Return the offset from the beginning of the file to the character after las
t character of the | 2183 * Return the offset from the beginning of the file to the character after the |
| 2195 * token. | 2184 * last character of the token. |
| 2196 * | |
| 2197 * @return the offset from the beginning of the file to the first character af
ter last character | |
| 2198 * of the token | |
| 2199 */ | 2185 */ |
| 2200 int get end => offset + length; | 2186 int get end => offset + length; |
| 2201 | 2187 |
| 2202 /** | 2188 /** |
| 2203 * Return `true` if this token represents an operator. | 2189 * Return `true` if this token represents an operator. |
| 2204 * | |
| 2205 * @return `true` if this token represents an operator | |
| 2206 */ | 2190 */ |
| 2207 bool get isOperator => type.isOperator; | 2191 bool get isOperator => type.isOperator; |
| 2208 | 2192 |
| 2209 /** | 2193 /** |
| 2210 * Return `true` if this token is a synthetic token. A synthetic token is a to
ken that was | 2194 * Return `true` if this token is a synthetic token. A synthetic token is a |
| 2211 * introduced by the parser in order to recover from an error in the code. | 2195 * token that was introduced by the parser in order to recover from an error |
| 2212 * | 2196 * in the code. |
| 2213 * @return `true` if this token is a synthetic token | |
| 2214 */ | 2197 */ |
| 2215 bool get isSynthetic => length == 0; | 2198 bool get isSynthetic => length == 0; |
| 2216 | 2199 |
| 2217 /** | 2200 /** |
| 2218 * Return `true` if this token represents an operator that can be defined by u
sers. | 2201 * Return `true` if this token represents an operator that can be defined by |
| 2219 * | 2202 * users. |
| 2220 * @return `true` if this token represents an operator that can be defined by
users | |
| 2221 */ | 2203 */ |
| 2222 bool get isUserDefinableOperator => type.isUserDefinableOperator; | 2204 bool get isUserDefinableOperator => type.isUserDefinableOperator; |
| 2223 | 2205 |
| 2224 /** | 2206 /** |
| 2225 * Return the number of characters in the node's source range. | 2207 * Return the number of characters in the node's source range. |
| 2226 * | |
| 2227 * @return the number of characters in the node's source range | |
| 2228 */ | 2208 */ |
| 2229 int get length => lexeme.length; | 2209 int get length => lexeme.length; |
| 2230 | 2210 |
| 2231 /** | 2211 /** |
| 2232 * Return the lexeme that represents this token. | 2212 * Return the lexeme that represents this token. |
| 2233 * | |
| 2234 * @return the lexeme that represents this token | |
| 2235 */ | 2213 */ |
| 2236 String get lexeme => type.lexeme; | 2214 String get lexeme => type.lexeme; |
| 2237 | 2215 |
| 2238 /** | 2216 /** |
| 2239 * Return the next token in the token stream. | 2217 * Return the next token in the token stream. |
| 2240 * | |
| 2241 * @return the next token in the token stream | |
| 2242 */ | 2218 */ |
| 2243 Token get next => _next; | 2219 Token get next => _next; |
| 2244 | 2220 |
| 2245 /** | 2221 /** |
| 2246 * Return the first comment in the list of comments that precede this token, o
r `null` if | 2222 * Return the first comment in the list of comments that precede this token, |
| 2247 * there are no comments preceding this token. Additional comments can be reac
hed by following the | 2223 * or `null` if there are no comments preceding this token. Additional |
| 2248 * token stream using [getNext] until `null` is returned. | 2224 * comments can be reached by following the token stream using [next] until |
| 2225 * `null` is returned. |
| 2249 * | 2226 * |
| 2250 * @return the first comment in the list of comments that precede this token | 2227 * For example, if the original contents were "/* one */ /* two */ id", then |
| 2228 * the first precceding comment token will have a lexeme of "/* one */" and |
| 2229 * the next comment token will have a lexeme of "/* two */". |
| 2251 */ | 2230 */ |
| 2252 Token get precedingComments => null; | 2231 Token get precedingComments => null; |
| 2253 | 2232 |
| 2254 /** | 2233 /** |
| 2255 * Apply (add) the given delta to this token's offset. | 2234 * Apply (add) the given [delta] to this token's offset. |
| 2256 * | |
| 2257 * @param delta the amount by which the offset is to be adjusted | |
| 2258 */ | 2235 */ |
| 2259 void applyDelta(int delta) { | 2236 void applyDelta(int delta) { |
| 2260 offset += delta; | 2237 offset += delta; |
| 2261 } | 2238 } |
| 2262 | 2239 |
| 2263 /** | 2240 /** |
| 2264 * Return a newly created token that is a copy of this token but that is not a
part of any token | 2241 * Return a newly created token that is a copy of this token but that is not a |
| 2265 * stream. | 2242 * part of any token stream. |
| 2266 * | |
| 2267 * @return a newly created token that is a copy of this token | |
| 2268 */ | 2243 */ |
| 2269 Token copy() => new Token(type, offset); | 2244 Token copy() => new Token(type, offset); |
| 2270 | 2245 |
| 2271 /** | 2246 /** |
| 2272 * Copy a linked list of comment tokens identical to the given comment tokens. | 2247 * Copy a linked list of comment tokens identical to the given comment tokens. |
| 2273 * | |
| 2274 * @param token the first token in the list, or `null` if there are no tokens
to be copied | |
| 2275 * @return the tokens that were created | |
| 2276 */ | 2248 */ |
| 2277 Token copyComments(Token token) { | 2249 Token copyComments(Token token) { |
| 2278 if (token == null) { | 2250 if (token == null) { |
| 2279 return null; | 2251 return null; |
| 2280 } | 2252 } |
| 2281 Token head = token.copy(); | 2253 Token head = token.copy(); |
| 2282 Token tail = head; | 2254 Token tail = head; |
| 2283 token = token.next; | 2255 token = token.next; |
| 2284 while (token != null) { | 2256 while (token != null) { |
| 2285 tail = tail.setNext(token.copy()); | 2257 tail = tail.setNext(token.copy()); |
| 2286 token = token.next; | 2258 token = token.next; |
| 2287 } | 2259 } |
| 2288 return head; | 2260 return head; |
| 2289 } | 2261 } |
| 2290 | 2262 |
| 2291 /** | 2263 /** |
| 2292 * Return `true` if this token has any one of the given types. | 2264 * Return `true` if this token has any one of the given [types]. |
| 2293 * | |
| 2294 * @param types the types of token that are being tested for | |
| 2295 * @return `true` if this token has any of the given types | |
| 2296 */ | 2265 */ |
| 2297 bool matchesAny(List<TokenType> types) { | 2266 bool matchesAny(List<TokenType> types) { |
| 2298 for (TokenType type in types) { | 2267 for (TokenType type in types) { |
| 2299 if (this.type == type) { | 2268 if (this.type == type) { |
| 2300 return true; | 2269 return true; |
| 2301 } | 2270 } |
| 2302 } | 2271 } |
| 2303 return false; | 2272 return false; |
| 2304 } | 2273 } |
| 2305 | 2274 |
| 2306 /** | 2275 /** |
| 2307 * Set the next token in the token stream to the given token. This has the sid
e-effect of setting | 2276 * Set the next token in the token stream to the given [token]. This has the |
| 2308 * this token to be the previous token for the given token. | 2277 * side-effect of setting this token to be the previous token for the given |
| 2309 * | 2278 * token. Return the token that was passed in. |
| 2310 * @param token the next token in the token stream | |
| 2311 * @return the token that was passed in | |
| 2312 */ | 2279 */ |
| 2313 Token setNext(Token token) { | 2280 Token setNext(Token token) { |
| 2314 _next = token; | 2281 _next = token; |
| 2315 token.previous = this; | 2282 token.previous = this; |
| 2316 return token; | 2283 return token; |
| 2317 } | 2284 } |
| 2318 | 2285 |
| 2319 /** | 2286 /** |
| 2320 * Set the next token in the token stream to the given token without changing
which token is the | 2287 * Set the next token in the token stream to the given token without changing |
| 2321 * previous token for the given token. | 2288 * which token is the previous token for the given token. Return the token |
| 2322 * | 2289 * that was passed in. |
| 2323 * @param token the next token in the token stream | |
| 2324 * @return the token that was passed in | |
| 2325 */ | 2290 */ |
| 2326 Token setNextWithoutSettingPrevious(Token token) { | 2291 Token setNextWithoutSettingPrevious(Token token) { |
| 2327 _next = token; | 2292 _next = token; |
| 2328 return token; | 2293 return token; |
| 2329 } | 2294 } |
| 2330 | 2295 |
| 2331 @override | 2296 @override |
| 2332 String toString() => lexeme; | 2297 String toString() => lexeme; |
| 2333 | 2298 |
| 2334 /** | 2299 /** |
| 2335 * Return the value of this token. For keyword tokens, this is the keyword ass
ociated with the | 2300 * Return the value of this token. For keyword tokens, this is the keyword |
| 2336 * token, for other tokens it is the lexeme associated with the token. | 2301 * associated with the token, for other tokens it is the lexeme associated |
| 2337 * | 2302 * with the token. |
| 2338 * @return the value of this token | |
| 2339 */ | 2303 */ |
| 2340 Object value() => type.lexeme; | 2304 Object value() => type.lexeme; |
| 2341 | 2305 |
| 2342 /** | 2306 /** |
| 2343 * Compare the given [tokens] to find the token that appears first in the | 2307 * Compare the given [tokens] to find the token that appears first in the |
| 2344 * source being parsed. That is, return the left-most of all of the tokens. | 2308 * source being parsed. That is, return the left-most of all of the tokens. |
| 2345 * The list must be non-`null`, but the elements of the list are allowed to be | 2309 * The list must be non-`null`, but the elements of the list are allowed to be |
| 2346 * `null`. Return the token with the smallest offset, or `null` if there are | 2310 * `null`. Return the token with the smallest offset, or `null` if the list is |
| 2347 * no tokens or if all of the tokens are `null`. | 2311 * empty or if all of the elements of the list are `null`. |
| 2348 */ | 2312 */ |
| 2349 static Token lexicallyFirst(List<Token> tokens) { | 2313 static Token lexicallyFirst(List<Token> tokens) { |
| 2350 Token first = null; | 2314 Token first = null; |
| 2351 int offset = -1; | 2315 int offset = -1; |
| 2352 for (Token token in tokens) { | 2316 for (Token token in tokens) { |
| 2353 if (token != null && (offset < 0 || token.offset < offset)) { | 2317 if (token != null && (offset < 0 || token.offset < offset)) { |
| 2354 first = token; | 2318 first = token; |
| 2355 offset = token.offset; | 2319 offset = token.offset; |
| 2356 } | 2320 } |
| 2357 } | 2321 } |
| 2358 return first; | 2322 return first; |
| 2359 } | 2323 } |
| 2360 } | 2324 } |
| 2361 | 2325 |
| 2362 /** | 2326 /** |
| 2363 * The enumeration `TokenClass` represents classes (or groups) of tokens with a
similar use. | 2327 * The enumeration `TokenClass` represents classes (or groups) of tokens with a |
| 2328 * similar use. |
| 2364 */ | 2329 */ |
| 2365 class TokenClass extends Enum<TokenClass> { | 2330 class TokenClass { |
| 2366 /** | 2331 /** |
| 2367 * A value used to indicate that the token type is not part of any specific cl
ass of token. | 2332 * A value used to indicate that the token type is not part of any specific |
| 2368 */ | 2333 * class of token. |
| 2369 static const TokenClass NO_CLASS = const TokenClass.con1('NO_CLASS', 0); | 2334 */ |
| 2335 static const TokenClass NO_CLASS = const TokenClass('NO_CLASS'); |
| 2370 | 2336 |
| 2371 /** | 2337 /** |
| 2372 * A value used to indicate that the token type is an additive operator. | 2338 * A value used to indicate that the token type is an additive operator. |
| 2373 */ | 2339 */ |
| 2374 static const TokenClass ADDITIVE_OPERATOR = | 2340 static const TokenClass ADDITIVE_OPERATOR = |
| 2375 const TokenClass.con2('ADDITIVE_OPERATOR', 1, 12); | 2341 const TokenClass('ADDITIVE_OPERATOR', 12); |
| 2376 | 2342 |
| 2377 /** | 2343 /** |
| 2378 * A value used to indicate that the token type is an assignment operator. | 2344 * A value used to indicate that the token type is an assignment operator. |
| 2379 */ | 2345 */ |
| 2380 static const TokenClass ASSIGNMENT_OPERATOR = | 2346 static const TokenClass ASSIGNMENT_OPERATOR = |
| 2381 const TokenClass.con2('ASSIGNMENT_OPERATOR', 2, 1); | 2347 const TokenClass('ASSIGNMENT_OPERATOR', 1); |
| 2382 | 2348 |
| 2383 /** | 2349 /** |
| 2384 * A value used to indicate that the token type is a bitwise-and operator. | 2350 * A value used to indicate that the token type is a bitwise-and operator. |
| 2385 */ | 2351 */ |
| 2386 static const TokenClass BITWISE_AND_OPERATOR = | 2352 static const TokenClass BITWISE_AND_OPERATOR = |
| 2387 const TokenClass.con2('BITWISE_AND_OPERATOR', 3, 10); | 2353 const TokenClass('BITWISE_AND_OPERATOR', 10); |
| 2388 | 2354 |
| 2389 /** | 2355 /** |
| 2390 * A value used to indicate that the token type is a bitwise-or operator. | 2356 * A value used to indicate that the token type is a bitwise-or operator. |
| 2391 */ | 2357 */ |
| 2392 static const TokenClass BITWISE_OR_OPERATOR = | 2358 static const TokenClass BITWISE_OR_OPERATOR = |
| 2393 const TokenClass.con2('BITWISE_OR_OPERATOR', 4, 8); | 2359 const TokenClass('BITWISE_OR_OPERATOR', 8); |
| 2394 | 2360 |
| 2395 /** | 2361 /** |
| 2396 * A value used to indicate that the token type is a bitwise-xor operator. | 2362 * A value used to indicate that the token type is a bitwise-xor operator. |
| 2397 */ | 2363 */ |
| 2398 static const TokenClass BITWISE_XOR_OPERATOR = | 2364 static const TokenClass BITWISE_XOR_OPERATOR = |
| 2399 const TokenClass.con2('BITWISE_XOR_OPERATOR', 5, 9); | 2365 const TokenClass('BITWISE_XOR_OPERATOR', 9); |
| 2400 | 2366 |
| 2401 /** | 2367 /** |
| 2402 * A value used to indicate that the token type is a cascade operator. | 2368 * A value used to indicate that the token type is a cascade operator. |
| 2403 */ | 2369 */ |
| 2404 static const TokenClass CASCADE_OPERATOR = | 2370 static const TokenClass CASCADE_OPERATOR = |
| 2405 const TokenClass.con2('CASCADE_OPERATOR', 6, 2); | 2371 const TokenClass('CASCADE_OPERATOR', 2); |
| 2406 | 2372 |
| 2407 /** | 2373 /** |
| 2408 * A value used to indicate that the token type is a conditional operator. | 2374 * A value used to indicate that the token type is a conditional operator. |
| 2409 */ | 2375 */ |
| 2410 static const TokenClass CONDITIONAL_OPERATOR = | 2376 static const TokenClass CONDITIONAL_OPERATOR = |
| 2411 const TokenClass.con2('CONDITIONAL_OPERATOR', 7, 3); | 2377 const TokenClass('CONDITIONAL_OPERATOR', 3); |
| 2412 | 2378 |
| 2413 /** | 2379 /** |
| 2414 * A value used to indicate that the token type is an equality operator. | 2380 * A value used to indicate that the token type is an equality operator. |
| 2415 */ | 2381 */ |
| 2416 static const TokenClass EQUALITY_OPERATOR = | 2382 static const TokenClass EQUALITY_OPERATOR = |
| 2417 const TokenClass.con2('EQUALITY_OPERATOR', 8, 6); | 2383 const TokenClass('EQUALITY_OPERATOR', 6); |
| 2418 | 2384 |
| 2419 /** | 2385 /** |
| 2420 * A value used to indicate that the token type is a logical-and operator. | 2386 * A value used to indicate that the token type is a logical-and operator. |
| 2421 */ | 2387 */ |
| 2422 static const TokenClass LOGICAL_AND_OPERATOR = | 2388 static const TokenClass LOGICAL_AND_OPERATOR = |
| 2423 const TokenClass.con2('LOGICAL_AND_OPERATOR', 9, 5); | 2389 const TokenClass('LOGICAL_AND_OPERATOR', 5); |
| 2424 | 2390 |
| 2425 /** | 2391 /** |
| 2426 * A value used to indicate that the token type is a logical-or operator. | 2392 * A value used to indicate that the token type is a logical-or operator. |
| 2427 */ | 2393 */ |
| 2428 static const TokenClass LOGICAL_OR_OPERATOR = | 2394 static const TokenClass LOGICAL_OR_OPERATOR = |
| 2429 const TokenClass.con2('LOGICAL_OR_OPERATOR', 10, 4); | 2395 const TokenClass('LOGICAL_OR_OPERATOR', 4); |
| 2430 | 2396 |
| 2431 /** | 2397 /** |
| 2432 * A value used to indicate that the token type is a multiplicative operator. | 2398 * A value used to indicate that the token type is a multiplicative operator. |
| 2433 */ | 2399 */ |
| 2434 static const TokenClass MULTIPLICATIVE_OPERATOR = | 2400 static const TokenClass MULTIPLICATIVE_OPERATOR = |
| 2435 const TokenClass.con2('MULTIPLICATIVE_OPERATOR', 11, 13); | 2401 const TokenClass('MULTIPLICATIVE_OPERATOR', 13); |
| 2436 | 2402 |
| 2437 /** | 2403 /** |
| 2438 * A value used to indicate that the token type is a relational operator. | 2404 * A value used to indicate that the token type is a relational operator. |
| 2439 */ | 2405 */ |
| 2440 static const TokenClass RELATIONAL_OPERATOR = | 2406 static const TokenClass RELATIONAL_OPERATOR = |
| 2441 const TokenClass.con2('RELATIONAL_OPERATOR', 12, 7); | 2407 const TokenClass('RELATIONAL_OPERATOR', 7); |
| 2442 | 2408 |
| 2443 /** | 2409 /** |
| 2444 * A value used to indicate that the token type is a shift operator. | 2410 * A value used to indicate that the token type is a shift operator. |
| 2445 */ | 2411 */ |
| 2446 static const TokenClass SHIFT_OPERATOR = | 2412 static const TokenClass SHIFT_OPERATOR = |
| 2447 const TokenClass.con2('SHIFT_OPERATOR', 13, 11); | 2413 const TokenClass('SHIFT_OPERATOR', 11); |
| 2448 | 2414 |
| 2449 /** | 2415 /** |
| 2450 * A value used to indicate that the token type is a unary operator. | 2416 * A value used to indicate that the token type is a unary operator. |
| 2451 */ | 2417 */ |
| 2452 static const TokenClass UNARY_POSTFIX_OPERATOR = | 2418 static const TokenClass UNARY_POSTFIX_OPERATOR = |
| 2453 const TokenClass.con2('UNARY_POSTFIX_OPERATOR', 14, 15); | 2419 const TokenClass('UNARY_POSTFIX_OPERATOR', 15); |
| 2454 | 2420 |
| 2455 /** | 2421 /** |
| 2456 * A value used to indicate that the token type is a unary operator. | 2422 * A value used to indicate that the token type is a unary operator. |
| 2457 */ | 2423 */ |
| 2458 static const TokenClass UNARY_PREFIX_OPERATOR = | 2424 static const TokenClass UNARY_PREFIX_OPERATOR = |
| 2459 const TokenClass.con2('UNARY_PREFIX_OPERATOR', 15, 14); | 2425 const TokenClass('UNARY_PREFIX_OPERATOR', 14); |
| 2460 | 2426 |
| 2461 static const List<TokenClass> values = const [ | 2427 /** |
| 2462 NO_CLASS, | 2428 * The name of the token class. |
| 2463 ADDITIVE_OPERATOR, | 2429 */ |
| 2464 ASSIGNMENT_OPERATOR, | 2430 final String name; |
| 2465 BITWISE_AND_OPERATOR, | 2431 |
| 2466 BITWISE_OR_OPERATOR, | 2432 /** |
| 2467 BITWISE_XOR_OPERATOR, | 2433 * The precedence of tokens of this class, or `0` if the such tokens do not |
| 2468 CASCADE_OPERATOR, | 2434 * represent an operator. |
| 2469 CONDITIONAL_OPERATOR, | |
| 2470 EQUALITY_OPERATOR, | |
| 2471 LOGICAL_AND_OPERATOR, | |
| 2472 LOGICAL_OR_OPERATOR, | |
| 2473 MULTIPLICATIVE_OPERATOR, | |
| 2474 RELATIONAL_OPERATOR, | |
| 2475 SHIFT_OPERATOR, | |
| 2476 UNARY_POSTFIX_OPERATOR, | |
| 2477 UNARY_PREFIX_OPERATOR]; | |
| 2478 | |
| 2479 /** | |
| 2480 * The precedence of tokens of this class, or `0` if the such tokens do not re
present an | |
| 2481 * operator. | |
| 2482 */ | 2435 */ |
| 2483 final int precedence; | 2436 final int precedence; |
| 2484 | 2437 |
| 2485 const TokenClass.con1(String name, int ordinal) : this.con2(name, ordinal, 0); | 2438 const TokenClass(this.name, [this.precedence = 0]); |
| 2486 | |
| 2487 const TokenClass.con2(String name, int ordinal, this.precedence) | |
| 2488 : super(name, ordinal); | |
| 2489 } | 2439 } |
| 2490 | 2440 |
| 2491 /** | 2441 /** |
| 2492 * The enumeration `TokenType` defines the types of tokens that can be returned
by the | 2442 * The enumeration `TokenType` defines the types of tokens that can be returned |
| 2493 * scanner. | 2443 * by the scanner. |
| 2494 */ | 2444 */ |
| 2495 class TokenType extends Enum<TokenType> { | 2445 class TokenType { |
| 2496 /** | 2446 /** |
| 2497 * The type of the token that marks the end of the input. | 2447 * The type of the token that marks the end of the input. |
| 2498 */ | 2448 */ |
| 2499 static const TokenType EOF = | 2449 static const TokenType EOF = const TokenType_EOF('EOF'); |
| 2500 const TokenType_EOF('EOF', 0, TokenClass.NO_CLASS, ""); | 2450 |
| 2501 | 2451 static const TokenType DOUBLE = const TokenType('DOUBLE'); |
| 2502 static const TokenType DOUBLE = const TokenType.con1('DOUBLE', 1); | 2452 |
| 2503 | 2453 static const TokenType HEXADECIMAL = const TokenType('HEXADECIMAL'); |
| 2504 static const TokenType HEXADECIMAL = const TokenType.con1('HEXADECIMAL', 2); | 2454 |
| 2505 | 2455 static const TokenType IDENTIFIER = const TokenType('IDENTIFIER'); |
| 2506 static const TokenType IDENTIFIER = const TokenType.con1('IDENTIFIER', 3); | 2456 |
| 2507 | 2457 static const TokenType INT = const TokenType('INT'); |
| 2508 static const TokenType INT = const TokenType.con1('INT', 4); | 2458 |
| 2509 | 2459 static const TokenType KEYWORD = const TokenType('KEYWORD'); |
| 2510 static const TokenType KEYWORD = const TokenType.con1('KEYWORD', 5); | |
| 2511 | 2460 |
| 2512 static const TokenType MULTI_LINE_COMMENT = | 2461 static const TokenType MULTI_LINE_COMMENT = |
| 2513 const TokenType.con1('MULTI_LINE_COMMENT', 6); | 2462 const TokenType('MULTI_LINE_COMMENT'); |
| 2514 | 2463 |
| 2515 static const TokenType SCRIPT_TAG = const TokenType.con1('SCRIPT_TAG', 7); | 2464 static const TokenType SCRIPT_TAG = const TokenType('SCRIPT_TAG'); |
| 2516 | 2465 |
| 2517 static const TokenType SINGLE_LINE_COMMENT = | 2466 static const TokenType SINGLE_LINE_COMMENT = |
| 2518 const TokenType.con1('SINGLE_LINE_COMMENT', 8); | 2467 const TokenType('SINGLE_LINE_COMMENT'); |
| 2519 | 2468 |
| 2520 static const TokenType STRING = const TokenType.con1('STRING', 9); | 2469 static const TokenType STRING = const TokenType('STRING'); |
| 2521 | 2470 |
| 2522 static const TokenType AMPERSAND = | 2471 static const TokenType AMPERSAND = |
| 2523 const TokenType.con2('AMPERSAND', 10, TokenClass.BITWISE_AND_OPERATOR, "&"
); | 2472 const TokenType('AMPERSAND', TokenClass.BITWISE_AND_OPERATOR, "&"); |
| 2524 | 2473 |
| 2525 static const TokenType AMPERSAND_AMPERSAND = const TokenType.con2( | 2474 static const TokenType AMPERSAND_AMPERSAND = |
| 2526 'AMPERSAND_AMPERSAND', | 2475 const TokenType('AMPERSAND_AMPERSAND', TokenClass.LOGICAL_AND_OPERATOR, "&
&"); |
| 2527 11, | |
| 2528 TokenClass.LOGICAL_AND_OPERATOR, | |
| 2529 "&&"); | |
| 2530 | 2476 |
| 2531 static const TokenType AMPERSAND_EQ = | 2477 static const TokenType AMPERSAND_EQ = |
| 2532 const TokenType.con2('AMPERSAND_EQ', 12, TokenClass.ASSIGNMENT_OPERATOR, "
&="); | 2478 const TokenType('AMPERSAND_EQ', TokenClass.ASSIGNMENT_OPERATOR, "&="); |
| 2533 | 2479 |
| 2534 static const TokenType AT = | 2480 static const TokenType AT = const TokenType('AT', TokenClass.NO_CLASS, "@"); |
| 2535 const TokenType.con2('AT', 13, TokenClass.NO_CLASS, "@"); | |
| 2536 | 2481 |
| 2537 static const TokenType BANG = | 2482 static const TokenType BANG = |
| 2538 const TokenType.con2('BANG', 14, TokenClass.UNARY_PREFIX_OPERATOR, "!"); | 2483 const TokenType('BANG', TokenClass.UNARY_PREFIX_OPERATOR, "!"); |
| 2539 | 2484 |
| 2540 static const TokenType BANG_EQ = | 2485 static const TokenType BANG_EQ = |
| 2541 const TokenType.con2('BANG_EQ', 15, TokenClass.EQUALITY_OPERATOR, "!="); | 2486 const TokenType('BANG_EQ', TokenClass.EQUALITY_OPERATOR, "!="); |
| 2542 | 2487 |
| 2543 static const TokenType BAR = | 2488 static const TokenType BAR = |
| 2544 const TokenType.con2('BAR', 16, TokenClass.BITWISE_OR_OPERATOR, "|"); | 2489 const TokenType('BAR', TokenClass.BITWISE_OR_OPERATOR, "|"); |
| 2545 | 2490 |
| 2546 static const TokenType BAR_BAR = | 2491 static const TokenType BAR_BAR = |
| 2547 const TokenType.con2('BAR_BAR', 17, TokenClass.LOGICAL_OR_OPERATOR, "||"); | 2492 const TokenType('BAR_BAR', TokenClass.LOGICAL_OR_OPERATOR, "||"); |
| 2548 | 2493 |
| 2549 static const TokenType BAR_EQ = | 2494 static const TokenType BAR_EQ = |
| 2550 const TokenType.con2('BAR_EQ', 18, TokenClass.ASSIGNMENT_OPERATOR, "|="); | 2495 const TokenType('BAR_EQ', TokenClass.ASSIGNMENT_OPERATOR, "|="); |
| 2551 | 2496 |
| 2552 static const TokenType COLON = | 2497 static const TokenType COLON = |
| 2553 const TokenType.con2('COLON', 19, TokenClass.NO_CLASS, ":"); | 2498 const TokenType('COLON', TokenClass.NO_CLASS, ":"); |
| 2554 | 2499 |
| 2555 static const TokenType COMMA = | 2500 static const TokenType COMMA = |
| 2556 const TokenType.con2('COMMA', 20, TokenClass.NO_CLASS, ","); | 2501 const TokenType('COMMA', TokenClass.NO_CLASS, ","); |
| 2557 | 2502 |
| 2558 static const TokenType CARET = | 2503 static const TokenType CARET = |
| 2559 const TokenType.con2('CARET', 21, TokenClass.BITWISE_XOR_OPERATOR, "^"); | 2504 const TokenType('CARET', TokenClass.BITWISE_XOR_OPERATOR, "^"); |
| 2560 | 2505 |
| 2561 static const TokenType CARET_EQ = | 2506 static const TokenType CARET_EQ = |
| 2562 const TokenType.con2('CARET_EQ', 22, TokenClass.ASSIGNMENT_OPERATOR, "^=")
; | 2507 const TokenType('CARET_EQ', TokenClass.ASSIGNMENT_OPERATOR, "^="); |
| 2563 | 2508 |
| 2564 static const TokenType CLOSE_CURLY_BRACKET = | 2509 static const TokenType CLOSE_CURLY_BRACKET = |
| 2565 const TokenType.con2('CLOSE_CURLY_BRACKET', 23, TokenClass.NO_CLASS, "}"); | 2510 const TokenType('CLOSE_CURLY_BRACKET', TokenClass.NO_CLASS, "}"); |
| 2566 | 2511 |
| 2567 static const TokenType CLOSE_PAREN = | 2512 static const TokenType CLOSE_PAREN = |
| 2568 const TokenType.con2('CLOSE_PAREN', 24, TokenClass.NO_CLASS, ")"); | 2513 const TokenType('CLOSE_PAREN', TokenClass.NO_CLASS, ")"); |
| 2569 | 2514 |
| 2570 static const TokenType CLOSE_SQUARE_BRACKET = | 2515 static const TokenType CLOSE_SQUARE_BRACKET = |
| 2571 const TokenType.con2('CLOSE_SQUARE_BRACKET', 25, TokenClass.NO_CLASS, "]")
; | 2516 const TokenType('CLOSE_SQUARE_BRACKET', TokenClass.NO_CLASS, "]"); |
| 2572 | 2517 |
| 2573 static const TokenType EQ = | 2518 static const TokenType EQ = |
| 2574 const TokenType.con2('EQ', 26, TokenClass.ASSIGNMENT_OPERATOR, "="); | 2519 const TokenType('EQ', TokenClass.ASSIGNMENT_OPERATOR, "="); |
| 2575 | 2520 |
| 2576 static const TokenType EQ_EQ = | 2521 static const TokenType EQ_EQ = |
| 2577 const TokenType.con2('EQ_EQ', 27, TokenClass.EQUALITY_OPERATOR, "=="); | 2522 const TokenType('EQ_EQ', TokenClass.EQUALITY_OPERATOR, "=="); |
| 2578 | 2523 |
| 2579 static const TokenType FUNCTION = | 2524 static const TokenType FUNCTION = |
| 2580 const TokenType.con2('FUNCTION', 28, TokenClass.NO_CLASS, "=>"); | 2525 const TokenType('FUNCTION', TokenClass.NO_CLASS, "=>"); |
| 2581 | 2526 |
| 2582 static const TokenType GT = | 2527 static const TokenType GT = |
| 2583 const TokenType.con2('GT', 29, TokenClass.RELATIONAL_OPERATOR, ">"); | 2528 const TokenType('GT', TokenClass.RELATIONAL_OPERATOR, ">"); |
| 2584 | 2529 |
| 2585 static const TokenType GT_EQ = | 2530 static const TokenType GT_EQ = |
| 2586 const TokenType.con2('GT_EQ', 30, TokenClass.RELATIONAL_OPERATOR, ">="); | 2531 const TokenType('GT_EQ', TokenClass.RELATIONAL_OPERATOR, ">="); |
| 2587 | 2532 |
| 2588 static const TokenType GT_GT = | 2533 static const TokenType GT_GT = |
| 2589 const TokenType.con2('GT_GT', 31, TokenClass.SHIFT_OPERATOR, ">>"); | 2534 const TokenType('GT_GT', TokenClass.SHIFT_OPERATOR, ">>"); |
| 2590 | 2535 |
| 2591 static const TokenType GT_GT_EQ = | 2536 static const TokenType GT_GT_EQ = |
| 2592 const TokenType.con2('GT_GT_EQ', 32, TokenClass.ASSIGNMENT_OPERATOR, ">>="
); | 2537 const TokenType('GT_GT_EQ', TokenClass.ASSIGNMENT_OPERATOR, ">>="); |
| 2593 | 2538 |
| 2594 static const TokenType HASH = | 2539 static const TokenType HASH = |
| 2595 const TokenType.con2('HASH', 33, TokenClass.NO_CLASS, "#"); | 2540 const TokenType('HASH', TokenClass.NO_CLASS, "#"); |
| 2596 | 2541 |
| 2597 static const TokenType INDEX = | 2542 static const TokenType INDEX = |
| 2598 const TokenType.con2('INDEX', 34, TokenClass.UNARY_POSTFIX_OPERATOR, "[]")
; | 2543 const TokenType('INDEX', TokenClass.UNARY_POSTFIX_OPERATOR, "[]"); |
| 2599 | 2544 |
| 2600 static const TokenType INDEX_EQ = | 2545 static const TokenType INDEX_EQ = |
| 2601 const TokenType.con2('INDEX_EQ', 35, TokenClass.UNARY_POSTFIX_OPERATOR, "[
]="); | 2546 const TokenType('INDEX_EQ', TokenClass.UNARY_POSTFIX_OPERATOR, "[]="); |
| 2602 | 2547 |
| 2603 static const TokenType IS = | 2548 static const TokenType IS = |
| 2604 const TokenType.con2('IS', 36, TokenClass.RELATIONAL_OPERATOR, "is"); | 2549 const TokenType('IS', TokenClass.RELATIONAL_OPERATOR, "is"); |
| 2605 | 2550 |
| 2606 static const TokenType LT = | 2551 static const TokenType LT = |
| 2607 const TokenType.con2('LT', 37, TokenClass.RELATIONAL_OPERATOR, "<"); | 2552 const TokenType('LT', TokenClass.RELATIONAL_OPERATOR, "<"); |
| 2608 | 2553 |
| 2609 static const TokenType LT_EQ = | 2554 static const TokenType LT_EQ = |
| 2610 const TokenType.con2('LT_EQ', 38, TokenClass.RELATIONAL_OPERATOR, "<="); | 2555 const TokenType('LT_EQ', TokenClass.RELATIONAL_OPERATOR, "<="); |
| 2611 | 2556 |
| 2612 static const TokenType LT_LT = | 2557 static const TokenType LT_LT = |
| 2613 const TokenType.con2('LT_LT', 39, TokenClass.SHIFT_OPERATOR, "<<"); | 2558 const TokenType('LT_LT', TokenClass.SHIFT_OPERATOR, "<<"); |
| 2614 | 2559 |
| 2615 static const TokenType LT_LT_EQ = | 2560 static const TokenType LT_LT_EQ = |
| 2616 const TokenType.con2('LT_LT_EQ', 40, TokenClass.ASSIGNMENT_OPERATOR, "<<="
); | 2561 const TokenType('LT_LT_EQ', TokenClass.ASSIGNMENT_OPERATOR, "<<="); |
| 2617 | 2562 |
| 2618 static const TokenType MINUS = | 2563 static const TokenType MINUS = |
| 2619 const TokenType.con2('MINUS', 41, TokenClass.ADDITIVE_OPERATOR, "-"); | 2564 const TokenType('MINUS', TokenClass.ADDITIVE_OPERATOR, "-"); |
| 2620 | 2565 |
| 2621 static const TokenType MINUS_EQ = | 2566 static const TokenType MINUS_EQ = |
| 2622 const TokenType.con2('MINUS_EQ', 42, TokenClass.ASSIGNMENT_OPERATOR, "-=")
; | 2567 const TokenType('MINUS_EQ', TokenClass.ASSIGNMENT_OPERATOR, "-="); |
| 2623 | 2568 |
| 2624 static const TokenType MINUS_MINUS = const TokenType.con2( | 2569 static const TokenType MINUS_MINUS = |
| 2625 'MINUS_MINUS', | 2570 const TokenType('MINUS_MINUS', TokenClass.UNARY_PREFIX_OPERATOR, "--"); |
| 2626 43, | |
| 2627 TokenClass.UNARY_PREFIX_OPERATOR, | |
| 2628 "--"); | |
| 2629 | 2571 |
| 2630 static const TokenType OPEN_CURLY_BRACKET = | 2572 static const TokenType OPEN_CURLY_BRACKET = |
| 2631 const TokenType.con2('OPEN_CURLY_BRACKET', 44, TokenClass.NO_CLASS, "{"); | 2573 const TokenType('OPEN_CURLY_BRACKET', TokenClass.NO_CLASS, "{"); |
| 2632 | 2574 |
| 2633 static const TokenType OPEN_PAREN = | 2575 static const TokenType OPEN_PAREN = |
| 2634 const TokenType.con2('OPEN_PAREN', 45, TokenClass.UNARY_POSTFIX_OPERATOR,
"("); | 2576 const TokenType('OPEN_PAREN', TokenClass.UNARY_POSTFIX_OPERATOR, "("); |
| 2635 | 2577 |
| 2636 static const TokenType OPEN_SQUARE_BRACKET = const TokenType.con2( | 2578 static const TokenType OPEN_SQUARE_BRACKET = |
| 2637 'OPEN_SQUARE_BRACKET', | 2579 const TokenType('OPEN_SQUARE_BRACKET', TokenClass.UNARY_POSTFIX_OPERATOR,
"["); |
| 2638 46, | |
| 2639 TokenClass.UNARY_POSTFIX_OPERATOR, | |
| 2640 "["); | |
| 2641 | 2580 |
| 2642 static const TokenType PERCENT = | 2581 static const TokenType PERCENT = |
| 2643 const TokenType.con2('PERCENT', 47, TokenClass.MULTIPLICATIVE_OPERATOR, "%
"); | 2582 const TokenType('PERCENT', TokenClass.MULTIPLICATIVE_OPERATOR, "%"); |
| 2644 | 2583 |
| 2645 static const TokenType PERCENT_EQ = | 2584 static const TokenType PERCENT_EQ = |
| 2646 const TokenType.con2('PERCENT_EQ', 48, TokenClass.ASSIGNMENT_OPERATOR, "%=
"); | 2585 const TokenType('PERCENT_EQ', TokenClass.ASSIGNMENT_OPERATOR, "%="); |
| 2647 | 2586 |
| 2648 static const TokenType PERIOD = | 2587 static const TokenType PERIOD = |
| 2649 const TokenType.con2('PERIOD', 49, TokenClass.UNARY_POSTFIX_OPERATOR, ".")
; | 2588 const TokenType('PERIOD', TokenClass.UNARY_POSTFIX_OPERATOR, "."); |
| 2650 | 2589 |
| 2651 static const TokenType PERIOD_PERIOD = | 2590 static const TokenType PERIOD_PERIOD = |
| 2652 const TokenType.con2('PERIOD_PERIOD', 50, TokenClass.CASCADE_OPERATOR, "..
"); | 2591 const TokenType('PERIOD_PERIOD', TokenClass.CASCADE_OPERATOR, ".."); |
| 2653 | 2592 |
| 2654 static const TokenType PLUS = | 2593 static const TokenType PLUS = |
| 2655 const TokenType.con2('PLUS', 51, TokenClass.ADDITIVE_OPERATOR, "+"); | 2594 const TokenType('PLUS', TokenClass.ADDITIVE_OPERATOR, "+"); |
| 2656 | 2595 |
| 2657 static const TokenType PLUS_EQ = | 2596 static const TokenType PLUS_EQ = |
| 2658 const TokenType.con2('PLUS_EQ', 52, TokenClass.ASSIGNMENT_OPERATOR, "+="); | 2597 const TokenType('PLUS_EQ', TokenClass.ASSIGNMENT_OPERATOR, "+="); |
| 2659 | 2598 |
| 2660 static const TokenType PLUS_PLUS = | 2599 static const TokenType PLUS_PLUS = |
| 2661 const TokenType.con2('PLUS_PLUS', 53, TokenClass.UNARY_PREFIX_OPERATOR, "+
+"); | 2600 const TokenType('PLUS_PLUS', TokenClass.UNARY_PREFIX_OPERATOR, "++"); |
| 2662 | 2601 |
| 2663 static const TokenType QUESTION = | 2602 static const TokenType QUESTION = |
| 2664 const TokenType.con2('QUESTION', 54, TokenClass.CONDITIONAL_OPERATOR, "?")
; | 2603 const TokenType('QUESTION', TokenClass.CONDITIONAL_OPERATOR, "?"); |
| 2665 | 2604 |
| 2666 static const TokenType SEMICOLON = | 2605 static const TokenType SEMICOLON = |
| 2667 const TokenType.con2('SEMICOLON', 55, TokenClass.NO_CLASS, ";"); | 2606 const TokenType('SEMICOLON', TokenClass.NO_CLASS, ";"); |
| 2668 | 2607 |
| 2669 static const TokenType SLASH = | 2608 static const TokenType SLASH = |
| 2670 const TokenType.con2('SLASH', 56, TokenClass.MULTIPLICATIVE_OPERATOR, "/")
; | 2609 const TokenType('SLASH', TokenClass.MULTIPLICATIVE_OPERATOR, "/"); |
| 2671 | 2610 |
| 2672 static const TokenType SLASH_EQ = | 2611 static const TokenType SLASH_EQ = |
| 2673 const TokenType.con2('SLASH_EQ', 57, TokenClass.ASSIGNMENT_OPERATOR, "/=")
; | 2612 const TokenType('SLASH_EQ', TokenClass.ASSIGNMENT_OPERATOR, "/="); |
| 2674 | 2613 |
| 2675 static const TokenType STAR = | 2614 static const TokenType STAR = |
| 2676 const TokenType.con2('STAR', 58, TokenClass.MULTIPLICATIVE_OPERATOR, "*"); | 2615 const TokenType('STAR', TokenClass.MULTIPLICATIVE_OPERATOR, "*"); |
| 2677 | 2616 |
| 2678 static const TokenType STAR_EQ = | 2617 static const TokenType STAR_EQ = |
| 2679 const TokenType.con2('STAR_EQ', 59, TokenClass.ASSIGNMENT_OPERATOR, "*="); | 2618 const TokenType('STAR_EQ', TokenClass.ASSIGNMENT_OPERATOR, "*="); |
| 2680 | 2619 |
| 2681 static const TokenType STRING_INTERPOLATION_EXPRESSION = const TokenType.con2( | 2620 static const TokenType STRING_INTERPOLATION_EXPRESSION = |
| 2682 'STRING_INTERPOLATION_EXPRESSION', | 2621 const TokenType('STRING_INTERPOLATION_EXPRESSION', TokenClass.NO_CLASS, "\
${"); |
| 2683 60, | 2622 |
| 2684 TokenClass.NO_CLASS, | 2623 static const TokenType STRING_INTERPOLATION_IDENTIFIER = |
| 2685 "\${"); | 2624 const TokenType('STRING_INTERPOLATION_IDENTIFIER', TokenClass.NO_CLASS, "\
$"); |
| 2686 | |
| 2687 static const TokenType STRING_INTERPOLATION_IDENTIFIER = const TokenType.con2( | |
| 2688 'STRING_INTERPOLATION_IDENTIFIER', | |
| 2689 61, | |
| 2690 TokenClass.NO_CLASS, | |
| 2691 "\$"); | |
| 2692 | 2625 |
| 2693 static const TokenType TILDE = | 2626 static const TokenType TILDE = |
| 2694 const TokenType.con2('TILDE', 62, TokenClass.UNARY_PREFIX_OPERATOR, "~"); | 2627 const TokenType('TILDE', TokenClass.UNARY_PREFIX_OPERATOR, "~"); |
| 2695 | 2628 |
| 2696 static const TokenType TILDE_SLASH = const TokenType.con2( | 2629 static const TokenType TILDE_SLASH = |
| 2697 'TILDE_SLASH', | 2630 const TokenType('TILDE_SLASH', TokenClass.MULTIPLICATIVE_OPERATOR, "~/"); |
| 2698 63, | 2631 |
| 2699 TokenClass.MULTIPLICATIVE_OPERATOR, | 2632 static const TokenType TILDE_SLASH_EQ = |
| 2700 "~/"); | 2633 const TokenType('TILDE_SLASH_EQ', TokenClass.ASSIGNMENT_OPERATOR, "~/="); |
| 2701 | |
| 2702 static const TokenType TILDE_SLASH_EQ = const TokenType.con2( | |
| 2703 'TILDE_SLASH_EQ', | |
| 2704 64, | |
| 2705 TokenClass.ASSIGNMENT_OPERATOR, | |
| 2706 "~/="); | |
| 2707 | 2634 |
| 2708 static const TokenType BACKPING = | 2635 static const TokenType BACKPING = |
| 2709 const TokenType.con2('BACKPING', 65, TokenClass.NO_CLASS, "`"); | 2636 const TokenType('BACKPING', TokenClass.NO_CLASS, "`"); |
| 2710 | 2637 |
| 2711 static const TokenType BACKSLASH = | 2638 static const TokenType BACKSLASH = |
| 2712 const TokenType.con2('BACKSLASH', 66, TokenClass.NO_CLASS, "\\"); | 2639 const TokenType('BACKSLASH', TokenClass.NO_CLASS, "\\"); |
| 2713 | 2640 |
| 2714 static const TokenType PERIOD_PERIOD_PERIOD = | 2641 static const TokenType PERIOD_PERIOD_PERIOD = |
| 2715 const TokenType.con2('PERIOD_PERIOD_PERIOD', 67, TokenClass.NO_CLASS, "...
"); | 2642 const TokenType('PERIOD_PERIOD_PERIOD', TokenClass.NO_CLASS, "..."); |
| 2716 | |
| 2717 static const List<TokenType> values = const [ | |
| 2718 EOF, | |
| 2719 DOUBLE, | |
| 2720 HEXADECIMAL, | |
| 2721 IDENTIFIER, | |
| 2722 INT, | |
| 2723 KEYWORD, | |
| 2724 MULTI_LINE_COMMENT, | |
| 2725 SCRIPT_TAG, | |
| 2726 SINGLE_LINE_COMMENT, | |
| 2727 STRING, | |
| 2728 AMPERSAND, | |
| 2729 AMPERSAND_AMPERSAND, | |
| 2730 AMPERSAND_EQ, | |
| 2731 AT, | |
| 2732 BANG, | |
| 2733 BANG_EQ, | |
| 2734 BAR, | |
| 2735 BAR_BAR, | |
| 2736 BAR_EQ, | |
| 2737 COLON, | |
| 2738 COMMA, | |
| 2739 CARET, | |
| 2740 CARET_EQ, | |
| 2741 CLOSE_CURLY_BRACKET, | |
| 2742 CLOSE_PAREN, | |
| 2743 CLOSE_SQUARE_BRACKET, | |
| 2744 EQ, | |
| 2745 EQ_EQ, | |
| 2746 FUNCTION, | |
| 2747 GT, | |
| 2748 GT_EQ, | |
| 2749 GT_GT, | |
| 2750 GT_GT_EQ, | |
| 2751 HASH, | |
| 2752 INDEX, | |
| 2753 INDEX_EQ, | |
| 2754 IS, | |
| 2755 LT, | |
| 2756 LT_EQ, | |
| 2757 LT_LT, | |
| 2758 LT_LT_EQ, | |
| 2759 MINUS, | |
| 2760 MINUS_EQ, | |
| 2761 MINUS_MINUS, | |
| 2762 OPEN_CURLY_BRACKET, | |
| 2763 OPEN_PAREN, | |
| 2764 OPEN_SQUARE_BRACKET, | |
| 2765 PERCENT, | |
| 2766 PERCENT_EQ, | |
| 2767 PERIOD, | |
| 2768 PERIOD_PERIOD, | |
| 2769 PLUS, | |
| 2770 PLUS_EQ, | |
| 2771 PLUS_PLUS, | |
| 2772 QUESTION, | |
| 2773 SEMICOLON, | |
| 2774 SLASH, | |
| 2775 SLASH_EQ, | |
| 2776 STAR, | |
| 2777 STAR_EQ, | |
| 2778 STRING_INTERPOLATION_EXPRESSION, | |
| 2779 STRING_INTERPOLATION_IDENTIFIER, | |
| 2780 TILDE, | |
| 2781 TILDE_SLASH, | |
| 2782 TILDE_SLASH_EQ, | |
| 2783 BACKPING, | |
| 2784 BACKSLASH, | |
| 2785 PERIOD_PERIOD_PERIOD]; | |
| 2786 | 2643 |
| 2787 /** | 2644 /** |
| 2788 * The class of the token. | 2645 * The class of the token. |
| 2789 */ | 2646 */ |
| 2790 final TokenClass _tokenClass; | 2647 final TokenClass _tokenClass; |
| 2791 | 2648 |
| 2792 /** | 2649 /** |
| 2793 * The lexeme that defines this type of token, or `null` if there is more than
one possible | 2650 * The name of the token type. |
| 2794 * lexeme for this type of token. | 2651 */ |
| 2652 final String name; |
| 2653 |
| 2654 /** |
| 2655 * The lexeme that defines this type of token, or `null` if there is more than |
| 2656 * one possible lexeme for this type of token. |
| 2795 */ | 2657 */ |
| 2796 final String lexeme; | 2658 final String lexeme; |
| 2797 | 2659 |
| 2798 const TokenType.con1(String name, int ordinal) | 2660 const TokenType(this.name, [this._tokenClass = TokenClass.NO_CLASS, |
| 2799 : this.con2(name, ordinal, TokenClass.NO_CLASS, null); | 2661 this.lexeme = null]); |
| 2800 | |
| 2801 const TokenType.con2(String name, int ordinal, this._tokenClass, this.lexeme) | |
| 2802 : super(name, ordinal); | |
| 2803 | 2662 |
| 2804 /** | 2663 /** |
| 2805 * Return `true` if this type of token represents an additive operator. | 2664 * Return `true` if this type of token represents an additive operator. |
| 2806 * | |
| 2807 * @return `true` if this type of token represents an additive operator | |
| 2808 */ | 2665 */ |
| 2809 bool get isAdditiveOperator => _tokenClass == TokenClass.ADDITIVE_OPERATOR; | 2666 bool get isAdditiveOperator => _tokenClass == TokenClass.ADDITIVE_OPERATOR; |
| 2810 | 2667 |
| 2811 /** | 2668 /** |
| 2812 * Return `true` if this type of token represents an assignment operator. | 2669 * Return `true` if this type of token represents an assignment operator. |
| 2813 * | |
| 2814 * @return `true` if this type of token represents an assignment operator | |
| 2815 */ | 2670 */ |
| 2816 bool get isAssignmentOperator => | 2671 bool get isAssignmentOperator => |
| 2817 _tokenClass == TokenClass.ASSIGNMENT_OPERATOR; | 2672 _tokenClass == TokenClass.ASSIGNMENT_OPERATOR; |
| 2818 | 2673 |
| 2819 /** | 2674 /** |
| 2820 * Return `true` if this type of token represents an associative operator. An
associative | 2675 * Return `true` if this type of token represents an associative operator. An |
| 2821 * operator is an operator for which the following equality is true: | 2676 * associative operator is an operator for which the following equality is |
| 2822 * `(a * b) * c == a * (b * c)`. In other words, if the result of applying the
operator to | 2677 * true: `(a * b) * c == a * (b * c)`. In other words, if the result of |
| 2823 * multiple operands does not depend on the order in which those applications
occur. | 2678 * applying the operator to multiple operands does not depend on the order in |
| 2679 * which those applications occur. |
| 2824 * | 2680 * |
| 2825 * Note: This method considers the logical-and and logical-or operators to be
associative, even | 2681 * Note: This method considers the logical-and and logical-or operators to be |
| 2826 * though the order in which the application of those operators can have an ef
fect because | 2682 * associative, even though the order in which the application of those |
| 2827 * evaluation of the right-hand operand is conditional. | 2683 * operators can have an effect because evaluation of the right-hand operand |
| 2828 * | 2684 * is conditional. |
| 2829 * @return `true` if this type of token represents an associative operator | |
| 2830 */ | 2685 */ |
| 2831 bool get isAssociativeOperator => | 2686 bool get isAssociativeOperator => |
| 2832 this == AMPERSAND || | 2687 this == AMPERSAND || |
| 2833 this == AMPERSAND_AMPERSAND || | 2688 this == AMPERSAND_AMPERSAND || |
| 2834 this == BAR || | 2689 this == BAR || |
| 2835 this == BAR_BAR || | 2690 this == BAR_BAR || |
| 2836 this == CARET || | 2691 this == CARET || |
| 2837 this == PLUS || | 2692 this == PLUS || |
| 2838 this == STAR; | 2693 this == STAR; |
| 2839 | 2694 |
| 2840 /** | 2695 /** |
| 2841 * Return `true` if this type of token represents an equality operator. | 2696 * Return `true` if this type of token represents an equality operator. |
| 2842 * | |
| 2843 * @return `true` if this type of token represents an equality operator | |
| 2844 */ | 2697 */ |
| 2845 bool get isEqualityOperator => _tokenClass == TokenClass.EQUALITY_OPERATOR; | 2698 bool get isEqualityOperator => _tokenClass == TokenClass.EQUALITY_OPERATOR; |
| 2846 | 2699 |
| 2847 /** | 2700 /** |
| 2848 * Return `true` if this type of token represents an increment operator. | 2701 * Return `true` if this type of token represents an increment operator. |
| 2849 * | |
| 2850 * @return `true` if this type of token represents an increment operator | |
| 2851 */ | 2702 */ |
| 2852 bool get isIncrementOperator => | 2703 bool get isIncrementOperator => |
| 2853 identical(lexeme, "++") || identical(lexeme, "--"); | 2704 identical(lexeme, "++") || identical(lexeme, "--"); |
| 2854 | 2705 |
| 2855 /** | 2706 /** |
| 2856 * Return `true` if this type of token represents a multiplicative operator. | 2707 * Return `true` if this type of token represents a multiplicative operator. |
| 2857 * | |
| 2858 * @return `true` if this type of token represents a multiplicative operator | |
| 2859 */ | 2708 */ |
| 2860 bool get isMultiplicativeOperator => | 2709 bool get isMultiplicativeOperator => |
| 2861 _tokenClass == TokenClass.MULTIPLICATIVE_OPERATOR; | 2710 _tokenClass == TokenClass.MULTIPLICATIVE_OPERATOR; |
| 2862 | 2711 |
| 2863 /** | 2712 /** |
| 2864 * Return `true` if this token type represents an operator. | 2713 * Return `true` if this token type represents an operator. |
| 2865 * | |
| 2866 * @return `true` if this token type represents an operator | |
| 2867 */ | 2714 */ |
| 2868 bool get isOperator => | 2715 bool get isOperator => |
| 2869 _tokenClass != TokenClass.NO_CLASS && | 2716 _tokenClass != TokenClass.NO_CLASS && |
| 2870 this != OPEN_PAREN && | 2717 this != OPEN_PAREN && |
| 2871 this != OPEN_SQUARE_BRACKET && | 2718 this != OPEN_SQUARE_BRACKET && |
| 2872 this != PERIOD; | 2719 this != PERIOD; |
| 2873 | 2720 |
| 2874 /** | 2721 /** |
| 2875 * Return `true` if this type of token represents a relational operator. | 2722 * Return `true` if this type of token represents a relational operator. |
| 2876 * | |
| 2877 * @return `true` if this type of token represents a relational operator | |
| 2878 */ | 2723 */ |
| 2879 bool get isRelationalOperator => | 2724 bool get isRelationalOperator => |
| 2880 _tokenClass == TokenClass.RELATIONAL_OPERATOR; | 2725 _tokenClass == TokenClass.RELATIONAL_OPERATOR; |
| 2881 | 2726 |
| 2882 /** | 2727 /** |
| 2883 * Return `true` if this type of token represents a shift operator. | 2728 * Return `true` if this type of token represents a shift operator. |
| 2884 * | |
| 2885 * @return `true` if this type of token represents a shift operator | |
| 2886 */ | 2729 */ |
| 2887 bool get isShiftOperator => _tokenClass == TokenClass.SHIFT_OPERATOR; | 2730 bool get isShiftOperator => _tokenClass == TokenClass.SHIFT_OPERATOR; |
| 2888 | 2731 |
| 2889 /** | 2732 /** |
| 2890 * Return `true` if this type of token represents a unary postfix operator. | 2733 * Return `true` if this type of token represents a unary postfix operator. |
| 2891 * | |
| 2892 * @return `true` if this type of token represents a unary postfix operator | |
| 2893 */ | 2734 */ |
| 2894 bool get isUnaryPostfixOperator => | 2735 bool get isUnaryPostfixOperator => |
| 2895 _tokenClass == TokenClass.UNARY_POSTFIX_OPERATOR; | 2736 _tokenClass == TokenClass.UNARY_POSTFIX_OPERATOR; |
| 2896 | 2737 |
| 2897 /** | 2738 /** |
| 2898 * Return `true` if this type of token represents a unary prefix operator. | 2739 * Return `true` if this type of token represents a unary prefix operator. |
| 2899 * | |
| 2900 * @return `true` if this type of token represents a unary prefix operator | |
| 2901 */ | 2740 */ |
| 2902 bool get isUnaryPrefixOperator => | 2741 bool get isUnaryPrefixOperator => |
| 2903 _tokenClass == TokenClass.UNARY_PREFIX_OPERATOR; | 2742 _tokenClass == TokenClass.UNARY_PREFIX_OPERATOR; |
| 2904 | 2743 |
| 2905 /** | 2744 /** |
| 2906 * Return `true` if this token type represents an operator that can be defined
by users. | 2745 * Return `true` if this token type represents an operator that can be defined |
| 2907 * | 2746 * by users. |
| 2908 * @return `true` if this token type represents an operator that can be define
d by users | |
| 2909 */ | 2747 */ |
| 2910 bool get isUserDefinableOperator => | 2748 bool get isUserDefinableOperator => |
| 2911 identical(lexeme, "==") || | 2749 identical(lexeme, "==") || |
| 2912 identical(lexeme, "~") || | 2750 identical(lexeme, "~") || |
| 2913 identical(lexeme, "[]") || | 2751 identical(lexeme, "[]") || |
| 2914 identical(lexeme, "[]=") || | 2752 identical(lexeme, "[]=") || |
| 2915 identical(lexeme, "*") || | 2753 identical(lexeme, "*") || |
| 2916 identical(lexeme, "/") || | 2754 identical(lexeme, "/") || |
| 2917 identical(lexeme, "%") || | 2755 identical(lexeme, "%") || |
| 2918 identical(lexeme, "~/") || | 2756 identical(lexeme, "~/") || |
| 2919 identical(lexeme, "+") || | 2757 identical(lexeme, "+") || |
| 2920 identical(lexeme, "-") || | 2758 identical(lexeme, "-") || |
| 2921 identical(lexeme, "<<") || | 2759 identical(lexeme, "<<") || |
| 2922 identical(lexeme, ">>") || | 2760 identical(lexeme, ">>") || |
| 2923 identical(lexeme, ">=") || | 2761 identical(lexeme, ">=") || |
| 2924 identical(lexeme, ">") || | 2762 identical(lexeme, ">") || |
| 2925 identical(lexeme, "<=") || | 2763 identical(lexeme, "<=") || |
| 2926 identical(lexeme, "<") || | 2764 identical(lexeme, "<") || |
| 2927 identical(lexeme, "&") || | 2765 identical(lexeme, "&") || |
| 2928 identical(lexeme, "^") || | 2766 identical(lexeme, "^") || |
| 2929 identical(lexeme, "|"); | 2767 identical(lexeme, "|"); |
| 2930 | 2768 |
| 2931 /** | 2769 /** |
| 2932 * Return the precedence of the token, or `0` if the token does not represent
an operator. | 2770 * Return the precedence of the token, or `0` if the token does not represent |
| 2933 * | 2771 * an operator. |
| 2934 * @return the precedence of the token | |
| 2935 */ | 2772 */ |
| 2936 int get precedence => _tokenClass.precedence; | 2773 int get precedence => _tokenClass.precedence; |
| 2937 } | 2774 } |
| 2938 | 2775 |
| 2939 class TokenType_EOF extends TokenType { | 2776 class TokenType_EOF extends TokenType { |
| 2940 const TokenType_EOF(String name, int ordinal, TokenClass arg0, String arg1) | 2777 const TokenType_EOF(String name) : super(name, TokenClass.NO_CLASS, ""); |
| 2941 : super.con2(name, ordinal, arg0, arg1); | |
| 2942 | 2778 |
| 2943 @override | 2779 @override |
| 2944 String toString() => "-eof-"; | 2780 String toString() => "-eof-"; |
| 2945 } | 2781 } |
| 2946 | 2782 |
| 2947 /** | 2783 /** |
| 2948 * Instances of the class `TokenWithComment` represent a normal token that is pr
eceded by | 2784 * A `TokenWithComment` is a normal token that is preceded by comments. |
| 2949 * comments. | |
| 2950 */ | 2785 */ |
| 2951 class TokenWithComment extends Token { | 2786 class TokenWithComment extends Token { |
| 2952 /** | 2787 /** |
| 2953 * The first comment in the list of comments that precede this token. | 2788 * The first comment in the list of comments that precede this token. |
| 2954 */ | 2789 */ |
| 2955 final Token _precedingComment; | 2790 final Token _precedingComment; |
| 2956 | 2791 |
| 2957 /** | 2792 /** |
| 2958 * Initialize a newly created token to have the given type and offset and to b
e preceded by the | 2793 * Initialize a newly created token to have the given [type] at the given |
| 2959 * comments reachable from the given comment. | 2794 * [offset] and to be preceded by the comments reachable from the given |
| 2960 * | 2795 * [comment]. |
| 2961 * @param type the type of the token | |
| 2962 * @param offset the offset from the beginning of the file to the first charac
ter in the token | |
| 2963 * @param precedingComment the first comment in the list of comments that prec
ede this token | |
| 2964 */ | 2796 */ |
| 2965 TokenWithComment(TokenType type, int offset, this._precedingComment) | 2797 TokenWithComment(TokenType type, int offset, this._precedingComment) |
| 2966 : super(type, offset); | 2798 : super(type, offset); |
| 2967 | 2799 |
| 2968 @override | 2800 @override |
| 2969 Token get precedingComments => _precedingComment; | 2801 Token get precedingComments => _precedingComment; |
| 2970 | 2802 |
| 2971 @override | 2803 @override |
| 2972 Token copy() => new TokenWithComment(type, offset, _precedingComment); | 2804 Token copy() => new TokenWithComment(type, offset, _precedingComment); |
| 2973 } | 2805 } |
| OLD | NEW |