Re-add String.replace(CharSequence,CharSequence) with proper quoting on the
replacement string.

Patch by: jat
Review by: spoon (desk review)



git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2203 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/super/com/google/gwt/emul/java/lang/String.java b/user/super/com/google/gwt/emul/java/lang/String.java
index 92b2f45..f219c30 100644
--- a/user/super/com/google/gwt/emul/java/lang/String.java
+++ b/user/super/com/google/gwt/emul/java/lang/String.java
@@ -555,12 +555,15 @@
   }-*/;
 
   // TODO(jat): fails on Safari 2 -- to be fixed for 1.5RC1
-//  public String replace(CharSequence from, CharSequence to) {
-//    // Escape regex special characters from literal replacement string.
-//    String regex = from.toString().replaceAll("([/\\\\\\.\\*\\+\\?\\|\\(\\)\\[\\]\\{\\}])",
-//        "\\\\$1");
-//    return replaceAll(regex, to.toString());
-//  }
+  public String replace(CharSequence from, CharSequence to) {
+    // Escape regex special characters from literal replacement string.
+    String regex = from.toString().replaceAll("([/\\\\\\.\\*\\+\\?\\|\\(\\)\\[\\]\\{\\}])",
+        "\\\\$1");
+    // Escape $ since it is for match backrefs and \ since it is used to escape $.
+    String replacement = to.toString().replaceAll("\\\\", "\\\\\\\\").replaceAll("\\$",
+        "\\\\$");
+    return replaceAll(regex, replacement);
+  }
   
   /**
    * Regular expressions vary from the standard implementation. The
diff --git a/user/test/com/google/gwt/emultest/java/lang/StringTest.java b/user/test/com/google/gwt/emultest/java/lang/StringTest.java
index 48dcb5c..dbd2aa8 100644
--- a/user/test/com/google/gwt/emultest/java/lang/StringTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/StringTest.java
@@ -326,15 +326,15 @@
     assertEquals("dog food", dogFood.replace('\u0120', ' '));
     String testStr = String.valueOf(new char[] {'\u1111', 'B', '\u1111', 'B', '\u1111', 'B'});
     assertEquals("ABABAB", testStr.replace('\u1111', 'A'));
-//    assertEquals("foobar", hideFromCompiler("bazbar").replace("baz", "foo"));
-//    assertEquals("$0bar", hideFromCompiler("foobar").replace("foo", "$0"));
-//    assertEquals("+1", hideFromCompiler("*[)1").replace("*[)", "+"));
   }
 
   public void testReplaceAll() {
     String regex = hideFromCompiler("*[").replaceAll("([/\\\\\\.\\*\\+\\?\\|\\(\\)\\[\\]\\{\\}])",
         "\\\\$1");
     assertEquals("\\*\\[", regex);
+    String replacement = hideFromCompiler("\\").replaceAll("\\\\", "\\\\\\\\").replaceAll("\\$",
+        "\\\\$");
+    assertEquals("\\\\", replacement);
     assertEquals("+1", hideFromCompiler("*[1").replaceAll(regex, "+"));
     String x1 = String.valueOf(new char[] {'x', 'x', 'x', 'a', 'b', 'c', 'x', 'x', 'd', 'e', 'x',
     'f'});
@@ -374,6 +374,14 @@
         "boo", "and", "foo"});
   }
 
+  public void testReplaceString() {
+    assertEquals("foobar", hideFromCompiler("bazbar").replace("baz", "foo"));
+    assertEquals("$0bar", hideFromCompiler("foobar").replace("foo", "$0"));
+    assertEquals("$1bar", hideFromCompiler("foobar").replace("foo", "$1"));
+    assertEquals("\\$1bar", hideFromCompiler("foobar").replace("foo", "\\$1"));
+    assertEquals("\\1", hideFromCompiler("*[)1").replace("*[)", "\\"));
+  }
+  
   public void testStartsWith() {
     String haystack = "abcdefghi";
     assertTrue(haystack.startsWith("abc"));