[dart] r14678 committed - Allow function as replacement argument to String.replaceAll....

1 view
Skip to first unread message

da...@googlecode.com

unread,
Nov 8, 2012, 7:57:17 AM11/8/12
to com...@dartlang.org
Revision: 14678
Author: l...@google.com
Date: Thu Nov 8 04:56:47 2012
Log: Allow function as replacement argument to String.replaceAll.

TBR=floi...@google.com

Review URL: https://codereview.chromium.org//11312144
http://code.google.com/p/dart/source/detail?r=14678

Modified:
/experimental/lib_v2/dart/runtime/lib/string_base.dart

/experimental/lib_v2/dart/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart

/experimental/lib_v2/dart/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
/experimental/lib_v2/dart/sdk/lib/core/regexp.dart
/experimental/lib_v2/dart/sdk/lib/core/string.dart
/experimental/lib_v2/dart/tests/corelib/corelib.status

=======================================
--- /experimental/lib_v2/dart/runtime/lib/string_base.dart Thu Nov 1
06:46:30 2012
+++ /experimental/lib_v2/dart/runtime/lib/string_base.dart Thu Nov 8
04:56:47 2012
@@ -210,12 +210,28 @@
return buffer.add(this.substring(startIndex)).toString();
}

- String replaceAll(Pattern pattern, String replacement) {
+ String replaceAll(Pattern pattern, var replacement) {
if (pattern is! Pattern) {
throw new ArgumentError("${pattern} is not a Pattern");
}
+ if (replacement is Function) {
+ StringBuffer buffer = new StringBuffer();
+ int startIndex = 0;
+ for (Match match in pattern.allMatches(this)) {
+ if (match.start > startIndex) {
+ buffer.add(this.substring(startIndex, match.start));
+ }
+ buffer.add(replacement(match).toString());
+ startIndex = match.end;
+ }
+ if (startIndex < this.length) {
+ buffer.add(this.substring(startIndex));
+ }
+ return buffer.toString();
+ }
if (replacement is! String) {
- throw new ArgumentError("${replacement} is not a String");
+ throw new ArgumentError(
+ "${replacement} is not a String or Match->String function");
}
StringBuffer buffer = new StringBuffer();
int startIndex = 0;
=======================================
---
/experimental/lib_v2/dart/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
Tue Nov 6 07:43:13 2012
+++
/experimental/lib_v2/dart/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
Thu Nov 8 04:56:47 2012
@@ -560,8 +560,6 @@

replaceAll(receiver, from, to) {
if (receiver is !String) return UNINTERCEPTED(receiver.replaceAll(from,
to));
-
- checkString(to);
return stringReplaceAllUnchecked(receiver, from, to);
}

=======================================
---
/experimental/lib_v2/dart/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
Thu Nov 1 06:46:30 2012
+++
/experimental/lib_v2/dart/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
Thu Nov 8 04:56:47 2012
@@ -33,7 +33,7 @@

List<Match> allMatchesInStringUnchecked(String needle, String haystack) {
// Copied from StringBase.allMatches in
- // ../../../runtime/lib/string.dart
+ // /runtime/lib/string_base.dart
List<Match> result = new List<Match>();
int length = haystack.length;
int patternLength = needle.length;
@@ -76,6 +76,10 @@
}

stringReplaceAllUnchecked(receiver, from, to) {
+ if (to is Function) {
+ return stringReplaceAllFuncUnchecked(receiver, from, to);
+ }
+ checkString(to);
if (from is String) {
if (from == "") {
if (receiver == "") {
@@ -109,6 +113,57 @@
}
}

+stringReplaceAllFuncUnchecked(receiver, pattern, replace) {
+ if (pattern is! Pattern) {
+ throw new ArgumentError("${pattern} is not a Pattern");
+ }
+ if (pattern is String) {
+ // Inline the allMatches code.
+ return stringReplaceAllStringFuncUnchecked(receiver, pattern, replace);
+ }
+ StringBuffer buffer = new StringBuffer();
+ int startIndex = 0;
+ for (Match match in pattern.allMatches(receiver)) {
+ if (startIndex < match.start) {
+ buffer.add(receiver.substring(startIndex, match.start));
+ }
+ buffer.add(replace(match).toString());
+ startIndex = match.end;
+ }
+ if (startIndex < receiver.length) {
+ buffer.add(receiver.substring(startIndex));
+ }
+ return buffer.toString();
+}
+
+stringReplaceAllStringFuncUnchecked(receiver, pattern, replace) {
+ int length = receiver.length;
+ int patternLength = pattern.length;
+ int startIndex = 0;
+ StringBuffer buffer = new StringBuffer();
+ while (true) {
+ int position = receiver.indexOf(pattern, startIndex);
+ if (position == -1) {
+ if (startIndex < length) buffer.add(receiver.substring(startIndex));
+ return buffer.toString();
+ }
+ if (startIndex < position) {
+ buffer.add(receiver.substring(startIndex, position));
+ }
+ buffer.add(
+ replace(new StringMatch(position, receiver, pattern)).toString());
+ int endIndex = position + patternLength;
+ if (endIndex == length) {
+ return buffer.toString();
+ } else if (position == endIndex) {
+ ++startIndex; // empty match, advance and restart
+ } else {
+ startIndex = endIndex;
+ }
+ }
+}
+
+
stringReplaceFirstUnchecked(receiver, from, to) {
if (from is String) {
return stringReplaceJS(receiver, from, to);
=======================================
--- /experimental/lib_v2/dart/sdk/lib/core/regexp.dart Thu Oct 25 12:31:56
2012
+++ /experimental/lib_v2/dart/sdk/lib/core/regexp.dart Thu Nov 8 04:56:47
2012
@@ -60,7 +60,7 @@
String get str;

/**
- * The pattern to search for in [str].
+ * The pattern used to search in [str].
*/
Pattern get pattern;
}
=======================================
--- /experimental/lib_v2/dart/sdk/lib/core/string.dart Tue Oct 30 07:19:57
2012
+++ /experimental/lib_v2/dart/sdk/lib/core/string.dart Thu Nov 8 04:56:47
2012
@@ -99,9 +99,14 @@

/**
* Returns a new string where all occurences of [from] in this string
- * are replaced with [to].
+ * are replaced with a [String] depending on [replace].
+ *
+ * If [replace] is a [Function], it's called with the [Match] generated
+ * by the pattern, and its result is used as replacement.
+ * Otherwise, [replace] must be a [String], which is directly used as
+ * the replacement.
*/
- String replaceAll(Pattern from, String to);
+ String replaceAll(Pattern from, var replace);

/**
* Splits the string around matches of [pattern]. Returns
=======================================
--- /experimental/lib_v2/dart/tests/corelib/corelib.status Tue Nov 6
04:16:30 2012
+++ /experimental/lib_v2/dart/tests/corelib/corelib.status Thu Nov 8
04:56:47 2012
@@ -49,6 +49,8 @@

null_nosuchmethod_test: Fail # Bug 5513

+string_replace_func_test: Skip # Bug 6554 - doesn't terminate.
+
[ $compiler == dart2js && $runtime == none ]
*: Fail, Pass # TODO(ahe): Triage these tests.

Reply all
Reply to author
Forward
0 new messages