Fix System.arrayCopy to handle interfaces properly.
Issue: 3621
Patch by: hayward.chan
Review by: jat
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7286 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/super/com/google/gwt/emul/java/lang/System.java b/user/super/com/google/gwt/emul/java/lang/System.java
index 8567ef6..333b5b2 100644
--- a/user/super/com/google/gwt/emul/java/lang/System.java
+++ b/user/super/com/google/gwt/emul/java/lang/System.java
@@ -52,8 +52,7 @@
Class<?> srcComp = srcType.getComponentType();
Class<?> destComp = destType.getComponentType();
- if (srcComp.modifiers != destComp.modifiers
- || (srcComp.isPrimitive() && !srcComp.equals(destComp))) {
+ if (!arrayTypeMatch(srcComp, destComp)) {
throw new ArrayStoreException("Array types must match");
}
int srclen = getArrayLength(src);
@@ -92,7 +91,7 @@
public static long currentTimeMillis() {
return (long) currentTimeMillis0();
- };
+ }
/**
* Has no effect; just here for source compatibility.
@@ -100,7 +99,7 @@
* @skip
*/
public static void gc() {
- };
+ }
public static int identityHashCode(Object o) {
return (o == null) ? 0 : (!(o instanceof String)) ? Impl.getHashCode(o)
@@ -115,6 +114,14 @@
@java.lang.System::out = out;
}-*/;
+ private static boolean arrayTypeMatch(Class<?> srcComp, Class<?> destComp) {
+ if (srcComp.isPrimitive()) {
+ return srcComp.equals(destComp);
+ } else {
+ return !destComp.isPrimitive();
+ }
+ }
+
private static native double currentTimeMillis0() /*-{
return (new Date()).getTime();
}-*/;
diff --git a/user/test/com/google/gwt/emultest/java/lang/SystemTest.java b/user/test/com/google/gwt/emultest/java/lang/SystemTest.java
index 5df9bb0..dab692a 100644
--- a/user/test/com/google/gwt/emultest/java/lang/SystemTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/SystemTest.java
@@ -17,6 +17,8 @@
import com.google.gwt.junit.client.GWTTestCase;
+import java.util.Arrays;
+
/**
* Tests java.lang.System.
*/
@@ -27,15 +29,75 @@
}
}
+ private enum EnumImpl implements Interfaz {
+ FOO,
+ BAR,
+ BAZ
+ }
+
private static class Foo {
public Foo() {
}
}
+ private interface Interfaz {
+ }
+
+ private static class InterfazImpl implements Interfaz {
+
+ private final String data;
+
+ /**
+ * @param data non-null string
+ */
+ InterfazImpl(String data) {
+ this.data = data;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof InterfazImpl) && ((InterfazImpl) obj).data.equals(
+ data);
+ }
+
+ @Override
+ public int hashCode() {
+ return data.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "InterfazImpl[data=" + data + "]";
+ }
+ }
+
+ @Override
public String getModuleName() {
return "com.google.gwt.emultest.EmulSuite";
}
+ public void testArraycopyEnumToInterface() {
+ EnumImpl[] src = new EnumImpl[]{ EnumImpl.FOO, null, EnumImpl.BAZ };
+ Interfaz[] dest = new Interfaz[5];
+ Arrays.fill(dest, null); // undefined != null, wierd.
+
+ System.arraycopy(src, 0, dest, 1, 3);
+ assertEquals(
+ Arrays.asList(null, EnumImpl.FOO, null, EnumImpl.BAZ, null),
+ Arrays.asList(dest));
+ }
+
+ public void testArraycopyEnumToObject() {
+ EnumImpl[] src = new EnumImpl[]{ EnumImpl.FOO, null, EnumImpl.BAZ };
+ Object[] dest = new Object[5];
+ Arrays.fill(dest, null); // undefined != null, wierd.
+
+ System.arraycopy(src, 0, dest, 1, 3);
+ assertEquals(
+ Arrays.asList(null, EnumImpl.FOO, null, EnumImpl.BAZ, null),
+ Arrays.asList(dest));
+ }
+
public void testArraycopyFailures() {
int[] src = new int[4];
int[] dest = new int[] {1, 1, 1, 1};
@@ -93,6 +155,17 @@
}
}
+ public void testArraycopyInterfaceToObject() {
+ Interfaz[] src = new Interfaz[]{
+ new InterfazImpl("foo"), null, new InterfazImpl("bar") };
+ Object[] dest = new Object[5];
+ Arrays.fill(dest, null); // undefined != null, wierd.
+
+ System.arraycopy(src, 0, dest, 1, 3);
+ assertEquals(Arrays.asList(null, new InterfazImpl("foo"), null,
+ new InterfazImpl("bar"), null), Arrays.asList(dest));
+ }
+
public void testArraycopyMultidim() {
Object[][] objArray = new Object[1][1];
String[][] strArray = new String[1][1];
@@ -151,7 +224,7 @@
assertNull(barArray[3]);
}
}
-
+
public void testArraycopyOverlap() {
int[] intArray = new int[] {0, 1, 2, 3};
String[] strArray = new String[] {"0", "1", "2", "3"};
@@ -165,18 +238,21 @@
for (int i = 0; i < intArray.length - 1; ++i) {
assertEquals("fwd int copy index " + i, i, intArray[i]);
}
- assertEquals("fwd int copy index " + (intArray.length - 2), intArray.length - 2,
- intArray[intArray.length - 1]);
+ assertEquals("fwd int copy index " + (intArray.length - 2),
+ intArray.length - 2, intArray[intArray.length - 1]);
System.arraycopy(strArray, 0, strArray, 1, strArray.length - 1);
assertEquals(0, Integer.valueOf(strArray[0]).intValue());
for (int i = 1; i < strArray.length; ++i) {
- assertEquals("rev str copy index " + i, i - 1, Integer.valueOf(strArray[i]).intValue());
+ assertEquals("rev str copy index " + i, i - 1, Integer.valueOf(
+ strArray[i]).intValue());
}
System.arraycopy(strArray, 1, strArray, 0, strArray.length - 1);
for (int i = 0; i < strArray.length - 1; ++i) {
- assertEquals("fwd str copy index " + i, i, Integer.valueOf(strArray[i]).intValue());
+ assertEquals("fwd str copy index " + i, i, Integer.valueOf(
+ strArray[i]).intValue());
}
- assertEquals("fwd str copy index " + (strArray.length - 2), strArray.length - 2,
+ assertEquals("fwd str copy index " + (strArray.length - 2),
+ strArray.length - 2,
Integer.valueOf(strArray[strArray.length - 1]).intValue());
/*
* TODO(jat): how is it supposed to behave with overlapped copies if there