| 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'; |
| 458 } |
| 459 |
| 460 @override |
| 461 void remove() { |
| 462 // TODO: implement remove |
| 463 throw 'not implemented yet'; |
| 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 |