Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 /** | 5 library front_end.src.scanner.token; |
|
Brian Wilkerson
2016/11/08 20:53:24
Not sure why we dropped the doc comment.
Paul Berry
2016/11/08 21:47:06
Re-added.
| |
| 6 * Defines the tokens that are produced by the scanner, used by the parser, and | |
| 7 * referenced from the [AST structure](ast.dart). | |
| 8 */ | |
| 9 library analyzer.dart.ast.token; | |
| 10 | 6 |
| 11 import 'dart:collection'; | 7 import 'dart:collection'; |
| 12 | 8 |
| 13 import 'package:analyzer/dart/ast/syntactic_entity.dart'; | 9 import 'package:front_end/src/scanner/string_utilities.dart'; |
| 14 import 'package:analyzer/src/dart/ast/token.dart' show SimpleToken, TokenClass; | 10 import 'package:front_end/src/scanner/syntactic_entity.dart'; |
| 11 | |
| 12 /** | |
| 13 * The opening half of a grouping pair of tokens. This is used for curly | |
| 14 * brackets ('{'), parentheses ('('), and square brackets ('['). | |
| 15 */ | |
| 16 class BeginToken extends SimpleToken { | |
|
Brian Wilkerson
2016/11/08 20:53:24
As discussed off-line, I liked the previous separa
Paul Berry
2016/11/08 21:47:06
Acknowledged.
| |
| 17 /** | |
| 18 * The token that corresponds to this token. | |
| 19 */ | |
| 20 Token endToken; | |
| 21 | |
| 22 /** | |
| 23 * Initialize a newly created token to have the given [type] at the given | |
| 24 * [offset]. | |
| 25 */ | |
| 26 BeginToken(TokenType type, int offset) : super(type, offset) { | |
| 27 assert(type == TokenType.OPEN_CURLY_BRACKET || | |
| 28 type == TokenType.OPEN_PAREN || | |
| 29 type == TokenType.OPEN_SQUARE_BRACKET || | |
| 30 type == TokenType.STRING_INTERPOLATION_EXPRESSION); | |
| 31 } | |
| 32 | |
| 33 @override | |
| 34 Token copy() => new BeginToken(type, offset); | |
| 35 } | |
| 36 | |
| 37 /** | |
| 38 * A begin token that is preceded by comments. | |
| 39 */ | |
| 40 class BeginTokenWithComment extends BeginToken implements TokenWithComment { | |
| 41 /** | |
| 42 * The first comment in the list of comments that precede this token. | |
| 43 */ | |
| 44 @override | |
| 45 CommentToken _precedingComment; | |
| 46 | |
| 47 /** | |
| 48 * Initialize a newly created token to have the given [type] at the given | |
| 49 * [offset] and to be preceded by the comments reachable from the given | |
| 50 * [_precedingComment]. | |
| 51 */ | |
| 52 BeginTokenWithComment(TokenType type, int offset, this._precedingComment) | |
| 53 : super(type, offset) { | |
| 54 _setCommentParent(_precedingComment); | |
| 55 } | |
| 56 | |
| 57 @override | |
| 58 CommentToken get precedingComments => _precedingComment; | |
| 59 | |
| 60 @override | |
| 61 void set precedingComments(CommentToken comment) { | |
| 62 _precedingComment = comment; | |
| 63 _setCommentParent(_precedingComment); | |
| 64 } | |
| 65 | |
| 66 @override | |
| 67 void applyDelta(int delta) { | |
| 68 super.applyDelta(delta); | |
| 69 Token token = precedingComments; | |
| 70 while (token != null) { | |
| 71 token.applyDelta(delta); | |
| 72 token = token.next; | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 @override | |
| 77 Token copy() => | |
| 78 new BeginTokenWithComment(type, offset, copyComments(precedingComments)); | |
| 79 } | |
| 80 | |
| 81 /** | |
| 82 * A token representing a comment. | |
| 83 */ | |
| 84 class CommentToken extends StringToken { | |
| 85 /** | |
| 86 * The token that contains this comment. | |
| 87 */ | |
| 88 TokenWithComment parent; | |
| 89 | |
| 90 /** | |
| 91 * Initialize a newly created token to represent a token of the given [type] | |
| 92 * with the given [value] at the given [offset]. | |
| 93 */ | |
| 94 CommentToken(TokenType type, String value, int offset) | |
| 95 : super(type, value, offset); | |
| 96 | |
| 97 @override | |
| 98 CommentToken copy() => new CommentToken(type, _value, offset); | |
| 99 | |
| 100 /** | |
| 101 * Remove this comment token from the list. | |
| 102 * | |
| 103 * This is used when we decide to interpret the comment as syntax. | |
| 104 */ | |
| 105 void remove() { | |
| 106 if (previous != null) { | |
| 107 previous.setNextWithoutSettingPrevious(next); | |
| 108 next?.previous = previous; | |
| 109 } else { | |
| 110 assert(parent.precedingComments == this); | |
| 111 parent.precedingComments = next; | |
| 112 } | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 /** | |
| 117 * A documentation comment token. | |
| 118 */ | |
| 119 class DocumentationCommentToken extends CommentToken { | |
| 120 /** | |
| 121 * The references embedded within the documentation comment. | |
| 122 * This list will be empty unless this is a documentation comment that has | |
| 123 * references embedded within it. | |
| 124 */ | |
| 125 final List<Token> references = <Token>[]; | |
| 126 | |
| 127 /** | |
| 128 * Initialize a newly created token to represent a token of the given [type] | |
| 129 * with the given [value] at the given [offset]. | |
| 130 */ | |
| 131 DocumentationCommentToken(TokenType type, String value, int offset) | |
| 132 : super(type, value, offset); | |
| 133 | |
| 134 @override | |
| 135 CommentToken copy() { | |
| 136 DocumentationCommentToken copy = | |
| 137 new DocumentationCommentToken(type, _value, offset); | |
| 138 references.forEach((ref) => copy.references.add(ref.copy())); | |
| 139 return copy; | |
| 140 } | |
| 141 } | |
| 15 | 142 |
| 16 /** | 143 /** |
| 17 * The keywords in the Dart programming language. | 144 * The keywords in the Dart programming language. |
| 18 * | 145 * |
| 19 * Clients may not extend, implement or mix-in this class. | 146 * Clients may not extend, implement or mix-in this class. |
| 20 */ | 147 */ |
| 21 class Keyword { | 148 class Keyword { |
| 22 static const Keyword ABSTRACT = const Keyword._('ABSTRACT', "abstract", true); | 149 static const Keyword ABSTRACT = const Keyword._('ABSTRACT', "abstract", true); |
| 23 | 150 |
| 24 static const Keyword AS = const Keyword._('AS', "as", true); | 151 static const Keyword AS = const Keyword._('AS', "as", true); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 LinkedHashMap<String, Keyword> result = | 335 LinkedHashMap<String, Keyword> result = |
| 209 new LinkedHashMap<String, Keyword>(); | 336 new LinkedHashMap<String, Keyword>(); |
| 210 for (Keyword keyword in values) { | 337 for (Keyword keyword in values) { |
| 211 result[keyword.syntax] = keyword; | 338 result[keyword.syntax] = keyword; |
| 212 } | 339 } |
| 213 return result; | 340 return result; |
| 214 } | 341 } |
| 215 } | 342 } |
| 216 | 343 |
| 217 /** | 344 /** |
| 345 * A token representing a keyword in the language. | |
| 346 */ | |
| 347 class KeywordToken extends SimpleToken { | |
| 348 @override | |
| 349 final Keyword keyword; | |
| 350 | |
| 351 /** | |
| 352 * Initialize a newly created token to represent the given [keyword] at the | |
| 353 * given [offset]. | |
| 354 */ | |
| 355 KeywordToken(this.keyword, int offset) : super(TokenType.KEYWORD, offset); | |
| 356 | |
| 357 @override | |
| 358 String get lexeme => keyword.syntax; | |
| 359 | |
| 360 @override | |
| 361 Token copy() => new KeywordToken(keyword, offset); | |
| 362 | |
| 363 @override | |
| 364 Keyword value() => keyword; | |
| 365 } | |
| 366 | |
| 367 /** | |
| 368 * A keyword token that is preceded by comments. | |
| 369 */ | |
| 370 class KeywordTokenWithComment extends KeywordToken implements TokenWithComment { | |
| 371 /** | |
| 372 * The first comment in the list of comments that precede this token. | |
| 373 */ | |
| 374 @override | |
| 375 CommentToken _precedingComment; | |
| 376 | |
| 377 /** | |
| 378 * Initialize a newly created token to to represent the given [keyword] at the | |
| 379 * given [offset] and to be preceded by the comments reachable from the given | |
| 380 * [_precedingComment]. | |
| 381 */ | |
| 382 KeywordTokenWithComment(Keyword keyword, int offset, this._precedingComment) | |
| 383 : super(keyword, offset) { | |
| 384 _setCommentParent(_precedingComment); | |
| 385 } | |
| 386 | |
| 387 @override | |
| 388 CommentToken get precedingComments => _precedingComment; | |
| 389 | |
| 390 void set precedingComments(CommentToken comment) { | |
| 391 _precedingComment = comment; | |
| 392 _setCommentParent(_precedingComment); | |
| 393 } | |
| 394 | |
| 395 @override | |
| 396 void applyDelta(int delta) { | |
| 397 super.applyDelta(delta); | |
| 398 Token token = precedingComments; | |
| 399 while (token != null) { | |
| 400 token.applyDelta(delta); | |
| 401 token = token.next; | |
| 402 } | |
| 403 } | |
| 404 | |
| 405 @override | |
| 406 Token copy() => new KeywordTokenWithComment( | |
| 407 keyword, offset, copyComments(precedingComments)); | |
| 408 } | |
| 409 | |
| 410 /** | |
| 411 * A token that was scanned from the input. Each token knows which tokens | |
| 412 * precede and follow it, acting as a link in a doubly linked list of tokens. | |
| 413 */ | |
| 414 class SimpleToken implements Token { | |
| 415 /** | |
| 416 * The type of the token. | |
| 417 */ | |
| 418 @override | |
| 419 final TokenType type; | |
| 420 | |
| 421 /** | |
| 422 * The offset from the beginning of the file to the first character in the | |
| 423 * token. | |
| 424 */ | |
| 425 @override | |
| 426 int offset = 0; | |
| 427 | |
| 428 /** | |
| 429 * The previous token in the token stream. | |
| 430 */ | |
| 431 @override | |
| 432 Token previous; | |
| 433 | |
| 434 /** | |
| 435 * The next token in the token stream. | |
| 436 */ | |
| 437 Token _next; | |
| 438 | |
| 439 /** | |
| 440 * Initialize a newly created token to have the given [type] and [offset]. | |
| 441 */ | |
| 442 SimpleToken(this.type, this.offset); | |
| 443 | |
| 444 @override | |
| 445 int get end => offset + length; | |
| 446 | |
| 447 @override | |
| 448 bool get isOperator => type.isOperator; | |
| 449 | |
| 450 @override | |
| 451 bool get isSynthetic => length == 0; | |
| 452 | |
| 453 @override | |
| 454 bool get isUserDefinableOperator => type.isUserDefinableOperator; | |
| 455 | |
| 456 @override | |
| 457 Keyword get keyword => null; | |
| 458 | |
| 459 @override | |
| 460 int get length => lexeme.length; | |
| 461 | |
| 462 @override | |
| 463 String get lexeme => type.lexeme; | |
| 464 | |
| 465 @override | |
| 466 Token get next => _next; | |
| 467 | |
| 468 @override | |
| 469 CommentToken get precedingComments => null; | |
| 470 | |
| 471 @override | |
| 472 void applyDelta(int delta) { | |
| 473 offset += delta; | |
| 474 } | |
| 475 | |
| 476 @override | |
| 477 Token copy() => new Token(type, offset); | |
| 478 | |
| 479 @override | |
| 480 Token copyComments(Token token) { | |
| 481 if (token == null) { | |
| 482 return null; | |
| 483 } | |
| 484 Token head = token.copy(); | |
| 485 Token tail = head; | |
| 486 token = token.next; | |
| 487 while (token != null) { | |
| 488 tail = tail.setNext(token.copy()); | |
| 489 token = token.next; | |
| 490 } | |
| 491 return head; | |
| 492 } | |
| 493 | |
| 494 @override | |
| 495 bool matchesAny(List<TokenType> types) { | |
| 496 for (TokenType type in types) { | |
| 497 if (this.type == type) { | |
| 498 return true; | |
| 499 } | |
| 500 } | |
| 501 return false; | |
| 502 } | |
| 503 | |
| 504 @override | |
| 505 Token setNext(Token token) { | |
| 506 _next = token; | |
| 507 token.previous = this; | |
| 508 return token; | |
| 509 } | |
| 510 | |
| 511 @override | |
| 512 Token setNextWithoutSettingPrevious(Token token) { | |
| 513 _next = token; | |
| 514 return token; | |
| 515 } | |
| 516 | |
| 517 @override | |
| 518 String toString() => lexeme; | |
| 519 | |
| 520 @override | |
| 521 Object value() => type.lexeme; | |
| 522 | |
| 523 /** | |
| 524 * Sets the `parent` property to `this` for the given [comment] and all the | |
| 525 * next tokens. | |
| 526 */ | |
| 527 void _setCommentParent(CommentToken comment) { | |
| 528 while (comment != null) { | |
| 529 comment.parent = this; | |
| 530 comment = comment.next; | |
| 531 } | |
| 532 } | |
| 533 } | |
| 534 | |
| 535 /** | |
| 536 * A token whose value is independent of it's type. | |
| 537 */ | |
| 538 class StringToken extends SimpleToken { | |
| 539 /** | |
| 540 * The lexeme represented by this token. | |
| 541 */ | |
| 542 String _value; | |
| 543 | |
| 544 /** | |
| 545 * Initialize a newly created token to represent a token of the given [type] | |
| 546 * with the given [value] at the given [offset]. | |
| 547 */ | |
| 548 StringToken(TokenType type, String value, int offset) : super(type, offset) { | |
| 549 this._value = StringUtilities.intern(value); | |
| 550 } | |
| 551 | |
| 552 @override | |
| 553 String get lexeme => _value; | |
| 554 | |
| 555 @override | |
| 556 Token copy() => new StringToken(type, _value, offset); | |
| 557 | |
| 558 @override | |
| 559 String value() => _value; | |
| 560 } | |
| 561 | |
| 562 /** | |
| 563 * A string token that is preceded by comments. | |
| 564 */ | |
| 565 class StringTokenWithComment extends StringToken implements TokenWithComment { | |
| 566 /** | |
| 567 * The first comment in the list of comments that precede this token. | |
| 568 */ | |
| 569 CommentToken _precedingComment; | |
| 570 | |
| 571 /** | |
| 572 * Initialize a newly created token to have the given [type] at the given | |
| 573 * [offset] and to be preceded by the comments reachable from the given | |
| 574 * [comment]. | |
| 575 */ | |
| 576 StringTokenWithComment( | |
| 577 TokenType type, String value, int offset, this._precedingComment) | |
| 578 : super(type, value, offset) { | |
| 579 _setCommentParent(_precedingComment); | |
| 580 } | |
| 581 | |
| 582 @override | |
| 583 CommentToken get precedingComments => _precedingComment; | |
| 584 | |
| 585 void set precedingComments(CommentToken comment) { | |
| 586 _precedingComment = comment; | |
| 587 _setCommentParent(_precedingComment); | |
| 588 } | |
| 589 | |
| 590 @override | |
| 591 void applyDelta(int delta) { | |
| 592 super.applyDelta(delta); | |
| 593 Token token = precedingComments; | |
| 594 while (token != null) { | |
| 595 token.applyDelta(delta); | |
| 596 token = token.next; | |
| 597 } | |
| 598 } | |
| 599 | |
| 600 @override | |
| 601 Token copy() => new StringTokenWithComment( | |
| 602 type, lexeme, offset, copyComments(precedingComments)); | |
| 603 } | |
| 604 | |
| 605 /** | |
| 218 * A token that was scanned from the input. Each token knows which tokens | 606 * A token that was scanned from the input. Each token knows which tokens |
| 219 * precede and follow it, acting as a link in a doubly linked list of tokens. | 607 * precede and follow it, acting as a link in a doubly linked list of tokens. |
| 220 * | 608 * |
| 221 * Clients may not extend, implement or mix-in this class. | 609 * Clients may not extend, implement or mix-in this class. |
| 222 */ | 610 */ |
| 223 abstract class Token implements SyntacticEntity { | 611 abstract class Token implements SyntacticEntity { |
| 224 /** | 612 /** |
| 225 * Initialize a newly created token to have the given [type] and [offset]. | 613 * Initialize a newly created token to have the given [type] and [offset]. |
| 226 */ | 614 */ |
| 227 factory Token(TokenType type, int offset) = SimpleToken; | 615 factory Token(TokenType type, int offset) = SimpleToken; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 if (token != null && (offset < 0 || token.offset < offset)) { | 747 if (token != null && (offset < 0 || token.offset < offset)) { |
| 360 first = token; | 748 first = token; |
| 361 offset = token.offset; | 749 offset = token.offset; |
| 362 } | 750 } |
| 363 } | 751 } |
| 364 return first; | 752 return first; |
| 365 } | 753 } |
| 366 } | 754 } |
| 367 | 755 |
| 368 /** | 756 /** |
| 757 * The classes (or groups) of tokens with a similar use. | |
| 758 */ | |
| 759 class TokenClass { | |
| 760 /** | |
| 761 * A value used to indicate that the token type is not part of any specific | |
| 762 * class of token. | |
| 763 */ | |
| 764 static const TokenClass NO_CLASS = const TokenClass('NO_CLASS'); | |
| 765 | |
| 766 /** | |
| 767 * A value used to indicate that the token type is an additive operator. | |
| 768 */ | |
| 769 static const TokenClass ADDITIVE_OPERATOR = | |
| 770 const TokenClass('ADDITIVE_OPERATOR', 13); | |
| 771 | |
| 772 /** | |
| 773 * A value used to indicate that the token type is an assignment operator. | |
| 774 */ | |
| 775 static const TokenClass ASSIGNMENT_OPERATOR = | |
| 776 const TokenClass('ASSIGNMENT_OPERATOR', 1); | |
| 777 | |
| 778 /** | |
| 779 * A value used to indicate that the token type is a bitwise-and operator. | |
| 780 */ | |
| 781 static const TokenClass BITWISE_AND_OPERATOR = | |
| 782 const TokenClass('BITWISE_AND_OPERATOR', 11); | |
| 783 | |
| 784 /** | |
| 785 * A value used to indicate that the token type is a bitwise-or operator. | |
| 786 */ | |
| 787 static const TokenClass BITWISE_OR_OPERATOR = | |
| 788 const TokenClass('BITWISE_OR_OPERATOR', 9); | |
| 789 | |
| 790 /** | |
| 791 * A value used to indicate that the token type is a bitwise-xor operator. | |
| 792 */ | |
| 793 static const TokenClass BITWISE_XOR_OPERATOR = | |
| 794 const TokenClass('BITWISE_XOR_OPERATOR', 10); | |
| 795 | |
| 796 /** | |
| 797 * A value used to indicate that the token type is a cascade operator. | |
| 798 */ | |
| 799 static const TokenClass CASCADE_OPERATOR = | |
| 800 const TokenClass('CASCADE_OPERATOR', 2); | |
| 801 | |
| 802 /** | |
| 803 * A value used to indicate that the token type is a conditional operator. | |
| 804 */ | |
| 805 static const TokenClass CONDITIONAL_OPERATOR = | |
| 806 const TokenClass('CONDITIONAL_OPERATOR', 3); | |
| 807 | |
| 808 /** | |
| 809 * A value used to indicate that the token type is an equality operator. | |
| 810 */ | |
| 811 static const TokenClass EQUALITY_OPERATOR = | |
| 812 const TokenClass('EQUALITY_OPERATOR', 7); | |
| 813 | |
| 814 /** | |
| 815 * A value used to indicate that the token type is an if-null operator. | |
| 816 */ | |
| 817 static const TokenClass IF_NULL_OPERATOR = | |
| 818 const TokenClass('IF_NULL_OPERATOR', 4); | |
| 819 | |
| 820 /** | |
| 821 * A value used to indicate that the token type is a logical-and operator. | |
| 822 */ | |
| 823 static const TokenClass LOGICAL_AND_OPERATOR = | |
| 824 const TokenClass('LOGICAL_AND_OPERATOR', 6); | |
| 825 | |
| 826 /** | |
| 827 * A value used to indicate that the token type is a logical-or operator. | |
| 828 */ | |
| 829 static const TokenClass LOGICAL_OR_OPERATOR = | |
| 830 const TokenClass('LOGICAL_OR_OPERATOR', 5); | |
| 831 | |
| 832 /** | |
| 833 * A value used to indicate that the token type is a multiplicative operator. | |
| 834 */ | |
| 835 static const TokenClass MULTIPLICATIVE_OPERATOR = | |
| 836 const TokenClass('MULTIPLICATIVE_OPERATOR', 14); | |
| 837 | |
| 838 /** | |
| 839 * A value used to indicate that the token type is a relational operator. | |
| 840 */ | |
| 841 static const TokenClass RELATIONAL_OPERATOR = | |
| 842 const TokenClass('RELATIONAL_OPERATOR', 8); | |
| 843 | |
| 844 /** | |
| 845 * A value used to indicate that the token type is a shift operator. | |
| 846 */ | |
| 847 static const TokenClass SHIFT_OPERATOR = | |
| 848 const TokenClass('SHIFT_OPERATOR', 12); | |
| 849 | |
| 850 /** | |
| 851 * A value used to indicate that the token type is a unary operator. | |
| 852 */ | |
| 853 static const TokenClass UNARY_POSTFIX_OPERATOR = | |
| 854 const TokenClass('UNARY_POSTFIX_OPERATOR', 16); | |
| 855 | |
| 856 /** | |
| 857 * A value used to indicate that the token type is a unary operator. | |
| 858 */ | |
| 859 static const TokenClass UNARY_PREFIX_OPERATOR = | |
| 860 const TokenClass('UNARY_PREFIX_OPERATOR', 15); | |
| 861 | |
| 862 /** | |
| 863 * The name of the token class. | |
| 864 */ | |
| 865 final String name; | |
| 866 | |
| 867 /** | |
| 868 * The precedence of tokens of this class, or `0` if the such tokens do not | |
| 869 * represent an operator. | |
| 870 */ | |
| 871 final int precedence; | |
| 872 | |
| 873 /** | |
| 874 * Initialize a newly created class of tokens to have the given [name] and | |
| 875 * [precedence]. | |
| 876 */ | |
| 877 const TokenClass(this.name, [this.precedence = 0]); | |
| 878 | |
| 879 @override | |
| 880 String toString() => name; | |
| 881 } | |
| 882 | |
| 883 /** | |
| 369 * The types of tokens that can be returned by the scanner. | 884 * The types of tokens that can be returned by the scanner. |
| 370 * | 885 * |
| 371 * Clients may not extend, implement or mix-in this class. | 886 * Clients may not extend, implement or mix-in this class. |
| 372 */ | 887 */ |
| 373 class TokenType { | 888 class TokenType { |
| 374 /** | 889 /** |
| 375 * The type of the token that marks the start or end of the input. | 890 * The type of the token that marks the start or end of the input. |
| 376 */ | 891 */ |
| 377 static const TokenType EOF = const _EndOfFileTokenType(); | 892 static const TokenType EOF = const _EndOfFileTokenType(); |
| 378 | 893 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 * Return the precedence of the token, or `0` if the token does not represent | 1238 * Return the precedence of the token, or `0` if the token does not represent |
| 724 * an operator. | 1239 * an operator. |
| 725 */ | 1240 */ |
| 726 int get precedence => _tokenClass.precedence; | 1241 int get precedence => _tokenClass.precedence; |
| 727 | 1242 |
| 728 @override | 1243 @override |
| 729 String toString() => name; | 1244 String toString() => name; |
| 730 } | 1245 } |
| 731 | 1246 |
| 732 /** | 1247 /** |
| 1248 * A normal token that is preceded by comments. | |
| 1249 */ | |
| 1250 class TokenWithComment extends SimpleToken { | |
| 1251 /** | |
| 1252 * The first comment in the list of comments that precede this token. | |
| 1253 */ | |
| 1254 CommentToken _precedingComment; | |
| 1255 | |
| 1256 /** | |
| 1257 * Initialize a newly created token to have the given [type] at the given | |
| 1258 * [offset] and to be preceded by the comments reachable from the given | |
| 1259 * [comment]. | |
| 1260 */ | |
| 1261 TokenWithComment(TokenType type, int offset, this._precedingComment) | |
| 1262 : super(type, offset) { | |
| 1263 _setCommentParent(_precedingComment); | |
| 1264 } | |
| 1265 | |
| 1266 @override | |
| 1267 CommentToken get precedingComments => _precedingComment; | |
| 1268 | |
| 1269 void set precedingComments(CommentToken comment) { | |
| 1270 _precedingComment = comment; | |
| 1271 _setCommentParent(_precedingComment); | |
| 1272 } | |
| 1273 | |
| 1274 @override | |
| 1275 Token copy() => | |
| 1276 new TokenWithComment(type, offset, copyComments(precedingComments)); | |
| 1277 } | |
| 1278 | |
| 1279 /** | |
| 733 * A token representing the end (either the head or the tail) of a stream of | 1280 * A token representing the end (either the head or the tail) of a stream of |
| 734 * tokens. | 1281 * tokens. |
| 735 */ | 1282 */ |
| 736 class _EndOfFileTokenType extends TokenType { | 1283 class _EndOfFileTokenType extends TokenType { |
| 737 /** | 1284 /** |
| 738 * Initialize a newly created token. | 1285 * Initialize a newly created token. |
| 739 */ | 1286 */ |
| 740 const _EndOfFileTokenType() : super._('EOF', TokenClass.NO_CLASS, ''); | 1287 const _EndOfFileTokenType() : super._('EOF', TokenClass.NO_CLASS, ''); |
| 741 | 1288 |
| 742 @override | 1289 @override |
| 743 String toString() => '-eof-'; | 1290 String toString() => '-eof-'; |
| 744 } | 1291 } |
| OLD | NEW |