Revision: 7286 Author: [email protected] Date: Wed Dec 9 11:18:49 2009 Log: Fix System.arrayCopy to handle interfaces properly.
Issue: 3621 Patch by: hayward.chan Review by: jat http://code.google.com/p/google-web-toolkit/source/detail?r=7286 Modified: /trunk/user/super/com/google/gwt/emul/java/lang/System.java /trunk/user/test/com/google/gwt/emultest/java/lang/SystemTest.java ======================================= --- /trunk/user/super/com/google/gwt/emul/java/lang/System.java Wed Feb 18 17:08:17 2009 +++ /trunk/user/super/com/google/gwt/emul/java/lang/System.java Wed Dec 9 11:18:49 2009 @@ -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(); }-*/; ======================================= --- /trunk/user/test/com/google/gwt/emultest/java/lang/SystemTest.java Mon Oct 15 11:52:26 2007 +++ /trunk/user/test/com/google/gwt/emultest/java/lang/SystemTest.java Wed Dec 9 11:18:49 2009 @@ -17,6 +17,8 @@ import com.google.gwt.junit.client.GWTTestCase; +import java.util.Arrays; + /** * Tests java.lang.System. */ @@ -26,15 +28,75 @@ public Bar() { } } + + 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]; @@ -92,6 +154,17 @@ } catch (ArrayStoreException e) { } } + + 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]; @@ -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 " + (strArray.length - 2), strArray.length - 2, + assertEquals("fwd str copy index " + i, i, Integer.valueOf( + strArray[i]).intValue()); + } + 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 -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
