| /* |
| * Copyright 2008 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.dev.jjs.test; |
| |
| import com.google.gwt.core.client.JavaScriptException; |
| import com.google.gwt.junit.client.GWTTestCase; |
| |
| /** |
| * This should probably be refactored at some point. |
| */ |
| public class MiscellaneousTest extends GWTTestCase { |
| |
| interface I { |
| } |
| |
| interface IBar extends I { |
| } |
| |
| interface IFoo extends I { |
| } |
| |
| static class PolyA implements IFoo { |
| public String toString() { |
| return "A"; |
| } |
| } |
| |
| static class PolyB implements IBar { |
| public String toString() { |
| return "B"; |
| } |
| } |
| |
| private static class HasClinit { |
| public static int i = 1; |
| |
| private static HasClinit sInstance = new HasClinit(); |
| |
| public static int sfoo() { |
| return sInstance.foo(); |
| } |
| |
| private static native void clinitInNative() /*-{ |
| }-*/; |
| |
| private int foo() { |
| this.toString(); |
| return 3; |
| } |
| } |
| |
| private static volatile boolean FALSE = false; |
| |
| private static volatile boolean TRUE = true; |
| |
| private static void assertAllCanStore(Object[] dest, Object[] src) { |
| for (int i = 0; i < src.length; ++i) { |
| dest[0] = src[i]; |
| } |
| } |
| |
| private static void assertNoneCanStore(Object[] dest, Object[] src) { |
| for (int i = 0; i < src.length; ++i) { |
| try { |
| dest[0] = src[i]; |
| fail(); |
| } catch (ArrayStoreException e) { |
| } |
| } |
| } |
| |
| private static native void clinitFromNative() /*-{ |
| @com.google.gwt.dev.jjs.test.MiscellaneousTest$HasClinit::i = 5; |
| }-*/; |
| |
| private static native void noOp() /*-{ |
| }-*/; |
| |
| private static native void throwNativeException() /*-{ |
| var a; a.asdf(); |
| }-*/; |
| |
| public String getModuleName() { |
| return "com.google.gwt.dev.jjs.CompilerSuite"; |
| } |
| |
| public void testArrayCasts() { |
| { |
| // thwart optimizer |
| Object f1 = FALSE ? (Object) new PolyA() : (Object) new IFoo[1]; |
| if (expectClassMetadata()) { |
| assertEquals("[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$IFoo;", |
| f1.getClass().getName()); |
| } |
| assertFalse(f1 instanceof PolyA[][]); |
| assertFalse(f1 instanceof IFoo[][]); |
| assertFalse(f1 instanceof PolyA[]); |
| assertTrue(f1 instanceof IFoo[]); |
| assertFalse(f1 instanceof PolyA); |
| assertFalse(f1 instanceof IFoo); |
| assertTrue(f1 instanceof Object[]); |
| assertFalse(f1 instanceof Object[][]); |
| |
| assertAllCanStore((Object[]) f1, new Object[] {new PolyA(), new IFoo() { |
| }}); |
| assertNoneCanStore((Object[]) f1, new Object[] { |
| new PolyB(), new Object(), new Object[0]}); |
| } |
| |
| { |
| // thwart optimizer |
| Object a1 = FALSE ? (Object) new PolyA() : (Object) new PolyA[1]; |
| if (expectClassMetadata()) { |
| assertEquals("[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$PolyA;", |
| a1.getClass().getName()); |
| } |
| assertFalse(a1 instanceof PolyA[][]); |
| assertFalse(a1 instanceof IFoo[][]); |
| assertTrue(a1 instanceof PolyA[]); |
| assertTrue(a1 instanceof IFoo[]); |
| assertFalse(a1 instanceof PolyA); |
| assertFalse(a1 instanceof IFoo); |
| assertTrue(a1 instanceof Object[]); |
| assertFalse(a1 instanceof Object[][]); |
| |
| assertAllCanStore((Object[]) a1, new Object[] {new PolyA()}); |
| assertNoneCanStore((Object[]) a1, new Object[] {new IFoo() { |
| }, new PolyB(), new Object(), new Object[0]}); |
| } |
| |
| { |
| // thwart optimizer |
| Object f2 = FALSE ? (Object) new PolyA() : (Object) new IFoo[1][]; |
| if (expectClassMetadata()) { |
| assertEquals("[[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$IFoo;", |
| f2.getClass().getName()); |
| } |
| assertFalse(f2 instanceof PolyA[][]); |
| assertTrue(f2 instanceof IFoo[][]); |
| assertFalse(f2 instanceof PolyA[]); |
| assertFalse(f2 instanceof IFoo[]); |
| assertFalse(f2 instanceof PolyA); |
| assertFalse(f2 instanceof IFoo); |
| assertTrue(f2 instanceof Object[]); |
| assertTrue(f2 instanceof Object[][]); |
| |
| assertAllCanStore((Object[]) f2, new Object[] {new PolyA[0], new IFoo[0]}); |
| assertNoneCanStore((Object[]) f2, new Object[] {new IFoo() { |
| }, new PolyB(), new Object(), new Object[0]}); |
| } |
| |
| { |
| // thwart optimizer |
| Object a2 = FALSE ? (Object) new PolyA() : (Object) new PolyA[1][]; |
| if (expectClassMetadata()) { |
| assertEquals("[[Lcom.google.gwt.dev.jjs.test.MiscellaneousTest$PolyA;", |
| a2.getClass().getName()); |
| } |
| assertTrue(a2 instanceof PolyA[][]); |
| assertTrue(a2 instanceof IFoo[][]); |
| assertFalse(a2 instanceof PolyA[]); |
| assertFalse(a2 instanceof IFoo[]); |
| assertFalse(a2 instanceof PolyA); |
| assertFalse(a2 instanceof IFoo); |
| assertTrue(a2 instanceof Object[]); |
| assertTrue(a2 instanceof Object[][]); |
| |
| assertAllCanStore((Object[]) a2, new Object[] {new PolyA[0]}); |
| assertNoneCanStore((Object[]) a2, new Object[] {new IFoo() { |
| }, new PolyB(), new Object(), new Object[0], new IFoo[0]}); |
| } |
| } |
| |
| public void testArrays() { |
| int[] c = new int[] {1, 2}; |
| int[][] d = new int[][] { {1, 2}, {3, 4}}; |
| int[][][] e = new int[][][] { { {1, 2}, {3, 4}}, { {5, 6}, {7, 8}}}; |
| if (expectClassMetadata()) { |
| assertEquals("[I", c.getClass().getName()); |
| assertEquals("[[I", d.getClass().getName()); |
| assertEquals("[I", d[1].getClass().getName()); |
| assertEquals("[[[I", e.getClass().getName()); |
| assertEquals("[[I", e[1].getClass().getName()); |
| assertEquals("[I", e[1][1].getClass().getName()); |
| } |
| assertEquals(2, c[1]); |
| assertEquals(3, d[1][0]); |
| assertEquals(8, e[1][1][1]); |
| |
| int[][][] b = new int[3][2][1]; |
| b[2][1][0] = 1; |
| b = new int[3][2][]; |
| b[2][1] = null; |
| b = new int[3][][]; |
| b[2] = null; |
| } |
| |
| public void testAssociativityCond() { |
| int result = (TRUE ? TRUE : FALSE) ? 100 : 200; |
| assertEquals(100, result); |
| } |
| |
| @SuppressWarnings("cast") |
| public void testCasts() { |
| Object o = FALSE ? (Object) new PolyA() : (Object) new PolyB(); |
| assertTrue(o instanceof I); |
| assertFalse(o instanceof IFoo); |
| assertTrue(o instanceof IBar); |
| assertFalse(o instanceof PolyA); |
| assertTrue(o instanceof PolyB); |
| try { |
| o = (PolyA) o; |
| fail(); |
| } catch (ClassCastException e) { |
| } |
| } |
| |
| public void testClinit() { |
| ++HasClinit.i; |
| HasClinit x = new HasClinit(); |
| ++x.i; |
| new HasClinit().i++; |
| HasClinit.i /= HasClinit.i; |
| HasClinit.sfoo(); |
| HasClinit.i /= HasClinit.sfoo(); |
| HasClinit.clinitInNative(); |
| clinitFromNative(); |
| } |
| |
| public void testExceptions() { |
| int i; |
| for (i = 0; i < 5; ++i) { |
| boolean hitOuter = false; |
| boolean hitInner = false; |
| try { |
| try { |
| switch (i) { |
| case 0: |
| throw new RuntimeException(); |
| case 1: |
| throw new IndexOutOfBoundsException(); |
| case 2: |
| throw new Exception(); |
| case 3: |
| throw new StringIndexOutOfBoundsException(); |
| case 4: |
| throwNativeException(); |
| } |
| } catch (StringIndexOutOfBoundsException e) { |
| assertEquals(3, i); |
| } finally { |
| hitInner = true; |
| } |
| } catch (IndexOutOfBoundsException f) { |
| assertEquals(1, i); |
| } catch (JavaScriptException js) { |
| assertEquals(4, i); |
| } catch (RuntimeException g) { |
| assertEquals(0, i); |
| } catch (Throwable e) { |
| assertEquals(2, i); |
| } finally { |
| assertTrue(hitInner); |
| hitOuter = true; |
| } |
| assertTrue(hitOuter); |
| } |
| assertEquals(5, i); |
| } |
| |
| public void testIssue2479() { |
| if (TRUE) { |
| FALSE = false; |
| } else if (FALSE) { |
| TRUE = true; |
| } else { |
| noOp(); |
| } |
| } |
| |
| public void testString() { |
| String x = "hi"; |
| assertEquals("hi", x); |
| assertEquals("hi", x.toString()); |
| x = new String(); |
| assertEquals("", x); |
| x = new String(x); |
| assertEquals("", x); |
| x = new String("hi"); |
| assertEquals("hi", x); |
| assertEquals('i', x.charAt(1)); |
| assertEquals("hiyay", x.concat("yay")); |
| assertEquals("hihi", x + x); |
| |
| assertEquals( |
| "blahcom.google.gwt.dev.jjs.test.MiscellaneousTestabctruefalsenullc27", |
| ("blah" + this + String.valueOf(new char[] {'a', 'b', 'c'}) + true |
| + false + null + 'c' + 27)); |
| } |
| |
| /** |
| * Ensures that polymorphic dispatch to String works correctly. |
| */ |
| @SuppressWarnings("unchecked") |
| public void testStringPrototype() { |
| Object s = FALSE ? new Object() : "Hello, World!"; |
| assertEquals(String.class, s.getClass()); |
| assertEquals("Hello, World!".hashCode(), s.hashCode()); |
| assertTrue(s.equals("Hello, World!")); |
| assertTrue("Hello, World!".equals(s)); |
| assertFalse(s.equals("")); |
| assertFalse("".equals(s)); |
| assertEquals("Hello, World!", s.toString()); |
| assertTrue(s instanceof String); |
| |
| Comparable b = FALSE ? new Integer(1) : "Hello, World!"; |
| assertTrue(((Comparable) "Hello, World!").compareTo(b) == 0); |
| assertTrue(b.compareTo("Hello, World!") == 0); |
| assertTrue(((Comparable) "A").compareTo(b) < 0); |
| assertTrue(b.compareTo("A") > 0); |
| assertTrue(((Comparable) "Z").compareTo(b) > 0); |
| assertTrue(b.compareTo("Z") < 0); |
| assertTrue(b instanceof String); |
| |
| CharSequence c = FALSE ? new StringBuffer() : "Hello, World!"; |
| assertEquals('e', c.charAt(1)); |
| assertEquals(13, c.length()); |
| assertEquals("ello", c.subSequence(1, 5)); |
| assertTrue(c instanceof String); |
| } |
| |
| public String toString() { |
| return "com.google.gwt.dev.jjs.test.MiscellaneousTest"; |
| } |
| |
| private boolean expectClassMetadata() { |
| String name = Object.class.getName(); |
| |
| if (name.equals("java.lang.Object")) { |
| return true; |
| } else if (name.startsWith("Class$")) { |
| return false; |
| } |
| |
| throw new RuntimeException("Unexpected class name " + name); |
| } |
| } |