Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: pkg/front_end/lib/src/fasta/scanner/token.dart

Issue 2696803003: Avoiding creating strings for canonicalization (Closed)
Patch Set: Fasta: avoiding allocating strings for canonicalization Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 HashCanonicalizer canonicalizer = new HashCanonicalizer();
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 13:52:46 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
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 == '-';
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698