Chromium Code Reviews| Index: runtime/lib/string_patch.dart |
| diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart |
| index 9d938c5b8d13e2bea417c68297960fac72e78eb3..e5e169d390956bffd007b2ec2fd8a58f5663674e 100644 |
| --- a/runtime/lib/string_patch.dart |
| +++ b/runtime/lib/string_patch.dart |
| @@ -87,6 +87,13 @@ class _StringBase { |
| int get hashCode native "String_getHashCode"; |
| + bool get _isOneByte { |
| + // Alternatively return false and override it on one-byte string classes. |
| + int id = ClassID.getID(this); |
| + return id == ClassID.cidOneByteString || |
| + id == ClassID.cidExternalOneByteString; |
| + } |
| + |
| /** |
| * Create the most efficient string representation for specified |
| * [charCodes]. |
| @@ -559,9 +566,7 @@ class _StringBase { |
| if (startIndex is! int) { |
| throw new ArgumentError("${startIndex} is not an int"); |
| } |
| - if ((startIndex < 0) || (startIndex > this.length)) { |
| - throw new RangeError.range(startIndex, 0, this.length); |
| - } |
| + RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); |
| Iterator iterator = |
| startIndex == 0 ? pattern.allMatches(this).iterator |
| : pattern.allMatches(this, startIndex).iterator; |
| @@ -608,15 +613,12 @@ class _StringBase { |
| } |
| } |
| length += _addReplaceSlice(matches, startIndex, this.length); |
| - bool replacementIsOneByte = (replacement is _OneByteString) || |
| - (replacement is _ExternalOneByteString); |
| - if (replacementIsOneByte && length < _maxJoinReplaceOneByteStringLength) { |
| + bool replacementIsOneByte = replacement._isOneByte; |
| + if (replacementIsOneByte && |
| + length < _maxJoinReplaceOneByteStringLength && |
| + this._isOneByte) { |
| // TODO(lrn): Is there a cut-off point, or is runtime always faster? |
| - bool thisIsOneByte = (this is _OneByteString) || |
| - (this is _ExternalOneByteString); |
| - if (replacementIsOneByte && thisIsOneByte) { |
| - return _joinReplaceAllOneByteResult(this, matches, length); |
| - } |
| + return _joinReplaceAllOneByteResult(this, matches, length); |
| } |
| return _joinReplaceAllResult(this, matches, length, |
| replacementIsOneByte); |
| @@ -688,20 +690,18 @@ class _StringBase { |
| bool replacementStringsAreOneByte = true; |
| for (Match match in pattern.allMatches(this)) { |
| length += _addReplaceSlice(matches, startIndex, match.start); |
| - String replacement = replace(match).toString(); |
| + String replacement = "${replace(match)}"; |
|
Ivan Posva
2015/02/11 22:45:40
Why this change? All it does is add string interpo
Lasse Reichstein Nielsen
2015/02/12 09:17:16
The interpolation also throws if the result of rep
|
| matches.add(replacement); |
| length += replacement.length; |
| - replacementStringsAreOneByte = replacementStringsAreOneByte && |
| - (replacement is _OneByteString || |
| - replacement is _ExternalOneByteString); |
| + replacementStringsAreOneByte = |
| + replacementStringsAreOneByte && replacement._isOneByte; |
| startIndex = match.end; |
| } |
| + if (matches.isEmpty) return this; |
| length += _addReplaceSlice(matches, startIndex, this.length); |
| if (replacementStringsAreOneByte && |
| length < _maxJoinReplaceOneByteStringLength) { |
| - bool thisIsOneByte = (this is _OneByteString) || |
| - (this is _ExternalOneByteString); |
| - if (thisIsOneByte) { |
| + if (this._isOneByte) { |
| return _joinReplaceAllOneByteResult(this, matches, length); |
| } |
| } |
| @@ -709,6 +709,31 @@ class _StringBase { |
| replacementStringsAreOneByte); |
| } |
| + String replaceFirstMapped(Pattern pattern, String replace(Match match), |
| + [int startIndex = 0]) { |
| + if (pattern == null) throw new ArgumentError.notNull("pattern"); |
| + if (replace == null) throw new ArgumentError.notNull("replace"); |
| + if (startIndex == null) throw new ArgumentError.notNull("startIndex"); |
| + RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex"); |
| + |
| + var matches = pattern.allMatches(this, startIndex).iterator; |
|
floitsch
2015/02/11 11:49:14
replace var with types.
Ivan Posva
2015/02/11 22:45:40
var is just fine in method bodies.
Lasse Reichstein Nielsen
2015/02/12 09:17:16
Keeping as-is in VM libraries.
|
| + if (!matches.moveNext()) return this; |
| + var match = matches.current; |
| + String replacement = "${replace(match)}"; |
|
Ivan Posva
2015/02/11 22:45:40
ditto as in:
var replacement = replace(match).toSt
Lasse Reichstein Nielsen
2015/02/12 09:17:16
Kept as interpolation, but changed "String" to "va
|
| + var slices = []; |
| + int length = 0; |
| + if (match.start > 0) { |
| + length += _addReplaceSlice(slices, 0, match.start); |
| + } |
| + slices.add(replacement); |
| + length += replacement.length; |
| + if (match.end < this.length) { |
| + length += _addReplaceSlice(slices, match.end, this.length); |
| + } |
| + return _joinReplaceAllResult(this, slices, length, |
|
Ivan Posva
2015/02/11 22:45:40
Why is there not the cutout for this being a one b
Lasse Reichstein Nielsen
2015/02/12 09:17:16
Good point, will add.
The cut-off length might be
|
| + replacement._isOneByte); |
| + } |
| + |
| static String _matchString(Match match) => match[0]; |
| static String _stringIdentity(String string) => string; |