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 'dart:collection' show | 7 import 'dart:collection' show |
| 8 HashSet; | 8 HashSet; |
| 9 | 9 |
| 10 import 'dart:convert' show | 10 import 'dart:convert' show |
| 11 UTF8; | 11 UTF8; |
| 12 | 12 |
| 13 import 'keyword.dart' show | 13 import 'keyword.dart' show |
| 14 Keyword; | 14 Keyword; |
| 15 | 15 |
| 16 import 'precedence.dart' show | 16 import 'precedence.dart' show |
| 17 BAD_INPUT_INFO, | 17 BAD_INPUT_INFO, |
| 18 EOF_INFO, | 18 EOF_INFO, |
| 19 PrecedenceInfo; | 19 PrecedenceInfo; |
| 20 | 20 |
| 21 import 'token_constants.dart' show | 21 import 'token_constants.dart' show |
| 22 IDENTIFIER_TOKEN; | 22 IDENTIFIER_TOKEN; |
| 23 | 23 |
| 24 import 'canonicalizer.dart'; | |
| 25 | |
| 24 /** | 26 /** |
| 25 * A token that doubles as a linked list. | 27 * A token that doubles as a linked list. |
| 26 */ | 28 */ |
| 27 abstract class Token { | 29 abstract class Token { |
| 28 /** | 30 /** |
| 29 * The character offset of the start of this token within the source text. | 31 * The character offset of the start of this token within the source text. |
| 30 */ | 32 */ |
| 31 final int charOffset; | 33 final int charOffset; |
| 32 | 34 |
| 33 Token(this.charOffset); | 35 Token(this.charOffset); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 var /* String | LazySubtring */ valueOrLazySubstring; | 190 var /* String | LazySubtring */ valueOrLazySubstring; |
| 189 | 191 |
| 190 final PrecedenceInfo info; | 192 final PrecedenceInfo info; |
| 191 | 193 |
| 192 /** | 194 /** |
| 193 * Creates a non-lazy string token. If [canonicalize] is true, the string | 195 * Creates a non-lazy string token. If [canonicalize] is true, the string |
| 194 * is canonicalized before the token is created. | 196 * is canonicalized before the token is created. |
| 195 */ | 197 */ |
| 196 StringToken.fromString(this.info, String value, int charOffset, | 198 StringToken.fromString(this.info, String value, int charOffset, |
| 197 {bool canonicalize: false}) | 199 {bool canonicalize: false}) |
| 198 : valueOrLazySubstring = canonicalizedString(value, canonicalize), | 200 : valueOrLazySubstring = canonicalizedString(value, |
| 201 0, value.length, canonicalize), | |
| 199 super(charOffset); | 202 super(charOffset); |
| 200 | 203 |
| 201 /** | 204 /** |
| 202 * Creates a lazy string token. If [canonicalize] is true, the string | 205 * Creates a lazy string token. If [canonicalize] is true, the string |
| 203 * is canonicalized before the token is created. | 206 * is canonicalized before the token is created. |
| 204 */ | 207 */ |
| 205 StringToken.fromSubstring( | 208 StringToken.fromSubstring( |
| 206 this.info, String data, int start, int end, int charOffset, | 209 this.info, String data, int start, int end, int charOffset, |
| 207 {bool canonicalize: false}) | 210 {bool canonicalize: false}) |
| 208 : super(charOffset) { | 211 : super(charOffset) { |
| 209 int length = end - start; | 212 int length = end - start; |
| 210 if (length <= LAZY_THRESHOLD) { | 213 if (length <= LAZY_THRESHOLD) { |
| 211 valueOrLazySubstring = | 214 valueOrLazySubstring = |
| 212 canonicalizedString(data.substring(start, end), canonicalize); | 215 canonicalizedString(data, start, end, canonicalize); |
| 213 } else { | 216 } else { |
| 214 valueOrLazySubstring = | 217 valueOrLazySubstring = |
| 215 new LazySubstring(data, start, length, canonicalize); | 218 new LazySubstring(data, start, length, canonicalize); |
| 216 } | 219 } |
| 217 } | 220 } |
| 218 | 221 |
| 219 /** | 222 /** |
| 220 * Creates a lazy string token. If [asciiOnly] is false, the byte array | 223 * Creates a lazy string token. If [asciiOnly] is false, the byte array |
| 221 * is passed through a UTF-8 decoder. | 224 * is passed through a UTF-8 decoder. |
| 222 */ | 225 */ |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 234 String get value { | 237 String get value { |
| 235 if (valueOrLazySubstring is String) { | 238 if (valueOrLazySubstring is String) { |
| 236 return valueOrLazySubstring; | 239 return valueOrLazySubstring; |
| 237 } else { | 240 } else { |
| 238 assert(valueOrLazySubstring is LazySubstring); | 241 assert(valueOrLazySubstring is LazySubstring); |
| 239 var data = valueOrLazySubstring.data; | 242 var data = valueOrLazySubstring.data; |
| 240 int start = valueOrLazySubstring.start; | 243 int start = valueOrLazySubstring.start; |
| 241 int end = start + valueOrLazySubstring.length; | 244 int end = start + valueOrLazySubstring.length; |
| 242 if (data is String) { | 245 if (data is String) { |
| 243 valueOrLazySubstring = canonicalizedString( | 246 valueOrLazySubstring = canonicalizedString( |
| 244 data.substring(start, end), valueOrLazySubstring.boolValue); | 247 data, start, end, valueOrLazySubstring.boolValue); |
| 245 } else { | 248 } else { |
| 246 valueOrLazySubstring = | 249 valueOrLazySubstring = |
| 247 decodeUtf8(data, start, end, valueOrLazySubstring.boolValue); | 250 decodeUtf8(data, start, end, valueOrLazySubstring.boolValue); |
| 248 } | 251 } |
| 249 return valueOrLazySubstring; | 252 return valueOrLazySubstring; |
| 250 } | 253 } |
| 251 } | 254 } |
| 252 | 255 |
| 253 /// See [Token.stringValue] for an explanation. | 256 /// See [Token.stringValue] for an explanation. |
| 254 String get stringValue => null; | 257 String get stringValue => null; |
| 255 | 258 |
| 256 bool isIdentifier() => identical(kind, IDENTIFIER_TOKEN); | 259 bool isIdentifier() => identical(kind, IDENTIFIER_TOKEN); |
| 257 | 260 |
| 258 String toString() => "StringToken($value)"; | 261 String toString() => "StringToken($value)"; |
| 259 | 262 |
| 260 static final HashSet<String> canonicalizedSubstrings = new HashSet<String>(); | 263 static final StringCanonicalizer canonicalizer = new StringCanonicalizer(); |
| 261 | 264 |
| 262 static String canonicalizedString(String s, bool canonicalize) { | 265 static String canonicalizedString(String s, int start, int end, bool canonical ize) { |
|
ahe
2017/02/14 14:35:04
Long line.
| |
| 263 if (!canonicalize) return s; | 266 if (!canonicalize) return s; |
| 264 var result = canonicalizedSubstrings.lookup(s); | 267 return canonicalizer.canonicalize(s, start, end, false); |
| 265 if (result != null) return result; | |
| 266 canonicalizedSubstrings.add(s); | |
| 267 return s; | |
| 268 } | 268 } |
| 269 | 269 |
| 270 static String decodeUtf8(List<int> data, int start, int end, bool asciiOnly) { | 270 static String decodeUtf8(List<int> data, int start, int end, bool asciiOnly) { |
| 271 var s; | 271 return canonicalizer.canonicalize(data, start, end, asciiOnly); |
| 272 if (asciiOnly) { | |
| 273 s = new String.fromCharCodes(data, start, end); | |
| 274 } else { | |
| 275 s = UTF8.decoder.convert(data, start, end); | |
| 276 } | |
| 277 return canonicalizedString(s, true); | |
| 278 } | 272 } |
| 279 } | 273 } |
| 280 | 274 |
| 281 /** | 275 /** |
| 282 * This class represents the necessary information to compute a substring | 276 * This class represents the necessary information to compute a substring |
| 283 * lazily. The substring can either originate from a string or from | 277 * lazily. The substring can either originate from a string or from |
| 284 * a [:List<int>:] of UTF-8 bytes. | 278 * a [:List<int>:] of UTF-8 bytes. |
| 285 */ | 279 */ |
| 286 abstract class LazySubstring { | 280 abstract class LazySubstring { |
| 287 /** The original data, either a string or a List<int> */ | 281 /** The original data, either a string or a List<int> */ |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 value == '<=' || | 361 value == '<=' || |
| 368 value == '<' || | 362 value == '<' || |
| 369 value == '&' || | 363 value == '&' || |
| 370 value == '^' || | 364 value == '^' || |
| 371 value == '|'; | 365 value == '|'; |
| 372 } | 366 } |
| 373 | 367 |
| 374 bool isTernaryOperator(String value) => value == '[]='; | 368 bool isTernaryOperator(String value) => value == '[]='; |
| 375 | 369 |
| 376 bool isMinusOperator(String value) => value == '-'; | 370 bool isMinusOperator(String value) => value == '-'; |
| OLD | NEW |