Move String.split to Java code.
Change-Id: Icd60ddc3a3f4493b25e0b4e33b1047c4fb4ca19f
diff --git a/dev/core/super/javaemul/internal/ArrayStamper.java b/dev/core/super/javaemul/internal/ArrayStamper.java
index 5c3d828..a6a9ed2 100644
--- a/dev/core/super/javaemul/internal/ArrayStamper.java
+++ b/dev/core/super/javaemul/internal/ArrayStamper.java
@@ -18,7 +18,7 @@
/**
* A utility to provide array stamping. Provided as a separate class to simplify super-source.
*/
-public class ArrayStamper {
+class ArrayStamper {
public static native <T> T[] stampJavaTypeInfo(Object array, T[] referenceType) /*-{
return @com.google.gwt.lang.Array::stampJavaTypeInfo(*)(array, referenceType);
}-*/;
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 825faa6..85d9059 100644
--- a/user/super/com/google/gwt/emul/java/lang/String.java
+++ b/user/super/com/google/gwt/emul/java/lang/String.java
@@ -26,7 +26,6 @@
import java.util.Locale;
import javaemul.internal.ArrayHelper;
-import javaemul.internal.ArrayStamper;
import javaemul.internal.EmulatedCharset;
import javaemul.internal.HashCodes;
import javaemul.internal.annotations.DoNotInline;
@@ -531,7 +530,7 @@
// in order to escape regexp special characters (e.g. '.').
String hex = Integer.toHexString(from);
String regex = "\\u" + "0000".substring(hex.length()) + hex;
- Object jsRegEx = createRegEx(regex, "g");
+ Object jsRegEx = createRegExp(regex, "g");
String replace = fromCharCode(to);
return replace(jsRegEx, replace);
}
@@ -566,7 +565,7 @@
*/
public String replaceAll(String regex, String replace) {
replace = translateReplaceString(replace);
- Object jsRegEx = createRegEx(regex, "g");
+ Object jsRegEx = createRegExp(regex, "g");
return replace(jsRegEx, replace);
}
@@ -580,18 +579,34 @@
*/
public String replaceFirst(String regex, String replace) {
replace = translateReplaceString(replace);
- Object jsRegEx = createRegEx(regex, "");
+ Object jsRegEx = createRegExp(regex, "");
return replace(jsRegEx, replace);
}
- private native Object createRegEx(String regex, String mode) /*-{
+ private static native Object createRegExp(String regex, String mode) /*-{
return RegExp(regex, mode);
}-*/;
+ private static native Object execRegExp(Object regex, String value) /*-{
+ return regex.exec(value);
+ }-*/;
+
+ private static native int resetRegExpLastIndex(Object compiledRegEx) /*-{
+ compiledRegEx.lastIndex = 0;
+ }-*/;
+
private native String replace(Object regex, String replace) /*-{
return this.replace(regex, replace);
}-*/;
+ private static native int getMatchIndex(Object matchObject) /*-{
+ return matchObject.index;
+ }-*/;
+
+ private static native int getMatchLength(Object matchObject, int index) /*-{
+ return matchObject[index].length;
+ }-*/;
+
/**
* Regular expressions vary from the standard implementation. The
* <code>regex</code> parameter is interpreted by JavaScript as a JavaScript
@@ -611,37 +626,32 @@
* TODO(jat): properly handle Java regex syntax
*/
public String[] split(String regex, int maxMatch) {
- String[] jsArrayString = split0(regex, maxMatch);
- ArrayStamper.stampJavaTypeInfo(jsArrayString, new String[0]);
- return jsArrayString;
- }
-
- private native String[] split0(String regex, int maxMatch) /*-{
// The compiled regular expression created from the string
- var compiled = new RegExp(regex, "g");
+ Object compiled = createRegExp(regex, "g");
// the Javascipt array to hold the matches prior to conversion
- var out = [];
+ String[] out = new String[0];
// how many matches performed so far
- var count = 0;
+ int count = 0;
// The current string that is being matched; trimmed as each piece matches
- var trail = this;
+ String trail = this;
// used to detect repeated zero length matches
// Must be null to start with because the first match of "" makes no
// progress by intention
- var lastTrail = null;
+ String lastTrail = null;
// We do the split manually to avoid Javascript incompatibility
while (true) {
// None of the information in the match returned are useful as we have no
// subgroup handling
- var matchObj = compiled.exec(trail);
+ Object matchObj = execRegExp(compiled, trail);
if (matchObj == null || trail == "" || (count == (maxMatch - 1) && maxMatch > 0)) {
out[count] = trail;
break;
} else {
- out[count] = trail.substring(0, matchObj.index);
- trail = trail.substring(matchObj.index + matchObj[0].length, trail.length);
+ out[count] = trail.substring(0, getMatchIndex(matchObj));
+ trail = trail.substring(
+ getMatchIndex(matchObj) + getMatchLength(matchObj, 0), trail.length());
// Force the compiled pattern to reset internal state
- compiled.lastIndex = 0;
+ resetRegExpLastIndex(compiled);
// Only one zero length match per character to ensure termination
if (lastTrail == trail) {
out[count] = trail.substring(0, 1);
@@ -654,17 +664,17 @@
// all blank delimiters at the end are supposed to disappear if maxMatch == 0;
// however, if the input string is empty, the output should consist of a
// single empty string
- if (maxMatch == 0 && this.length > 0) {
- var lastNonEmpty = out.length;
+ if (maxMatch == 0 && this.length() > 0) {
+ int lastNonEmpty = out.length;
while (lastNonEmpty > 0 && out[lastNonEmpty - 1] == "") {
--lastNonEmpty;
}
if (lastNonEmpty < out.length) {
- out.splice(lastNonEmpty, out.length - lastNonEmpty);
+ ArrayHelper.setLength(out, lastNonEmpty);
}
}
return out;
- }-*/;
+ }
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);