| 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 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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, "-"); |
| OLD | NEW |