OLD | NEW |
---|---|
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 | 8 |
9 import 'keyword.dart' show Keyword; | 9 import 'keyword.dart' show Keyword; |
10 | 10 |
11 import 'precedence.dart' show BAD_INPUT_INFO, EOF_INFO, PrecedenceInfo; | 11 import 'precedence.dart' show BAD_INPUT_INFO, EOF_INFO, PrecedenceInfo; |
12 | 12 |
13 import 'token_constants.dart' show IDENTIFIER_TOKEN; | 13 import 'token_constants.dart' show IDENTIFIER_TOKEN; |
14 | 14 |
15 import 'string_canonicalizer.dart'; | 15 import 'string_canonicalizer.dart'; |
16 | 16 |
17 /** | 17 /** |
18 * A token that doubles as a linked list. | 18 * A token that doubles as a linked list. |
19 */ | 19 */ |
20 abstract class Token implements analyzer.Token { | 20 abstract class Token implements analyzer.TokenWithComment { |
21 /** | 21 /** |
22 * The character offset of the start of this token within the source text. | 22 * The character offset of the start of this token within the source text. |
23 */ | 23 */ |
24 int charOffset; | 24 int charOffset; |
25 | 25 |
26 Token(this.charOffset); | 26 Token(this.charOffset); |
27 | 27 |
28 /** | 28 /** |
29 * The next token in the token stream. | 29 * The next token in the token stream. |
30 */ | 30 */ |
31 Token next; | 31 Token next; |
32 | 32 |
33 /** | 33 /** |
34 * The previous token in the token stream. | 34 * The previous token in the token stream. |
35 * | 35 * |
36 * Deprecated :: This exists for compatibility with the Analyzer token stream | 36 * Deprecated :: This exists for compatibility with the Analyzer token stream |
37 * and will be removed at some future date. | 37 * and will be removed at some future date. |
38 */ | 38 */ |
39 @deprecated | 39 @deprecated |
40 Token previousToken; | 40 Token previousToken; |
41 | 41 |
42 /** | 42 /** |
43 * Return the first comment in the list of comments that precede this token, | 43 * Return the first comment in the list of comments that precede this token, |
44 * or `null` if there are no comments preceding this token. Additional | 44 * or `null` if there are no comments preceding this token. Additional |
45 * comments can be reached by following the token stream using [next] until | 45 * comments can be reached by following the token stream using [next] until |
46 * `null` is returned. | 46 * `null` is returned. |
47 */ | 47 */ |
48 Token precedingComments; | 48 CommentToken precedingCommentTokens; |
49 | |
50 @override | |
51 analyzer.CommentToken get precedingComments => precedingCommentTokens; | |
52 | |
53 @override | |
54 void set precedingComments(analyzer.CommentToken token) { | |
55 precedingCommentTokens = token; | |
56 } | |
49 | 57 |
50 /** | 58 /** |
51 * The precedence info for this token. [info] determines the kind and the | 59 * The precedence info for this token. [info] determines the kind and the |
52 * precedence level of this token. | 60 * precedence level of this token. |
53 * | 61 * |
54 * Defined as getter to save a field in the [KeywordToken] subclass. | 62 * Defined as getter to save a field in the [KeywordToken] subclass. |
55 */ | 63 */ |
56 PrecedenceInfo get info; | 64 PrecedenceInfo get info; |
57 | 65 |
58 /** | 66 /** |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 analyzer.Token get previous => previousToken; | 165 analyzer.Token get previous => previousToken; |
158 | 166 |
159 @override | 167 @override |
160 set previous(analyzer.Token newToken) { | 168 set previous(analyzer.Token newToken) { |
161 previousToken = newToken as Token; | 169 previousToken = newToken as Token; |
162 } | 170 } |
163 | 171 |
164 @override | 172 @override |
165 void applyDelta(int delta) { | 173 void applyDelta(int delta) { |
166 charOffset += delta; | 174 charOffset += delta; |
167 Token token = precedingComments; | 175 CommentToken token = precedingComments; |
168 while (token != null) { | 176 while (token != null) { |
169 token.applyDelta(delta); | 177 token.applyDelta(delta); |
170 token = token.next; | 178 token = token.next; |
171 } | 179 } |
172 } | 180 } |
173 | 181 |
174 @override | 182 @override |
175 analyzer.Token copy() { | 183 analyzer.Token copy() { |
176 return copyWithoutComments() | 184 return copyWithoutComments() |
177 ..precedingComments = copyComments(precedingComments) as Token; | 185 ..precedingComments = copyComments(precedingComments); |
178 } | 186 } |
179 | 187 |
180 @override | 188 @override |
181 analyzer.Token copyComments(analyzer.Token token) { | 189 analyzer.Token copyComments(analyzer.Token token) { |
182 if (token == null) { | 190 if (token == null) { |
183 return null; | 191 return null; |
184 } | 192 } |
185 Token head = token.copy(); | 193 Token head = token.copy(); |
186 Token tail = head; | 194 Token tail = head; |
187 token = token.next; | 195 token = token.next; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 | 303 |
296 @override | 304 @override |
297 Object value() => keyword; | 305 Object value() => keyword; |
298 } | 306 } |
299 | 307 |
300 /** | 308 /** |
301 * A String-valued token. Represents identifiers, string literals, | 309 * A String-valued token. Represents identifiers, string literals, |
302 * number literals, comments, and error tokens, using the corresponding | 310 * number literals, comments, and error tokens, using the corresponding |
303 * precedence info. | 311 * precedence info. |
304 */ | 312 */ |
305 class StringToken extends Token { | 313 class StringToken extends Token implements analyzer.StringToken { |
306 /** | 314 /** |
307 * The length threshold above which substring tokens are computed lazily. | 315 * The length threshold above which substring tokens are computed lazily. |
308 * | 316 * |
309 * For string tokens that are substrings of the program source, the actual | 317 * For string tokens that are substrings of the program source, the actual |
310 * substring extraction is performed lazily. This is beneficial because | 318 * substring extraction is performed lazily. This is beneficial because |
311 * not all scanned code is actually used. For unused parts, the substrings | 319 * not all scanned code is actually used. For unused parts, the substrings |
312 * are never computed and allocated. | 320 * are never computed and allocated. |
313 */ | 321 */ |
314 static const int LAZY_THRESHOLD = 4; | 322 static const int LAZY_THRESHOLD = 4; |
315 | 323 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
397 return canonicalizer.canonicalize(s, start, end, false); | 405 return canonicalizer.canonicalize(s, start, end, false); |
398 } | 406 } |
399 | 407 |
400 static String decodeUtf8(List<int> data, int start, int end, bool asciiOnly) { | 408 static String decodeUtf8(List<int> data, int start, int end, bool asciiOnly) { |
401 return canonicalizer.canonicalize(data, start, end, asciiOnly); | 409 return canonicalizer.canonicalize(data, start, end, asciiOnly); |
402 } | 410 } |
403 | 411 |
404 @override | 412 @override |
405 Token copyWithoutComments() => | 413 Token copyWithoutComments() => |
406 new StringToken._(info, valueOrLazySubstring, charOffset); | 414 new StringToken._(info, valueOrLazySubstring, charOffset); |
415 | |
416 @override | |
417 String value() => lexeme; | |
418 } | |
419 | |
420 class CommentToken extends StringToken implements analyzer.CommentToken { | |
421 /** | |
422 * Creates a lazy comment token. If [canonicalize] is true, the string | |
423 * is canonicalized before the token is created. | |
424 */ | |
425 CommentToken.fromSubstring( | |
426 PrecedenceInfo info, String data, int start, int end, int charOffset, | |
427 {bool canonicalize: false}) | |
428 : super.fromSubstring(info, data, start, end, charOffset, | |
429 canonicalize: canonicalize); | |
430 | |
431 /** | |
432 * Creates a lazy string token. If [asciiOnly] is false, the byte array | |
433 * is passed through a UTF-8 decoder. | |
434 */ | |
435 CommentToken.fromUtf8Bytes(PrecedenceInfo info, List<int> data, int start, | |
436 int end, bool asciiOnly, int charOffset) | |
437 : super.fromUtf8Bytes(info, data, start, end, asciiOnly, charOffset); | |
438 | |
439 CommentToken._(PrecedenceInfo info, valueOrLazySubstring, int charOffset) | |
440 : super._(info, valueOrLazySubstring, charOffset); | |
441 | |
442 @override | |
443 CommentToken copy() => | |
444 new CommentToken._(info, valueOrLazySubstring, charOffset); | |
445 | |
446 @override | |
447 analyzer.TokenWithComment get parent { | |
448 Token token = next; | |
449 while (token is CommentToken) { | |
450 token = token.next; | |
451 } | |
452 return token; | |
453 } | |
454 | |
455 @override | |
456 void set parent(analyzer.TokenWithComment ignored) { | |
457 throw 'unsupported operation'; | |
Paul Berry
2017/03/21 14:23:07
Change this to `throw new StateError('unsupported
ahe
2017/03/21 14:36:50
I generally use strings for internal errors. We ha
danrubel
2017/03/22 17:10:48
Fixed. https://codereview.chromium.org/2767083002/
| |
458 } | |
459 | |
460 @override | |
461 void remove() { | |
462 // TODO: implement remove | |
Paul Berry
2017/03/21 14:23:07
Nit: change this to TODO(danrubel)
danrubel
2017/03/22 17:10:48
Fixed. https://codereview.chromium.org/2767083002/
| |
463 throw 'not implemented yet'; | |
Paul Berry
2017/03/21 14:23:07
Similarly, change to `throw new UnimplementedError
danrubel
2017/03/22 17:10:48
Fixed. https://codereview.chromium.org/2767083002/
| |
464 } | |
465 } | |
466 | |
467 class DartDocToken extends CommentToken | |
468 implements analyzer.DocumentationCommentToken { | |
469 /** | |
470 * The references embedded within the documentation comment. | |
471 * This list will be empty unless this is a documentation comment that has | |
472 * references embedded within it. | |
473 */ | |
474 final List<Token> references = <Token>[]; | |
475 | |
476 /** | |
477 * Creates a lazy comment token. If [canonicalize] is true, the string | |
478 * is canonicalized before the token is created. | |
479 */ | |
480 DartDocToken.fromSubstring( | |
481 PrecedenceInfo info, String data, int start, int end, int charOffset, | |
482 {bool canonicalize: false}) | |
483 : super.fromSubstring(info, data, start, end, charOffset, | |
484 canonicalize: canonicalize); | |
485 | |
486 /** | |
487 * Creates a lazy string token. If [asciiOnly] is false, the byte array | |
488 * is passed through a UTF-8 decoder. | |
489 */ | |
490 DartDocToken.fromUtf8Bytes(PrecedenceInfo info, List<int> data, int start, | |
491 int end, bool asciiOnly, int charOffset) | |
492 : super.fromUtf8Bytes(info, data, start, end, asciiOnly, charOffset); | |
493 | |
494 DartDocToken._(PrecedenceInfo info, valueOrLazySubstring, int charOffset) | |
495 : super._(info, valueOrLazySubstring, charOffset); | |
496 | |
497 @override | |
498 DartDocToken copy() { | |
499 DartDocToken copy = | |
500 new DartDocToken._(info, valueOrLazySubstring, charOffset); | |
501 references.forEach((ref) => copy.references.add(ref.copy())); | |
502 return copy; | |
503 } | |
407 } | 504 } |
408 | 505 |
409 /** | 506 /** |
410 * This class represents the necessary information to compute a substring | 507 * This class represents the necessary information to compute a substring |
411 * lazily. The substring can either originate from a string or from | 508 * lazily. The substring can either originate from a string or from |
412 * a [:List<int>:] of UTF-8 bytes. | 509 * a [:List<int>:] of UTF-8 bytes. |
413 */ | 510 */ |
414 abstract class LazySubstring { | 511 abstract class LazySubstring { |
415 /** The original data, either a string or a List<int> */ | 512 /** The original data, either a string or a List<int> */ |
416 get data; | 513 get data; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
495 identical(value, "<=") || | 592 identical(value, "<=") || |
496 identical(value, "<") || | 593 identical(value, "<") || |
497 identical(value, "&") || | 594 identical(value, "&") || |
498 identical(value, "^") || | 595 identical(value, "^") || |
499 identical(value, "|"); | 596 identical(value, "|"); |
500 } | 597 } |
501 | 598 |
502 bool isTernaryOperator(String value) => identical(value, "[]="); | 599 bool isTernaryOperator(String value) => identical(value, "[]="); |
503 | 600 |
504 bool isMinusOperator(String value) => identical(value, "-"); | 601 bool isMinusOperator(String value) => identical(value, "-"); |
OLD | NEW |