Chromium Code Reviews| 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 { | 20 abstract class Token implements analyzer.Token { |
| 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 final 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. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 } | 123 } |
| 124 } | 124 } |
| 125 | 125 |
| 126 /// The character offset of the end of this token within the source text. | 126 /// The character offset of the end of this token within the source text. |
| 127 int get charEnd => charOffset + charCount; | 127 int get charEnd => charOffset + charCount; |
| 128 | 128 |
| 129 bool get isEof => false; | 129 bool get isEof => false; |
| 130 | 130 |
| 131 bool get isBuiltInIdentifier => false; | 131 bool get isBuiltInIdentifier => false; |
| 132 | 132 |
| 133 @override | |
| 133 bool get isOperator => info.isOperator; | 134 bool get isOperator => info.isOperator; |
| 134 | 135 |
| 136 @override | |
| 135 bool get isUserDefinableOperator => info.isUserDefinableOperator; | 137 bool get isUserDefinableOperator => info.isUserDefinableOperator; |
| 136 | 138 |
| 139 @override | |
| 137 analyzer.TokenType get type => info; | 140 analyzer.TokenType get type => info; |
| 138 | 141 |
| 142 @override | |
| 139 int get offset => charOffset; | 143 int get offset => charOffset; |
| 144 | |
| 145 @override | |
| 146 set offset(int newOffset) { | |
| 147 charOffset = newOffset; | |
| 148 } | |
| 149 | |
| 150 @override | |
| 151 int get length => charCount; | |
| 152 | |
| 153 @override | |
| 154 int get end => charEnd; | |
| 155 | |
| 156 @override | |
| 157 analyzer.Token get previous => previousToken; | |
| 158 | |
| 159 @override | |
| 160 set previous(analyzer.Token newToken) { | |
| 161 previousToken = newToken as Token; | |
| 162 } | |
| 163 | |
| 164 @override | |
| 165 void applyDelta(int delta) { | |
| 166 charOffset += delta; | |
| 167 Token token = precedingComments; | |
| 168 while (token != null) { | |
| 169 token.applyDelta(delta); | |
| 170 token = token.next; | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 @override | |
| 175 analyzer.Token copy() { | |
| 176 return copyWithoutComments() | |
| 177 ..precedingComments = copyComments(precedingComments) as Token; | |
|
ahe
2017/03/20 12:32:48
Could you remove the casts from this file? As far
| |
| 178 } | |
| 179 | |
| 180 @override | |
| 181 analyzer.Token copyComments(analyzer.Token token) { | |
| 182 if (token == null) { | |
| 183 return null; | |
| 184 } | |
| 185 Token head = token.copy(); | |
| 186 Token tail = head; | |
| 187 token = token.next; | |
| 188 while (token != null) { | |
| 189 tail = tail.setNext(token.copy()); | |
| 190 token = token.next; | |
| 191 } | |
| 192 return head; | |
| 193 } | |
| 194 | |
| 195 /// Return a copy of the receiver without [preceedingComments]. | |
| 196 Token copyWithoutComments(); | |
| 197 | |
| 198 @override | |
| 199 bool get isSynthetic => charCount == 0; | |
| 200 | |
| 201 @override | |
| 202 analyzer.Keyword get keyword => null; | |
| 203 | |
| 204 @override | |
| 205 bool matchesAny(List<analyzer.TokenType> types) { | |
| 206 for (analyzer.TokenType type in types) { | |
| 207 if (this.type == type) { | |
| 208 return true; | |
| 209 } | |
| 210 } | |
| 211 return false; | |
| 212 } | |
| 213 | |
| 214 @override | |
| 215 analyzer.Token setNext(analyzer.Token token) { | |
| 216 next = token as Token; | |
| 217 next.previousToken = this; | |
| 218 return token; | |
| 219 } | |
| 220 | |
| 221 @override | |
| 222 analyzer.Token setNextWithoutSettingPrevious(analyzer.Token token) { | |
| 223 next = token as Token; | |
| 224 return token; | |
| 225 } | |
| 226 | |
| 227 @override | |
| 228 Object value() => lexeme; | |
| 140 } | 229 } |
| 141 | 230 |
| 142 /** | 231 /** |
| 143 * A [SymbolToken] represents the symbol in its precedence info. | 232 * A [SymbolToken] represents the symbol in its precedence info. |
| 144 * Also used for end of file with EOF_INFO. | 233 * Also used for end of file with EOF_INFO. |
| 145 */ | 234 */ |
| 146 class SymbolToken extends Token { | 235 class SymbolToken extends Token { |
| 147 final PrecedenceInfo info; | 236 final PrecedenceInfo info; |
| 148 | 237 |
| 149 SymbolToken(this.info, int charOffset) : super(charOffset); | 238 SymbolToken(this.info, int charOffset) : super(charOffset); |
| 150 | 239 |
| 151 String get lexeme => info.value; | 240 String get lexeme => info.value; |
| 152 | 241 |
| 153 String get stringValue => info.value; | 242 String get stringValue => info.value; |
| 154 | 243 |
| 155 bool isIdentifier() => false; | 244 bool isIdentifier() => false; |
| 156 | 245 |
| 157 String toString() => "SymbolToken($lexeme)"; | 246 String toString() => "SymbolToken($lexeme)"; |
| 158 | 247 |
| 159 bool get isEof => info == EOF_INFO; | 248 bool get isEof => info == EOF_INFO; |
| 249 | |
| 250 @override | |
| 251 Token copyWithoutComments() => new SymbolToken(info, charOffset); | |
| 160 } | 252 } |
| 161 | 253 |
| 162 /** | 254 /** |
| 163 * A [BeginGroupToken] represents a symbol that may be the beginning of | 255 * A [BeginGroupToken] represents a symbol that may be the beginning of |
| 164 * a pair of brackets, i.e., ( { [ < or ${ | 256 * a pair of brackets, i.e., ( { [ < or ${ |
| 165 * The [endGroup] token points to the matching closing bracked in case | 257 * The [endGroup] token points to the matching closing bracked in case |
| 166 * it can be identified during scanning. | 258 * it can be identified during scanning. |
| 167 */ | 259 */ |
| 168 class BeginGroupToken extends SymbolToken { | 260 class BeginGroupToken extends SymbolToken { |
| 169 Token endGroup; | 261 Token endGroup; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 190 | 282 |
| 191 bool get isPseudo => keyword.isPseudo; | 283 bool get isPseudo => keyword.isPseudo; |
| 192 | 284 |
| 193 bool get isBuiltInIdentifier { | 285 bool get isBuiltInIdentifier { |
| 194 // TODO(ahe): Remove special case for "deferred" once dartbug.com/29069 is | 286 // TODO(ahe): Remove special case for "deferred" once dartbug.com/29069 is |
| 195 // fixed. | 287 // fixed. |
| 196 return keyword.isBuiltIn || identical("deferred", lexeme); | 288 return keyword.isBuiltIn || identical("deferred", lexeme); |
| 197 } | 289 } |
| 198 | 290 |
| 199 String toString() => "KeywordToken($lexeme)"; | 291 String toString() => "KeywordToken($lexeme)"; |
| 292 | |
| 293 @override | |
| 294 Token copyWithoutComments() => new KeywordToken(keyword, charOffset); | |
| 295 | |
| 296 @override | |
| 297 Object value() => keyword; | |
| 200 } | 298 } |
| 201 | 299 |
| 202 /** | 300 /** |
| 203 * A String-valued token. Represents identifiers, string literals, | 301 * A String-valued token. Represents identifiers, string literals, |
| 204 * number literals, comments, and error tokens, using the corresponding | 302 * number literals, comments, and error tokens, using the corresponding |
| 205 * precedence info. | 303 * precedence info. |
| 206 */ | 304 */ |
| 207 class StringToken extends Token { | 305 class StringToken extends Token { |
| 208 /** | 306 /** |
| 209 * The length threshold above which substring tokens are computed lazily. | 307 * The length threshold above which substring tokens are computed lazily. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 bool asciiOnly, int charOffset) | 353 bool asciiOnly, int charOffset) |
| 256 : super(charOffset) { | 354 : super(charOffset) { |
| 257 int length = end - start; | 355 int length = end - start; |
| 258 if (length <= LAZY_THRESHOLD) { | 356 if (length <= LAZY_THRESHOLD) { |
| 259 valueOrLazySubstring = decodeUtf8(data, start, end, asciiOnly); | 357 valueOrLazySubstring = decodeUtf8(data, start, end, asciiOnly); |
| 260 } else { | 358 } else { |
| 261 valueOrLazySubstring = new LazySubstring(data, start, length, asciiOnly); | 359 valueOrLazySubstring = new LazySubstring(data, start, length, asciiOnly); |
| 262 } | 360 } |
| 263 } | 361 } |
| 264 | 362 |
| 363 StringToken._(this.info, this.valueOrLazySubstring, int charOffset) | |
|
ahe
2017/03/20 12:32:48
I'd prefer a non-private name for this.
| |
| 364 : super(charOffset); | |
| 365 | |
| 265 String get lexeme { | 366 String get lexeme { |
| 266 if (valueOrLazySubstring is String) { | 367 if (valueOrLazySubstring is String) { |
| 267 return valueOrLazySubstring; | 368 return valueOrLazySubstring; |
| 268 } else { | 369 } else { |
| 269 assert(valueOrLazySubstring is LazySubstring); | 370 assert(valueOrLazySubstring is LazySubstring); |
| 270 var data = valueOrLazySubstring.data; | 371 var data = valueOrLazySubstring.data; |
| 271 int start = valueOrLazySubstring.start; | 372 int start = valueOrLazySubstring.start; |
| 272 int end = start + valueOrLazySubstring.length; | 373 int end = start + valueOrLazySubstring.length; |
| 273 if (data is String) { | 374 if (data is String) { |
| 274 valueOrLazySubstring = canonicalizedString( | 375 valueOrLazySubstring = canonicalizedString( |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 292 | 393 |
| 293 static String canonicalizedString( | 394 static String canonicalizedString( |
| 294 String s, int start, int end, bool canonicalize) { | 395 String s, int start, int end, bool canonicalize) { |
| 295 if (!canonicalize) return s; | 396 if (!canonicalize) return s; |
| 296 return canonicalizer.canonicalize(s, start, end, false); | 397 return canonicalizer.canonicalize(s, start, end, false); |
| 297 } | 398 } |
| 298 | 399 |
| 299 static String decodeUtf8(List<int> data, int start, int end, bool asciiOnly) { | 400 static String decodeUtf8(List<int> data, int start, int end, bool asciiOnly) { |
| 300 return canonicalizer.canonicalize(data, start, end, asciiOnly); | 401 return canonicalizer.canonicalize(data, start, end, asciiOnly); |
| 301 } | 402 } |
| 403 | |
| 404 @override | |
| 405 Token copyWithoutComments() => | |
| 406 new StringToken._(info, valueOrLazySubstring, charOffset); | |
| 302 } | 407 } |
| 303 | 408 |
| 304 /** | 409 /** |
| 305 * This class represents the necessary information to compute a substring | 410 * This class represents the necessary information to compute a substring |
| 306 * lazily. The substring can either originate from a string or from | 411 * lazily. The substring can either originate from a string or from |
| 307 * a [:List<int>:] of UTF-8 bytes. | 412 * a [:List<int>:] of UTF-8 bytes. |
| 308 */ | 413 */ |
| 309 abstract class LazySubstring { | 414 abstract class LazySubstring { |
| 310 /** The original data, either a string or a List<int> */ | 415 /** The original data, either a string or a List<int> */ |
| 311 get data; | 416 get data; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 identical(value, "<=") || | 495 identical(value, "<=") || |
| 391 identical(value, "<") || | 496 identical(value, "<") || |
| 392 identical(value, "&") || | 497 identical(value, "&") || |
| 393 identical(value, "^") || | 498 identical(value, "^") || |
| 394 identical(value, "|"); | 499 identical(value, "|"); |
| 395 } | 500 } |
| 396 | 501 |
| 397 bool isTernaryOperator(String value) => identical(value, "[]="); | 502 bool isTernaryOperator(String value) => identical(value, "[]="); |
| 398 | 503 |
| 399 bool isMinusOperator(String value) => identical(value, "-"); | 504 bool isMinusOperator(String value) => identical(value, "-"); |
| OLD | NEW |