| Index: runtime/lib/string_patch.dart
|
| diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
|
| index 9d938c5b8d13e2bea417c68297960fac72e78eb3..12d788deb0f98278d5081ba528379edee31e3e72 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,27 +690,54 @@ class _StringBase {
|
| bool replacementStringsAreOneByte = true;
|
| for (Match match in pattern.allMatches(this)) {
|
| length += _addReplaceSlice(matches, startIndex, match.start);
|
| - String replacement = replace(match).toString();
|
| + var replacement = "${replace(match)}";
|
| 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) {
|
| - return _joinReplaceAllOneByteResult(this, matches, length);
|
| - }
|
| + length < _maxJoinReplaceOneByteStringLength &&
|
| + this._isOneByte) {
|
| + return _joinReplaceAllOneByteResult(this, matches, length);
|
| }
|
| return _joinReplaceAllResult(this, matches, length,
|
| 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;
|
| + if (!matches.moveNext()) return this;
|
| + var match = matches.current;
|
| + var replacement = "${replace(match)}";
|
| + 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);
|
| + }
|
| + bool replacementIsOneByte = _replacement._isOneByte;
|
| + if (replacementIsOneByte &&
|
| + length < _maxJoinReplaceOneByteStringLength &&
|
| + this._isOneByte) {
|
| + return _joinReplaceAllOneByteResult(this, matches, length);
|
| + }
|
| + return _joinReplaceAllResult(this, slices, length, replacementIsOneByte);
|
| + }
|
| +
|
| static String _matchString(Match match) => match[0];
|
| static String _stringIdentity(String string) => string;
|
|
|
|
|