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

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

Issue 2872433005: more work aligning fasta.Token with analyzer.Token (Closed)
Patch Set: Created 3 years, 7 months 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 library fasta.scanner.token; 5 library fasta.scanner.token;
6 6
7 import '../../scanner/token.dart' as analyzer; 7 import '../../scanner/token.dart' as analyzer;
8 import '../../scanner/token.dart' show TokenType; 8 import '../../scanner/token.dart' show TokenType;
9 9
10 import 'token_constants.dart' show IDENTIFIER_TOKEN; 10 import 'token_constants.dart' show IDENTIFIER_TOKEN;
11 11
12 import 'string_canonicalizer.dart'; 12 import 'string_canonicalizer.dart';
13 13
14 /** 14 /**
15 * A token that doubles as a linked list. 15 * A token that doubles as a linked list.
16 */ 16 */
17 abstract class Token implements analyzer.TokenWithComment { 17 abstract class Token implements analyzer.TokenWithComment {
18 @override 18 @override
19 int charOffset; 19 int charOffset;
20 20
21 Token(this.charOffset); 21 Token(this.charOffset);
22 22
23 /** 23 @override
24 * The next token in the token stream. 24 analyzer.Token next;
25 */
26 Token next;
27
28 /**
29 * The previous token in the token stream.
30 *
31 * Deprecated :: This exists for compatibility with the Analyzer token stream
32 * and will be removed at some future date.
33 */
34 @deprecated
35 Token previousToken;
36
37 /**
38 * Return the first comment in the list of comments that precede this token,
39 * or `null` if there are no comments preceding this token. Additional
40 * comments can be reached by following the token stream using [next] until
41 * `null` is returned.
42 */
43 CommentToken precedingCommentTokens;
44 25
45 @override 26 @override
46 analyzer.CommentToken get precedingComments => precedingCommentTokens; 27 analyzer.Token previous;
47 28
48 @override 29 @override
49 void set precedingComments(analyzer.CommentToken token) { 30 analyzer.CommentToken precedingComments;
50 precedingCommentTokens = token;
51 }
52
53 /**
54 * The string represented by this token, a substring of the source code.
55 *
56 * For [StringToken]s the [lexeme] includes the quotes, explicit escapes, etc.
57 */
58 String get lexeme;
59 31
60 @override 32 @override
61 String get stringValue => type.stringValue; 33 String get stringValue => type.stringValue;
62 34
63 /** 35 @override
64 * The kind enum of this token as determined by its [type].
65 */
66 int get kind => type.kind; 36 int get kind => type.kind;
67 37
68 /** 38 /**
69 * The precedence level for this token.
70 */
71 int get precedence => type.precedence;
72
73 /**
74 * True if this token is an identifier. Some keywords allowed as identifiers,
75 * see implementation in [KeywordToken].
76 */
77 bool get isIdentifier;
78
79 bool get isPseudo => false;
80
81 /**
82 * Returns a textual representation of this token to be used for debugging 39 * Returns a textual representation of this token to be used for debugging
83 * purposes. The resulting string might contain information about the 40 * purposes. The resulting string might contain information about the
84 * structure of the token, for example 'StringToken(foo)' for the identifier 41 * structure of the token, for example 'StringToken(foo)' for the identifier
85 * token 'foo'. 42 * token 'foo'.
86 * 43 *
87 * Use [lexeme] for the text actually parsed by the token. 44 * Use [lexeme] for the text actually parsed by the token.
88 */ 45 */
89 String toString(); 46 String toString();
90 47
91 @override 48 @override
92 int get charCount { 49 int get charCount => lexeme.length;
93 if (type == analyzer.TokenType.BAD_INPUT) {
94 // This is a token that wraps around an error message. Return 1
95 // instead of the size of the length of the error message.
96 return 1;
97 } else {
98 return lexeme.length;
99 }
100 }
101 50
102 @override 51 @override
103 int get charEnd => charOffset + charCount; 52 int get charEnd => charOffset + charCount;
104 53
105 @override 54 @override
106 bool get isEof => type == analyzer.TokenType.EOF; 55 bool get isEof => type == analyzer.TokenType.EOF;
107 56
108 bool get isBuiltInIdentifier => false; 57 bool get isBuiltInIdentifier => false;
109 58
110 @override 59 @override
(...skipping 10 matching lines...) Expand all
121 charOffset = newOffset; 70 charOffset = newOffset;
122 } 71 }
123 72
124 @override 73 @override
125 int get length => charCount; 74 int get length => charCount;
126 75
127 @override 76 @override
128 int get end => charEnd; 77 int get end => charEnd;
129 78
130 @override 79 @override
131 analyzer.Token get previous => previousToken;
132
133 @override
134 set previous(analyzer.Token newToken) {
135 previousToken = newToken as Token;
136 }
137
138 @override
139 void applyDelta(int delta) { 80 void applyDelta(int delta) {
140 charOffset += delta; 81 charOffset += delta;
141 CommentToken token = precedingComments; 82 CommentToken token = precedingComments;
142 while (token != null) { 83 while (token != null) {
143 token.applyDelta(delta); 84 token.applyDelta(delta);
144 token = token.next; 85 token = token.next;
145 } 86 }
146 } 87 }
147 88
148 @override 89 @override
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 if (this.type == type) { 122 if (this.type == type) {
182 return true; 123 return true;
183 } 124 }
184 } 125 }
185 return false; 126 return false;
186 } 127 }
187 128
188 @override 129 @override
189 analyzer.Token setNext(analyzer.Token token) { 130 analyzer.Token setNext(analyzer.Token token) {
190 next = token as Token; 131 next = token as Token;
191 next.previousToken = this; 132 next.previous = this;
192 return token; 133 return token;
193 } 134 }
194 135
195 @override 136 @override
196 analyzer.Token setNextWithoutSettingPrevious(analyzer.Token token) { 137 analyzer.Token setNextWithoutSettingPrevious(analyzer.Token token) {
197 next = token as Token; 138 next = token as Token;
198 return token; 139 return token;
199 } 140 }
200 141
201 @override 142 @override
202 Object value() => lexeme; 143 Object value() => lexeme;
203 } 144 }
204 145
205 /** 146 /**
206 * A [SymbolToken] represents the symbol in its precedence info. 147 * A [SymbolToken] represents the symbol in its precedence info.
207 * Also used for end of file with EOF_INFO. 148 * Also used for end of file with EOF_INFO.
208 */ 149 */
209 class SymbolToken extends Token { 150 class SymbolToken extends Token {
210 final TokenType type; 151 final TokenType type;
211 152
212 SymbolToken(this.type, int charOffset) : super(charOffset); 153 SymbolToken(this.type, int charOffset) : super(charOffset);
213 154
214 factory SymbolToken.eof(int charOffset) { 155 factory SymbolToken.eof(int charOffset) {
215 var eof = new SyntheticSymbolToken(analyzer.TokenType.EOF, charOffset); 156 var eof = new SyntheticSymbolToken(analyzer.TokenType.EOF, charOffset);
216 // EOF points to itself so there's always infinite look-ahead. 157 // EOF points to itself so there's always infinite look-ahead.
217 eof.previousToken = eof; 158 eof.previous = eof;
218 eof.next = eof; 159 eof.next = eof;
219 return eof; 160 return eof;
220 } 161 }
221 162
222 @override 163 @override
223 String get lexeme => type.value; 164 String get lexeme => type.value;
224 165
225 @override 166 @override
226 bool get isIdentifier => false; 167 bool get isIdentifier => false;
227 168
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 } 222 }
282 223
283 /** 224 /**
284 * A keyword token. 225 * A keyword token.
285 */ 226 */
286 class KeywordToken extends Token implements analyzer.KeywordTokenWithComment { 227 class KeywordToken extends Token implements analyzer.KeywordTokenWithComment {
287 final analyzer.Keyword keyword; 228 final analyzer.Keyword keyword;
288 229
289 KeywordToken(this.keyword, int charOffset) : super(charOffset); 230 KeywordToken(this.keyword, int charOffset) : super(charOffset);
290 231
291 TokenType get info => keyword; 232 @override
292
293 String get lexeme => keyword.lexeme; 233 String get lexeme => keyword.lexeme;
294 234
235 @override
295 bool get isIdentifier => keyword.isPseudo || keyword.isBuiltIn; 236 bool get isIdentifier => keyword.isPseudo || keyword.isBuiltIn;
296 237
297 bool get isPseudo => keyword.isPseudo; 238 @override
298
299 bool get isBuiltInIdentifier => keyword.isBuiltIn; 239 bool get isBuiltInIdentifier => keyword.isBuiltIn;
300 240
241 @override
301 String toString() => "KeywordToken($lexeme)"; 242 String toString() => "KeywordToken($lexeme)";
302 243
303 @override 244 @override
304 Token copyWithoutComments() => new KeywordToken(keyword, charOffset); 245 Token copyWithoutComments() => new KeywordToken(keyword, charOffset);
305 246
306 @override 247 @override
307 analyzer.Keyword value() => keyword; 248 analyzer.Keyword value() => keyword;
308 249
309 @override 250 @override
310 analyzer.TokenType get type => keyword; 251 analyzer.TokenType get type => keyword;
(...skipping 25 matching lines...) Expand all
336 * A String-valued token. Represents identifiers, string literals, 277 * A String-valued token. Represents identifiers, string literals,
337 * number literals, comments, and error tokens, using the corresponding 278 * number literals, comments, and error tokens, using the corresponding
338 * precedence info. 279 * precedence info.
339 */ 280 */
340 class StringToken extends Token implements analyzer.StringTokenWithComment { 281 class StringToken extends Token implements analyzer.StringTokenWithComment {
341 /** 282 /**
342 * The length threshold above which substring tokens are computed lazily. 283 * The length threshold above which substring tokens are computed lazily.
343 * 284 *
344 * For string tokens that are substrings of the program source, the actual 285 * For string tokens that are substrings of the program source, the actual
345 * substring extraction is performed lazily. This is beneficial because 286 * substring extraction is performed lazily. This is beneficial because
346 * not all scanned code is actually used. For unused parts, the substrings 287 * not all scanned code are actually used. For unused parts, the substrings
347 * are never computed and allocated. 288 * are never computed and allocated.
348 */ 289 */
349 static const int LAZY_THRESHOLD = 4; 290 static const int LAZY_THRESHOLD = 4;
350 291
351 var /* String | LazySubtring */ valueOrLazySubstring; 292 var /* String | LazySubtring */ valueOrLazySubstring;
352 293
294 @override
353 final TokenType type; 295 final TokenType type;
354 296
355 /** 297 /**
356 * Creates a non-lazy string token. If [canonicalize] is true, the string 298 * Creates a non-lazy string token. If [canonicalize] is true, the string
357 * is canonicalized before the token is created. 299 * is canonicalized before the token is created.
358 */ 300 */
359 StringToken.fromString(this.type, String value, int charOffset, 301 StringToken.fromString(this.type, String value, int charOffset,
360 {bool canonicalize: false}) 302 {bool canonicalize: false})
361 : valueOrLazySubstring = 303 : valueOrLazySubstring =
362 canonicalizedString(value, 0, value.length, canonicalize), 304 canonicalizedString(value, 0, value.length, canonicalize),
363 super(charOffset); 305 super(charOffset);
364 306
365 /** 307 /**
366 * Creates a lazy string token. If [canonicalize] is true, the string 308 * Creates a lazy string token. If [canonicalize] is true, the string
367 * is canonicalized before the token is created. 309 * is canonicalized before the token is created.
368 */ 310 */
369 StringToken.fromSubstring( 311 StringToken.fromSubstring(
370 this.type, String data, int start, int end, int charOffset, 312 this.type, String data, int start, int end, int charOffset,
371 {bool canonicalize: false}) 313 {bool canonicalize: false})
372 : super(charOffset) { 314 : super(charOffset) {
373 int length = end - start; 315 int length = end - start;
374 if (length <= LAZY_THRESHOLD) { 316 if (length <= LAZY_THRESHOLD) {
375 valueOrLazySubstring = 317 valueOrLazySubstring =
376 canonicalizedString(data, start, end, canonicalize); 318 canonicalizedString(data, start, end, canonicalize);
377 } else { 319 } else {
378 valueOrLazySubstring = 320 valueOrLazySubstring =
379 new LazySubstring(data, start, length, canonicalize); 321 new _LazySubstring(data, start, length, canonicalize);
380 } 322 }
381 } 323 }
382 324
383 /** 325 /**
384 * Creates a lazy string token. If [asciiOnly] is false, the byte array 326 * Creates a lazy string token. If [asciiOnly] is false, the byte array
385 * is passed through a UTF-8 decoder. 327 * is passed through a UTF-8 decoder.
386 */ 328 */
387 StringToken.fromUtf8Bytes(this.type, List<int> data, int start, int end, 329 StringToken.fromUtf8Bytes(this.type, List<int> data, int start, int end,
388 bool asciiOnly, int charOffset) 330 bool asciiOnly, int charOffset)
389 : super(charOffset) { 331 : super(charOffset) {
390 int length = end - start; 332 int length = end - start;
391 if (length <= LAZY_THRESHOLD) { 333 if (length <= LAZY_THRESHOLD) {
392 valueOrLazySubstring = decodeUtf8(data, start, end, asciiOnly); 334 valueOrLazySubstring = decodeUtf8(data, start, end, asciiOnly);
393 } else { 335 } else {
394 valueOrLazySubstring = new LazySubstring(data, start, length, asciiOnly); 336 valueOrLazySubstring = new _LazySubstring(data, start, length, asciiOnly);
395 } 337 }
396 } 338 }
397 339
398 StringToken._(this.type, this.valueOrLazySubstring, int charOffset) 340 StringToken._(this.type, this.valueOrLazySubstring, int charOffset)
399 : super(charOffset); 341 : super(charOffset);
400 342
343 @override
401 String get lexeme { 344 String get lexeme {
402 if (valueOrLazySubstring is String) { 345 if (valueOrLazySubstring is String) {
403 return valueOrLazySubstring; 346 return valueOrLazySubstring;
404 } else { 347 } else {
405 assert(valueOrLazySubstring is LazySubstring); 348 assert(valueOrLazySubstring is _LazySubstring);
406 var data = valueOrLazySubstring.data; 349 var data = valueOrLazySubstring.data;
407 int start = valueOrLazySubstring.start; 350 int start = valueOrLazySubstring.start;
408 int end = start + valueOrLazySubstring.length; 351 int end = start + valueOrLazySubstring.length;
409 if (data is String) { 352 if (data is String) {
410 valueOrLazySubstring = canonicalizedString( 353 valueOrLazySubstring = canonicalizedString(
411 data, start, end, valueOrLazySubstring.boolValue); 354 data, start, end, valueOrLazySubstring.boolValue);
412 } else { 355 } else {
413 valueOrLazySubstring = 356 valueOrLazySubstring =
414 decodeUtf8(data, start, end, valueOrLazySubstring.boolValue); 357 decodeUtf8(data, start, end, valueOrLazySubstring.boolValue);
415 } 358 }
416 return valueOrLazySubstring; 359 return valueOrLazySubstring;
417 } 360 }
418 } 361 }
419 362
363 @override
420 bool get isIdentifier => identical(kind, IDENTIFIER_TOKEN); 364 bool get isIdentifier => identical(kind, IDENTIFIER_TOKEN);
421 365
366 @override
422 String toString() => "StringToken($lexeme)"; 367 String toString() => "StringToken($lexeme)";
423 368
424 static final StringCanonicalizer canonicalizer = new StringCanonicalizer(); 369 static final StringCanonicalizer canonicalizer = new StringCanonicalizer();
425 370
426 static String canonicalizedString( 371 static String canonicalizedString(
427 String s, int start, int end, bool canonicalize) { 372 String s, int start, int end, bool canonicalize) {
428 if (!canonicalize) return s; 373 if (!canonicalize) return s;
429 return canonicalizer.canonicalize(s, start, end, false); 374 return canonicalizer.canonicalize(s, start, end, false);
430 } 375 }
431 376
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 next?.previous = previous; 447 next?.previous = previous;
503 } else { 448 } else {
504 assert(parent.precedingComments == this); 449 assert(parent.precedingComments == this);
505 parent.precedingComments = next as CommentToken; 450 parent.precedingComments = next as CommentToken;
506 } 451 }
507 } 452 }
508 } 453 }
509 454
510 class DartDocToken extends CommentToken 455 class DartDocToken extends CommentToken
511 implements analyzer.DocumentationCommentToken { 456 implements analyzer.DocumentationCommentToken {
512 /** 457 @override
513 * The references embedded within the documentation comment.
514 * This list will be empty unless this is a documentation comment that has
515 * references embedded within it.
516 */
517 final List<Token> references = <Token>[]; 458 final List<Token> references = <Token>[];
518 459
519 /** 460 /**
520 * Creates a lazy comment token. If [canonicalize] is true, the string 461 * Creates a lazy comment token. If [canonicalize] is true, the string
521 * is canonicalized before the token is created. 462 * is canonicalized before the token is created.
522 */ 463 */
523 DartDocToken.fromSubstring( 464 DartDocToken.fromSubstring(
524 TokenType type, String data, int start, int end, int charOffset, 465 TokenType type, String data, int start, int end, int charOffset,
525 {bool canonicalize: false}) 466 {bool canonicalize: false})
526 : super.fromSubstring(type, data, start, end, charOffset, 467 : super.fromSubstring(type, data, start, end, charOffset,
(...skipping 17 matching lines...) Expand all
544 references.forEach((ref) => copy.references.add(ref.copy())); 485 references.forEach((ref) => copy.references.add(ref.copy()));
545 return copy; 486 return copy;
546 } 487 }
547 } 488 }
548 489
549 /** 490 /**
550 * This class represents the necessary information to compute a substring 491 * This class represents the necessary information to compute a substring
551 * lazily. The substring can either originate from a string or from 492 * lazily. The substring can either originate from a string or from
552 * a [:List<int>:] of UTF-8 bytes. 493 * a [:List<int>:] of UTF-8 bytes.
553 */ 494 */
554 abstract class LazySubstring { 495 abstract class _LazySubstring {
555 /** The original data, either a string or a List<int> */ 496 /** The original data, either a string or a List<int> */
556 get data; 497 get data;
557 498
558 int get start; 499 int get start;
559 int get length; 500 int get length;
560 501
561 /** 502 /**
562 * If this substring is based on a String, the [boolValue] indicates wheter 503 * If this substring is based on a String, the [boolValue] indicates wheter
563 * the resulting substring should be canonicalized. 504 * the resulting substring should be canonicalized.
564 * 505 *
565 * For substrings based on a byte array, the [boolValue] is true if the 506 * For substrings based on a byte array, the [boolValue] is true if the
566 * array only holds ASCII characters. The resulting substring will be 507 * array only holds ASCII characters. The resulting substring will be
567 * canonicalized after decoding. 508 * canonicalized after decoding.
568 */ 509 */
569 bool get boolValue; 510 bool get boolValue;
570 511
571 LazySubstring.internal(); 512 _LazySubstring.internal();
572 513
573 factory LazySubstring(data, int start, int length, bool b) { 514 factory _LazySubstring(data, int start, int length, bool b) {
574 // See comment on [CompactLazySubstring]. 515 // See comment on [CompactLazySubstring].
575 if (start < 0x100000 && length < 0x200) { 516 if (start < 0x100000 && length < 0x200) {
576 int fields = (start << 9); 517 int fields = (start << 9);
577 fields = fields | length; 518 fields = fields | length;
578 fields = fields << 1; 519 fields = fields << 1;
579 if (b) fields |= 1; 520 if (b) fields |= 1;
580 return new CompactLazySubstring(data, fields); 521 return new _CompactLazySubstring(data, fields);
581 } else { 522 } else {
582 return new FullLazySubstring(data, start, length, b); 523 return new _FullLazySubstring(data, start, length, b);
583 } 524 }
584 } 525 }
585 } 526 }
586 527
587 /** 528 /**
588 * This class encodes [start], [length] and [boolValue] in a single 529 * This class encodes [start], [length] and [boolValue] in a single
589 * 30 bit integer. It uses 20 bits for [start], which covers source files 530 * 30 bit integer. It uses 20 bits for [start], which covers source files
590 * of 1MB. [length] has 9 bits, which covers 512 characters. 531 * of 1MB. [length] has 9 bits, which covers 512 characters.
591 * 532 *
592 * The file html_dart2js.dart is currently around 1MB. 533 * The file html_dart2js.dart is currently around 1MB.
593 */ 534 */
594 class CompactLazySubstring extends LazySubstring { 535 class _CompactLazySubstring extends _LazySubstring {
595 final data; 536 final data;
596 final int fields; 537 final int fields;
597 538
598 CompactLazySubstring(this.data, this.fields) : super.internal(); 539 _CompactLazySubstring(this.data, this.fields) : super.internal();
599 540
600 int get start => fields >> 10; 541 int get start => fields >> 10;
601 int get length => (fields >> 1) & 0x1ff; 542 int get length => (fields >> 1) & 0x1ff;
602 bool get boolValue => (fields & 1) == 1; 543 bool get boolValue => (fields & 1) == 1;
603 } 544 }
604 545
605 class FullLazySubstring extends LazySubstring { 546 class _FullLazySubstring extends _LazySubstring {
606 final data; 547 final data;
607 final int start; 548 final int start;
608 final int length; 549 final int length;
609 final bool boolValue; 550 final bool boolValue;
610 FullLazySubstring(this.data, this.start, this.length, this.boolValue) 551 _FullLazySubstring(this.data, this.start, this.length, this.boolValue)
611 : super.internal(); 552 : super.internal();
612 } 553 }
613 554
614 bool isUserDefinableOperator(String value) { 555 bool isUserDefinableOperator(String value) {
615 return isBinaryOperator(value) || 556 return isBinaryOperator(value) ||
616 isMinusOperator(value) || 557 isMinusOperator(value) ||
617 isTernaryOperator(value) || 558 isTernaryOperator(value) ||
618 isUnaryOperator(value); 559 isUnaryOperator(value);
619 } 560 }
620 561
(...skipping 14 matching lines...) Expand all
635 identical(value, "<=") || 576 identical(value, "<=") ||
636 identical(value, "<") || 577 identical(value, "<") ||
637 identical(value, "&") || 578 identical(value, "&") ||
638 identical(value, "^") || 579 identical(value, "^") ||
639 identical(value, "|"); 580 identical(value, "|");
640 } 581 }
641 582
642 bool isTernaryOperator(String value) => identical(value, "[]="); 583 bool isTernaryOperator(String value) => identical(value, "[]=");
643 584
644 bool isMinusOperator(String value) => identical(value, "-"); 585 bool isMinusOperator(String value) => identical(value, "-");
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698