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

Side by Side Diff: tool/input_sdk/private/js_string.dart

Issue 1950133003: Update String methods. (Closed) Base URL: https://github.com/dart-lang/dev_compiler@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « tool/input_sdk/private/js_rti.dart ('k') | tool/input_sdk/private/string_helper.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of dart._interceptors; 5 part of dart._interceptors;
6 6
7 /** 7 /**
8 * The interceptor class for [String]. The compiler recognizes this 8 * The interceptor class for [String]. The compiler recognizes this
9 * class as an interceptor, and changes references to [:this:] to 9 * class as an interceptor, and changes references to [:this:] to
10 * actually use the receiver of the method, which is generated as an extra 10 * actually use the receiver of the method, which is generated as an extra
11 * argument added to each member. 11 * argument added to each member.
12 */ 12 */
13 @JsPeerInterface(name: 'String') 13 @JsPeerInterface(name: 'String')
14 class JSString extends Interceptor implements String, JSIndexable { 14 class JSString extends Interceptor implements String, JSIndexable {
15 const JSString(); 15 const JSString();
16 16
17 int codeUnitAt(int index) { 17 int codeUnitAt(int index) {
18 if (index is !int) throw new ArgumentError(index); 18 if (index is !int) throw diagnoseIndexError(this, index);
19 if (index < 0) throw new RangeError.value(index); 19 if (index < 0) throw diagnoseIndexError(this, index);
20 if (index >= length) throw new RangeError.value(index); 20 if (index >= length) throw diagnoseIndexError(this, index);
21 return JS('int', r'#.charCodeAt(#)', this, index); 21 return JS('int', r'#.charCodeAt(#)', this, index);
22 } 22 }
23 23
24 Iterable<Match> allMatches(String string, [int start = 0]) { 24 Iterable<Match> allMatches(String string, [int start = 0]) {
25 checkString(string); 25 checkString(string);
26 checkInt(start); 26 checkInt(start);
27 if (0 > start || start > string.length) { 27 if (0 > start || start > string.length) {
28 throw new RangeError.range(start, 0, string.length); 28 throw new RangeError.range(start, 0, string.length);
29 } 29 }
30 return allMatchesInStringUnchecked(this, string, start); 30 return allMatchesInStringUnchecked(this, string, start);
31 } 31 }
32 32
33 Match matchAsPrefix(String string, [int start = 0]) { 33 Match matchAsPrefix(String string, [int start = 0]) {
34 if (start < 0 || start > string.length) { 34 if (start < 0 || start > string.length) {
35 throw new RangeError.range(start, 0, string.length); 35 throw new RangeError.range(start, 0, string.length);
36 } 36 }
37 if (start + this.length > string.length) return null; 37 if (start + this.length > string.length) return null;
38 // TODO(lrn): See if this can be optimized. 38 // TODO(lrn): See if this can be optimized.
39 for (int i = 0; i < this.length; i++) { 39 for (int i = 0; i < this.length; i++) {
40 if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) { 40 if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) {
41 return null; 41 return null;
42 } 42 }
43 } 43 }
44 return new StringMatch(start, string, this); 44 return new StringMatch(start, string, this);
45 } 45 }
46 46
47 String operator +(String other) { 47 String operator +(String other) {
48 if (other is !String) throw new ArgumentError(other); 48 if (other is !String) throw new ArgumentError.value(other);
49 return JS('String', r'# + #', this, other); 49 return JS('String', r'# + #', this, other);
50 } 50 }
51 51
52 bool endsWith(String other) { 52 bool endsWith(String other) {
53 checkString(other); 53 checkString(other);
54 int otherLength = other.length; 54 int otherLength = other.length;
55 if (otherLength > length) return false; 55 if (otherLength > length) return false;
56 return other == substring(length - otherLength); 56 return other == substring(length - otherLength);
57 } 57 }
58 58
59 String replaceAll(Pattern from, String to) { 59 String replaceAll(Pattern from, String to) {
60 checkString(to); 60 checkString(to);
61 return stringReplaceAllUnchecked(this, from, to); 61 return stringReplaceAllUnchecked(this, from, to);
62 } 62 }
63 63
64 String replaceAllMapped(Pattern from, String convert(Match match)) { 64 String replaceAllMapped(Pattern from, String convert(Match match)) {
65 return this.splitMapJoin(from, onMatch: convert); 65 return this.splitMapJoin(from, onMatch: convert);
66 } 66 }
67 67
68 String splitMapJoin(Pattern from, 68 String splitMapJoin(Pattern from,
69 {String onMatch(Match match), 69 {String onMatch(Match match),
70 String onNonMatch(String nonMatch)}) { 70 String onNonMatch(String nonMatch)}) {
71 return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch); 71 return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch);
72 } 72 }
73 73
74 String replaceFirst(Pattern from, String to, [int startIndex = 0]) { 74 String replaceFirst(Pattern from, String to, [int startIndex = 0]) {
75 checkString(to); 75 checkString(to);
76 checkInt(startIndex); 76 checkInt(startIndex);
77 if (startIndex < 0 || startIndex > this.length) { 77 RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
78 throw new RangeError.range(startIndex, 0, this.length);
79 }
80 return stringReplaceFirstUnchecked(this, from, to, startIndex); 78 return stringReplaceFirstUnchecked(this, from, to, startIndex);
81 } 79 }
82 80
81 String replaceFirstMapped(Pattern from, String replace(Match match),
82 [int startIndex = 0]) {
83 checkNull(replace);
84 checkInt(startIndex);
85 RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
86 return stringReplaceFirstMappedUnchecked(this, from, replace, startIndex);
87 }
88
83 List<String> split(Pattern pattern) { 89 List<String> split(Pattern pattern) {
84 checkNull(pattern); 90 checkNull(pattern);
85 if (pattern is String) { 91 if (pattern is String) {
86 return JS('JSExtendableArray', r'#.split(#)', this, pattern); 92 return JS('JSExtendableArray', r'#.split(#)', this, pattern);
87 } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) { 93 } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) {
88 var re = regExpGetNative(pattern); 94 var re = regExpGetNative(pattern);
89 return JS('JSExtendableArray', r'#.split(#)', this, re); 95 return JS('JSExtendableArray', r'#.split(#)', this, re);
90 } else { 96 } else {
91 return _defaultSplit(pattern); 97 return _defaultSplit(pattern);
92 } 98 }
93 } 99 }
94 100
101 String replaceRange(int start, int end, String replacement) {
102 checkString(replacement);
103 checkInt(start);
104 end = RangeError.checkValidRange(start, end, this.length);
105 checkInt(end);
106 return stringReplaceRangeUnchecked(this, start, end, replacement);
107 }
108
95 List<String> _defaultSplit(Pattern pattern) { 109 List<String> _defaultSplit(Pattern pattern) {
96 List<String> result = <String>[]; 110 List<String> result = <String>[];
97 // End of most recent match. That is, start of next part to add to result. 111 // End of most recent match. That is, start of next part to add to result.
98 int start = 0; 112 int start = 0;
99 // Length of most recent match. 113 // Length of most recent match.
100 // Set >0, so no match on the empty string causes the result to be [""]. 114 // Set >0, so no match on the empty string causes the result to be [""].
101 int length = 1; 115 int length = 1;
102 for (var match in pattern.allMatches(this)) { 116 for (var match in pattern.allMatches(this)) {
103 int matchStart = match.start; 117 int matchStart = match.start;
104 int matchEnd = match.end; 118 int matchEnd = match.end;
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 if (delta <= 0) return this; 373 if (delta <= 0) return this;
360 return this + padding * delta; 374 return this + padding * delta;
361 } 375 }
362 376
363 List<int> get codeUnits => new _CodeUnits(this); 377 List<int> get codeUnits => new _CodeUnits(this);
364 378
365 Runes get runes => new Runes(this); 379 Runes get runes => new Runes(this);
366 380
367 int indexOf(Pattern pattern, [int start = 0]) { 381 int indexOf(Pattern pattern, [int start = 0]) {
368 checkNull(pattern); 382 checkNull(pattern);
369 if (start is! int) throw new ArgumentError(start); 383 if (start is! int) throw argumentErrorValue(start);
370 if (start < 0 || start > this.length) { 384 if (start < 0 || start > this.length) {
371 throw new RangeError.range(start, 0, this.length); 385 throw new RangeError.range(start, 0, this.length);
372 } 386 }
373 if (pattern is String) { 387 if (pattern is String) {
374 return JS('int', r'#.indexOf(#, #)', this, pattern, start); 388 return stringIndexOfStringUnchecked(this, pattern, start);
375 } 389 }
376 if (pattern is JSSyntaxRegExp) { 390 if (pattern is JSSyntaxRegExp) {
377 JSSyntaxRegExp re = pattern; 391 JSSyntaxRegExp re = pattern;
378 Match match = firstMatchAfter(re, this, start); 392 Match match = firstMatchAfter(re, this, start);
379 return (match == null) ? -1 : match.start; 393 return (match == null) ? -1 : match.start;
380 } 394 }
381 for (int i = start; i <= this.length; i++) { 395 for (int i = start; i <= this.length; i++) {
382 if (pattern.matchAsPrefix(this, i) != null) return i; 396 if (pattern.matchAsPrefix(this, i) != null) return i;
383 } 397 }
384 return -1; 398 return -1;
385 } 399 }
386 400
387 int lastIndexOf(Pattern pattern, [int start]) { 401 int lastIndexOf(Pattern pattern, [int start]) {
388 checkNull(pattern); 402 checkNull(pattern);
389 if (start == null) { 403 if (start == null) {
390 start = length; 404 start = length;
391 } else if (start is! int) { 405 } else if (start is! int) {
392 throw new ArgumentError(start); 406 throw argumentErrorValue(start);
393 } else if (start < 0 || start > this.length) { 407 } else if (start < 0 || start > this.length) {
394 throw new RangeError.range(start, 0, this.length); 408 throw new RangeError.range(start, 0, this.length);
395 } 409 }
396 if (pattern is String) { 410 if (pattern is String) {
397 String other = pattern; 411 String other = pattern;
398 if (start + other.length > this.length) { 412 if (start + other.length > this.length) {
399 start = this.length - other.length; 413 start = this.length - other.length;
400 } 414 }
401 return stringLastIndexOfUnchecked(this, other, start); 415 return stringLastIndexOfUnchecked(this, other, start);
402 } 416 }
403 for (int i = start; i >= 0; i--) { 417 for (int i = start; i >= 0; i--) {
404 if (pattern.matchAsPrefix(this, i) != null) return i; 418 if (pattern.matchAsPrefix(this, i) != null) return i;
405 } 419 }
406 return -1; 420 return -1;
407 } 421 }
408 422
409 bool contains(Pattern other, [int startIndex = 0]) { 423 bool contains(Pattern other, [int startIndex = 0]) {
410 checkNull(other); 424 checkNull(other);
411 if (startIndex < 0 || startIndex > this.length) { 425 if (startIndex < 0 || startIndex > this.length) {
412 throw new RangeError.range(startIndex, 0, this.length); 426 throw new RangeError.range(startIndex, 0, this.length);
413 } 427 }
414 return stringContainsUnchecked(this, other, startIndex); 428 return stringContainsUnchecked(this, other, startIndex);
415 } 429 }
416 430
417 bool get isEmpty => length == 0; 431 bool get isEmpty => length == 0;
418 432
419 bool get isNotEmpty => !isEmpty; 433 bool get isNotEmpty => !isEmpty;
420 434
421 int compareTo(String other) { 435 int compareTo(String other) {
422 if (other is !String) throw new ArgumentError(other); 436 if (other is !String) throw argumentErrorValue(other);
423 return this == other ? 0 437 return this == other ? 0
424 : JS('bool', r'# < #', this, other) ? -1 : 1; 438 : JS('bool', r'# < #', this, other) ? -1 : 1;
425 } 439 }
426 440
427 // Note: if you change this, also change the function [S]. 441 // Note: if you change this, also change the function [S].
428 String toString() => this; 442 String toString() => this;
429 443
430 /** 444 /**
431 * This is the [Jenkins hash function][1] but using masking to keep 445 * This is the [Jenkins hash function][1] but using masking to keep
432 * values in SMI range. 446 * values in SMI range.
433 * 447 *
434 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function 448 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
(...skipping 10 matching lines...) Expand all
445 hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); 459 hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
446 hash = JS('int', '# ^ (# >> 11)', hash, hash); 460 hash = JS('int', '# ^ (# >> 11)', hash, hash);
447 return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); 461 return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
448 } 462 }
449 463
450 Type get runtimeType => String; 464 Type get runtimeType => String;
451 465
452 int get length => JS('int', r'#.length', this); 466 int get length => JS('int', r'#.length', this);
453 467
454 String operator [](int index) { 468 String operator [](int index) {
455 if (index is !int) throw new ArgumentError(index); 469 if (index is !int) throw diagnoseIndexError(this, index);
456 if (index >= length || index < 0) throw new RangeError.value(index); 470 if (index >= length || index < 0) throw diagnoseIndexError(this, index);
457 return JS('String', '#[#]', this, index); 471 return JS('String', '#[#]', this, index);
458 } 472 }
459 } 473 }
460 474
461 /** 475 /**
462 * An [Iterable] of the UTF-16 code units of a [String] in index order. 476 * An [Iterable] of the UTF-16 code units of a [String] in index order.
463 */ 477 */
464 class _CodeUnits extends UnmodifiableListBase<int> { 478 class _CodeUnits extends UnmodifiableListBase<int> {
465 /** The string that this is the code units of. */ 479 /** The string that this is the code units of. */
466 String _string; 480 String _string;
467 481
468 _CodeUnits(this._string); 482 _CodeUnits(this._string);
469 483
470 int get length => _string.length; 484 int get length => _string.length;
471 int operator[](int i) => _string.codeUnitAt(i); 485 int operator[](int i) => _string.codeUnitAt(i);
472 } 486 }
OLDNEW
« no previous file with comments | « tool/input_sdk/private/js_rti.dart ('k') | tool/input_sdk/private/string_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698