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

Unified Diff: runtime/lib/string_patch.dart

Issue 920453002: Add String.replaceFirstMapped. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: With change to _interpolate methods. Created 5 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 side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698