Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: pkg/front_end/lib/src/scanner/token.dart

Issue 2486873003: Move scanner into pkg/front_end/lib/src/scanner. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698