/*
 * 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.JavaScriptObject;
import com.google.gwt.junit.client.GWTTestCase;

/**
 * Tests {@link JavaScriptObject} and subclasses.
 */
public class JsoTest extends GWTTestCase {

  static class Bar extends JavaScriptObject {
    public static int field;

    public static native String staticNative() /*-{
      return "nativeBar";
    }-*/;

    public static String staticValue() {
      return "Bar" + field;
    }

    protected Bar() {
    }

    public final native String getBar() /*-{
      return this.bar;
    }-*/;

    public final String value() {
      return "Bar";
    }
  }

  static final class ClinitStaticFieldFirst extends JavaScriptObject {
    public static String[] FIELD = new String[]{"a","b","c"};
    protected ClinitStaticFieldFirst() {
    }
    public Object invokeInstanceMethod() {
      if (FIELD == null) {
        return null;
      }
      return FIELD;
    }
    public static Object invokeStaticMethod() {
      if (FIELD == null) {
        return null;
      }
      return FIELD;
    }
  }

  static final class ClinitInstanceMethodFirst extends JavaScriptObject {
    public static String[] FIELD = new String[]{"a","b","c"};
    protected ClinitInstanceMethodFirst() {
    }
    public Object invokeInstanceMethod() {
      if (FIELD == null) {
        return null;
      }
      return FIELD;
    }
    public static Object invokeStaticMethod() {
      if (FIELD == null) {
        return null;
      }
      return FIELD;
    }
  }

  static final class ClinitStaticMethodFirst extends JavaScriptObject {
    public static String[] FIELD = new String[]{"a","b","c"};
    protected ClinitStaticMethodFirst() {
    }
    public Object invokeInstanceMethod() {
      if (FIELD == null) {
        return null;
      }
      return FIELD;
    }
    public static Object invokeStaticMethod() {
      if (FIELD == null) {
        return null;
      }
      return FIELD;
    }
  }

  static class Foo extends JavaScriptObject {
    public static int field;

    public static native String staticNative() /*-{
      return "nativeFoo";
    }-*/;
    
    /**
     * Ensure that a supertype can refer to members of a subtype.
     */
    public static native String staticNativeToSub() /*-{
      return @com.google.gwt.dev.jjs.test.JsoTest.FooSub::staticValueSub()();
    }-*/;

    public static String staticValue() {
      return "Foo" + field;
    }

    protected Foo() {
    }

    public final native String getFoo() /*-{
      return this.foo;
    }-*/;

    public final String value() {
      return "Foo";
    }
  }

  static class FooSub extends Foo {
    static String staticValueSub() {
      return "FooSub";
    }
    
    protected FooSub() {
    }

    public final String anotherValue() {
      return "Still Foo";
    }

    public final String superCall() {
      return super.value();
    }
  }

  static class JsArray<T> extends JavaScriptObject {
    public static native <T> JsArray<T> create() /*-{
      return [];
    }-*/;

    protected JsArray() {
    }

    public final native T get(int index) /*-{
      return this[index];
    }-*/;

    public final native int length() /*-{
      return this.length;
    }-*/;

    public final native void put(int index, T value) /*-{
      this[index] = value;
    }-*/;
  }

  static class MethodMangleClash {
    @SuppressWarnings("unused")
    public static String func(JavaScriptObject this_) {
      return "funcJavaScriptObject";
    }

    @SuppressWarnings("unused")
    public static String func(MethodMangleClash this_) {
      return "funcMethodMangleClash";
    }

    @SuppressWarnings("unused")
    public String func() {
      return "func";
    }
  }

  static class Overloads {
    private static volatile boolean FALSE = false;

    @SuppressWarnings("unused")
    static String sFunc(Bar b) {
      return "sFunc Bar";
    }

    @SuppressWarnings("unused")
    static String sFunc(Bar[][] b) {
      return "sFunc Bar[][]";
    }

    @SuppressWarnings("unused")
    static String sFunc(Foo f) {
      return "sFunc Foo";
    }

    @SuppressWarnings("unused")
    static String sFunc(Foo[][] f) {
      return "sFunc Foo[][]";
    }

    @SuppressWarnings("unused")
    public Overloads(Bar b) {
    }

    @SuppressWarnings("unused")
    public Overloads(Bar[][] b) {
    }

    @SuppressWarnings("unused")
    public Overloads(Foo f) {
    }

    @SuppressWarnings("unused")
    public Overloads(Foo[][] f) {
    }

    @SuppressWarnings("unused")
    String func(Bar b) {
      if (FALSE) {
        // prevent inlining
        return func(b);
      }
      return "func Bar";
    }

    @SuppressWarnings("unused")
    String func(Bar[][] b) {
      if (FALSE) {
        // prevent inlining
        return func(b);
      }
      return "func Bar[][]";
    }

    @SuppressWarnings("unused")
    String func(Foo f) {
      if (FALSE) {
        // prevent inlining
        return func(f);
      }
      return "func Foo";
    }

    @SuppressWarnings("unused")
    String func(Foo[][] f) {
      if (FALSE) {
        // prevent inlining
        return func(f);
      }
      return "func Foo[][]";
    }
  }

  private static native Bar makeBar() /*-{
    return {
      toString:function() {
        return "bar";
      },
      bar: "this is bar",
    };
  }-*/;

  private static native Foo makeFoo() /*-{
    return {
      toString:function() {
        return "foo";
      },
      foo: "this is foo",
    };
  }-*/;

  private static native JavaScriptObject makeJSO() /*-{
    return {
      toString:function() {
        return "jso";
      },
      foo: "jso foo",
      bar: "jso bar",
    };
  }-*/;

  private static native JavaScriptObject makeMixedArray() /*-{
    return [
      @com.google.gwt.dev.jjs.test.JsoTest::makeJSO()(),
      "foo",
      @com.google.gwt.dev.jjs.test.JsoTest::makeObject()(),
      null
    ];
  }-*/;

  private static Object makeObject() {
    return new Object() {
      @Override
      public String toString() {
        return "myObject";
      }
    };
  }

  private static native JavaScriptObject returnMe(JavaScriptObject jso) /*-{
    return jso;
  }-*/;

  @Override
  public String getModuleName() {
    return "com.google.gwt.dev.jjs.CompilerSuite";
  }

  public void testArrayInit() {
    Object[] array = {makeJSO(), new Object(), ""};
    assertTrue(array[0] instanceof JavaScriptObject);
    assertFalse(array[1] instanceof JavaScriptObject);
    assertFalse(array[2] instanceof JavaScriptObject);
  }

  public void testArrayStore() {
    JavaScriptObject[] jsoArray = new JavaScriptObject[1];
    jsoArray[0] = makeJSO();
    jsoArray[0] = makeFoo();
    jsoArray[0] = makeBar();

    Foo[] fooArray = new Foo[1];
    fooArray[0] = (Foo) makeJSO();
    fooArray[0] = makeFoo();
    fooArray[0] = makeBar().cast();

    Bar[] barArray = new Bar[1];
    barArray[0] = (Bar) makeJSO();
    barArray[0] = makeBar();
    barArray[0] = makeFoo().cast();

    Object[] objArray = jsoArray;
    try {
      objArray[0] = new Object();
      fail("Expected ArrayStoreException");
    } catch (ArrayStoreException expected) {
    }

    objArray = new Object[1];
    objArray[0] = makeJSO();
    objArray[0] = makeFoo();
    objArray[0] = makeBar();

    Foo[][] foo = new Foo[10][];
    Object[][] fooAsObject = foo;
    fooAsObject[0] = new Bar[1];
  }

  public void testBasic() {
    JavaScriptObject jso = makeJSO();
    assertEquals("jso", jso.toString());

    Foo foo = (Foo) jso;
    assertEquals("jso", foo.toString());
    assertEquals("jso foo", foo.getFoo());
    assertEquals("Foo", foo.value());

    Bar bar = (Bar) jso;
    assertEquals("jso", bar.toString());
    assertEquals("jso bar", bar.getBar());
    assertEquals("Bar", bar.value());

    foo = makeFoo();
    assertEquals("foo", foo.toString());
    assertEquals("this is foo", foo.getFoo());
    assertEquals("Foo", foo.value());

    bar = makeBar();
    assertEquals("bar", bar.toString());
    assertEquals("this is bar", bar.getBar());
    assertEquals("Bar", bar.value());
  }

  @SuppressWarnings("cast")
  public void testCasts() {
    JavaScriptObject jso = makeJSO();
    assertTrue(jso instanceof JavaScriptObject);
    assertTrue(jso instanceof Foo);
    assertTrue(jso instanceof Bar);

    Foo foo = (Foo) jso;
    foo = makeFoo();
    assertTrue((JavaScriptObject) foo instanceof Bar);
    Bar bar = (Bar) (JavaScriptObject) makeFoo();
    bar = makeFoo().cast();

    bar = (Bar) jso;
    bar = makeBar();
    assertTrue((JavaScriptObject) bar instanceof Foo);
    foo = (Foo) (JavaScriptObject) makeBar();
    foo = makeBar().cast();

    // Implicit
    jso = foo;
    jso = bar;

    Object o = new Object();
    assertFalse(o instanceof JavaScriptObject);
    assertFalse(o instanceof Foo);
    assertFalse(o instanceof Bar);
    try {
      jso = (JavaScriptObject) o;
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }

    o = "foo";
    assertFalse(o instanceof JavaScriptObject);
    assertFalse(o instanceof Foo);
    assertFalse(o instanceof Bar);
    try {
      jso = (JavaScriptObject) o;
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }

    o = jso;
    assertFalse(o instanceof String);
    try {
      String s = (String) o;
      s = s.toString();
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }
  }

  @SuppressWarnings("cast")
  public void testCastsArray() {
    JavaScriptObject[][] jso = new JavaScriptObject[0][0];
    assertTrue(jso instanceof JavaScriptObject[][]);
    assertTrue(jso instanceof Foo[][]);
    assertTrue(jso instanceof Bar[][]);

    Foo[][] foo = (Foo[][]) jso;
    foo = new Foo[0][0];
    assertTrue((JavaScriptObject[][]) foo instanceof Bar[][]);
    Bar[][] bar = (Bar[][]) (JavaScriptObject[][]) new Foo[0][0];

    bar = (Bar[][]) jso;
    bar = new Bar[0][0];
    assertTrue((JavaScriptObject[][]) bar instanceof Foo[][]);
    foo = (Foo[][]) (JavaScriptObject[][]) new Bar[0][0];

    Object[][] o = new Object[0][0];
    assertFalse(o instanceof JavaScriptObject[][]);
    assertFalse(o instanceof Foo[][]);
    assertFalse(o instanceof Bar[][]);
    try {
      jso = (JavaScriptObject[][]) o;
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }

    o = jso;
    assertFalse(o instanceof String[][]);
    try {
      String[][] s = (String[][]) o;
      s.getClass();
      fail("Expected ClassCastException");
    } catch (ClassCastException expected) {
    }
  }

  public void testClassInitializerRun() {
    ClinitStaticMethodFirst staticMethodFirst = JavaScriptObject.createObject().cast();
    assertNotNull("static method", ClinitStaticMethodFirst.invokeStaticMethod());
    assertNotNull("instance method after static method", staticMethodFirst.invokeInstanceMethod());

    ClinitStaticFieldFirst staticFieldFirst = JavaScriptObject.createObject().cast();
    assertNotNull("field access", ClinitStaticFieldFirst.FIELD);
    assertNotNull("instance method after field access", staticFieldFirst.invokeInstanceMethod());

    ClinitInstanceMethodFirst instanceMethodFirst = JavaScriptObject.createObject().cast();
    assertNotNull("instance method", instanceMethodFirst.invokeInstanceMethod());
    assertNotNull("static method after instance method", ClinitInstanceMethodFirst.invokeStaticMethod());
  }

  public void testClassLiterals() {
    JavaScriptObject jso = makeJSO();
    Foo foo = makeFoo();
    Bar bar = makeBar();
    assertEquals(JavaScriptObject.class, jso.getClass());
    assertEquals(Foo.class, jso.getClass());
    assertEquals(Bar.class, jso.getClass());
    assertEquals(JavaScriptObject.class, foo.getClass());
    assertEquals(Foo.class, foo.getClass());
    assertEquals(Bar.class, foo.getClass());
    assertEquals(JavaScriptObject.class, bar.getClass());
    assertEquals(Foo.class, bar.getClass());
    assertEquals(Bar.class, bar.getClass());
    assertEquals(JavaScriptObject.class, Foo.class);
    assertEquals(JavaScriptObject.class, Bar.class);
    assertEquals(Foo.class, Bar.class);

    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
      // Class metadata could be disabled
      assertEquals("com.google.gwt.core.client.JavaScriptObject$",
          JavaScriptObject.class.getName());
    }
  }

  public void testClassLiteralsArray() {
    JavaScriptObject[][] jso = new JavaScriptObject[0][0];
    Foo[][] foo = new Foo[0][0];
    Bar[][] bar = new Bar[0][0];
    assertEquals(JavaScriptObject[][].class, jso.getClass());
    assertEquals(Foo[][].class, jso.getClass());
    assertEquals(Bar[][].class, jso.getClass());
    assertEquals(JavaScriptObject[][].class, foo.getClass());
    assertEquals(Foo[][].class, foo.getClass());
    assertEquals(Bar[][].class, foo.getClass());
    assertEquals(JavaScriptObject[][].class, bar.getClass());
    assertEquals(Foo[][].class, bar.getClass());
    assertEquals(Bar[][].class, bar.getClass());
    assertEquals(JavaScriptObject[][].class, Foo[][].class);
    assertEquals(JavaScriptObject[][].class, Bar[][].class);
    assertEquals(Foo[][].class, Bar[][].class);

    if (!JavaScriptObject.class.getName().startsWith("Class$")) {
      // Class metadata could be disabled
      assertEquals("[[Lcom.google.gwt.core.client.JavaScriptObject$;",
          JavaScriptObject[][].class.getName());
    }
  }

  static class MyJSO extends JavaScriptObject {
    protected MyJSO() {
    }

    public final boolean equalMethod(Object o) {
      return this == o;
    }
  }

  public void testEquality() {
    JavaScriptObject jso = makeJSO();
    assertEquals(jso, jso);

    JavaScriptObject jso2 = makeJSO();
    assertFalse(jso.equals(jso2));
    assertFalse(jso2.equals(jso));

    jso2 = returnMe(jso);
    assertEquals(jso, jso2);

    MyJSO jso3 = (MyJSO) makeJSO();
    MyJSO jso4 = (MyJSO) makeJSO();
    assertTrue(jso3.equalMethod(jso3));
    assertFalse(jso3.equalMethod(jso4));
  }

  public void testGenericsJsos() {
    JsArray<JavaScriptObject> a = JsArray.create();
    a.put(0, makeJSO());
    a.put(1, makeFoo());
    a.put(2, makeBar());
    a.put(3, null);
    assertEquals(4, a.length());
    assertEquals("jso", a.get(0).toString());
    assertEquals("foo", a.get(1).toString());
    assertEquals("bar", a.get(2).toString());
    assertEquals(null, a.get(3));
  }

  public void testGenericsMixed() {
    JsArray<Object> a = JsArray.create();
    a.put(0, makeJSO());
    a.put(1, "foo");
    a.put(2, makeObject());
    a.put(3, null);
    assertEquals(4, a.length());
    assertEquals("jso", a.get(0).toString());
    assertEquals("foo", a.get(1));
    assertEquals("myObject", a.get(2).toString());
    assertEquals(null, a.get(3));
  }

  @SuppressWarnings("unchecked")
  public void testGenericsRawJson() {
    JsArray a = (JsArray) makeMixedArray();
    assertEquals(4, a.length());
    assertEquals("jso", a.get(0).toString());
    assertEquals("foo", a.get(1));
    assertEquals("myObject", a.get(2).toString());
    assertEquals(null, a.get(3));
  }

  public void testGenericsStrings() {
    JsArray<String> a = JsArray.create();
    a.put(0, "foo");
    a.put(1, "bar");
    a.put(2, "baz");
    a.put(3, null);
    assertEquals(4, a.length());
    assertEquals("foo", a.get(0));
    assertEquals("bar", a.get(1));
    assertEquals("baz", a.get(2));
    assertEquals(null, a.get(3));
  }

  public void testHashCode() {
    // TODO: make this better.
    JavaScriptObject jso = makeJSO();
    int jsoHashCode = jso.hashCode();
    Foo foo = makeFoo();
    Bar bar = makeBar();
    Object o = new Object() {
      @Override
      public int hashCode() {
        // Return something unlikely so as not to collide with the JSOs.
        return 0xDEADBEEF;
      }
    };

    assertEquals(jsoHashCode, jso.hashCode());
    assertFalse(jsoHashCode == foo.hashCode());
    assertFalse(jsoHashCode == bar.hashCode());
    assertFalse(jsoHashCode == o.hashCode());
    assertFalse(foo.hashCode() == bar.hashCode());
    assertFalse(foo.hashCode() == o.hashCode());
    assertFalse(bar.hashCode() == o.hashCode());

    o = jso;
    assertEquals(jsoHashCode, o.hashCode());

    String s = "foo";
    int stringHashCode = s.hashCode();
    o = s;
    assertEquals(stringHashCode, o.hashCode());
  }

  public void testIdentity() {
    JavaScriptObject jso = makeJSO();
    assertSame(jso, jso);

    JavaScriptObject jso2 = makeJSO();
    assertNotSame(jso, jso2);

    jso2 = returnMe(jso);
    assertSame(jso, jso2);
  }

  public void testInheritance() {
    Foo foo = makeFoo();
    FooSub fooSub = (FooSub) foo;
    assertEquals("Foo", fooSub.value());
    assertEquals("Still Foo", fooSub.anotherValue());
    assertEquals("Foo", fooSub.superCall());
  }

  public void testMethodMangleClash() {
    assertEquals("funcJavaScriptObject",
        MethodMangleClash.func((JavaScriptObject) null));
    assertEquals("funcMethodMangleClash",
        MethodMangleClash.func((MethodMangleClash) null));
    assertEquals("func", new MethodMangleClash().func());
  }

  public void testOverloads() {
    Foo foo = makeFoo();
    assertEquals("func Foo", new Overloads(foo).func(foo));
    assertEquals("sFunc Foo", Overloads.sFunc(foo));

    Bar bar = makeBar();
    assertEquals("func Bar", new Overloads(bar).func(bar));
    assertEquals("sFunc Bar", Overloads.sFunc(bar));
  }

  public void testOverloadsArray() {
    Foo[][] foo = new Foo[0][0];
    assertEquals("func Foo[][]", new Overloads(foo).func(foo));
    assertEquals("sFunc Foo[][]", Overloads.sFunc(foo));

    Bar[][] bar = new Bar[0][0];
    assertEquals("func Bar[][]", new Overloads(bar).func(bar));
    assertEquals("sFunc Bar[][]", Overloads.sFunc(bar));
  }

  public native void testOverloadsArrayNative() /*-{
    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new([[Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Foo[][]", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func([[Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Foo[][]", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc([[Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));

    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new([[Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Bar[][]", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func([[Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Bar[][]", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc([[Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
  }-*/;

  public native void testOverloadsNative() /*-{
    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new(Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Foo", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func(Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Foo", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc(Lcom/google/gwt/dev/jjs/test/JsoTest$Foo;)(null));

    var o = @com.google.gwt.dev.jjs.test.JsoTest.Overloads::new(Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("func Bar", o.@com.google.gwt.dev.jjs.test.JsoTest.Overloads::func(Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("sFunc Bar", @com.google.gwt.dev.jjs.test.JsoTest.Overloads::sFunc(Lcom/google/gwt/dev/jjs/test/JsoTest$Bar;)(null));
  }-*/;

  public void testStaticAccess() {
    Foo.field = 3;
    assertEquals(3, Foo.field--);
    assertEquals("Foo2", Foo.staticValue());
    assertEquals("nativeFoo", Foo.staticNative());
    assertEquals("FooSub", Foo.staticNativeToSub());

    Bar.field = 10;
    assertEquals(11, ++Bar.field);
    assertEquals("Bar11", Bar.staticValue());
    assertEquals("nativeBar", Bar.staticNative());
  }

  public native void testStaticAccessNative() /*-{
    @com.google.gwt.dev.jjs.test.JsoTest.Foo::field = 3;
    @junit.framework.Assert::assertEquals(II)(3, @com.google.gwt.dev.jjs.test.JsoTest.Foo::field--);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("Foo2", @com.google.gwt.dev.jjs.test.JsoTest.Foo::staticValue()());
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("nativeFoo", @com.google.gwt.dev.jjs.test.JsoTest.Foo::staticNative()());

    @com.google.gwt.dev.jjs.test.JsoTest.Bar::field = 10;
    @junit.framework.Assert::assertEquals(II)(11, ++@com.google.gwt.dev.jjs.test.JsoTest.Bar::field);
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("Bar11", @com.google.gwt.dev.jjs.test.JsoTest.Bar::staticValue()());
    @junit.framework.Assert::assertEquals(Ljava/lang/Object;Ljava/lang/Object;)("nativeBar", @com.google.gwt.dev.jjs.test.JsoTest.Bar::staticNative()());
  }-*/;

  public void testStaticAccessSubclass() {
    FooSub.field = 3;
    assertEquals(3, FooSub.field--);
    assertEquals("Foo2", FooSub.staticValue());
    assertEquals("nativeFoo", FooSub.staticNative());
  }

  static JavaScriptObject someObject;
  static class JSO1 extends JavaScriptObject {
    protected JSO1() {
    }
    static native JSO1 create() /*-{
      @com.google.gwt.dev.jjs.test.JsoTest::someObject =
          @com.google.gwt.dev.jjs.test.JsoTest::someObject || [];
      return @com.google.gwt.dev.jjs.test.JsoTest::someObject;
    }-*/;
  }

  static class JSO2 extends JavaScriptObject {
    protected JSO2() {
    }
    static native JSO2 create() /*-{
      @com.google.gwt.dev.jjs.test.JsoTest::someObject =
          @com.google.gwt.dev.jjs.test.JsoTest::someObject || [];
      return @com.google.gwt.dev.jjs.test.JsoTest::someObject;
    }-*/;
  }

  /**
   * Some final JSOs classes to make sure exactness (inferred from final) does not affect
   * JSO cast semantics.
   */
  static final class FinalJSO1 extends JavaScriptObject {
    protected FinalJSO1() {
    }
    static native FinalJSO1 create() /*-{
      @com.google.gwt.dev.jjs.test.JsoTest::someObject =
          @com.google.gwt.dev.jjs.test.JsoTest::someObject || [];
      return @com.google.gwt.dev.jjs.test.JsoTest::someObject;
    }-*/;
  }

  static final class FinalJSO2 extends JavaScriptObject {
    protected FinalJSO2() {
    }
    static native FinalJSO2 create() /*-{
      @com.google.gwt.dev.jjs.test.JsoTest::someObject =
          @com.google.gwt.dev.jjs.test.JsoTest::someObject || [];
      return @com.google.gwt.dev.jjs.test.JsoTest::someObject;
    }-*/;
  }

  interface I {
  }

  /**
   * A JSO class that is the sole implementor of an interface to make sure that the logic in
   * {@link TypeTightener#getSingleConcreteType()} does not create an EXACT JSO type.
   */
  static class JSOImplementingI extends JavaScriptObject implements I {
    protected JSOImplementingI() {
    }
    static native I create() /*-{
      @com.google.gwt.dev.jjs.test.JsoTest::someObject =
          @com.google.gwt.dev.jjs.test.JsoTest::someObject || [];
      return @com.google.gwt.dev.jjs.test.JsoTest::someObject;
    }-*/;
  }

  /**
   * Tests various crosscasting scenarios to make sure that casts are erased and not transformed
   * into throws.
   */
  public void testCrossCasting() {
    JSO1 jso1 = JSO1.create();
    JSO2 jso2 = JSO2.create();
    FinalJSO1 finalJso1 = FinalJSO1.create();
    FinalJSO2 finalJso2 = FinalJSO2.create();
    I i = JSOImplementingI.create();

    assertTrue(jso1 == (JSO1) (trueFn() ? jso2 : (JavaScriptObject) null));
    assertTrue(jso1 == (JSO1) (trueFn() ? i : (JavaScriptObject) null));
    assertTrue(jso1 == (JSO1) (trueFn() ? finalJso1 : (JavaScriptObject) null));
    assertTrue(jso1 == (JSO1) (trueFn() ? finalJso2 : (JavaScriptObject) null));

    assertTrue(jso2 == (JSO2) (trueFn() ? jso1 : (JavaScriptObject) null));
    assertTrue(jso2 == (JSO2) (trueFn() ? i : (JavaScriptObject) null));
    assertTrue(jso2 == (JSO2) (trueFn() ? finalJso1 : (JavaScriptObject) null));
    assertTrue(jso2 == (JSO2) (trueFn() ? finalJso2 : (JavaScriptObject) null));

    assertTrue(finalJso1 == (FinalJSO1) (trueFn() ? jso1 : (JavaScriptObject) null));
    assertTrue(finalJso1 == (FinalJSO1) (trueFn() ? i : (JavaScriptObject) null));
    assertTrue(finalJso1 == (FinalJSO1) (trueFn() ? jso2 : (JavaScriptObject) null));
    assertTrue(finalJso1 == (FinalJSO1) (trueFn() ? finalJso2 : (JavaScriptObject) null));

    assertTrue(finalJso2 == (FinalJSO2) (trueFn() ? jso1 : (JavaScriptObject) null));
    assertTrue(finalJso2 == (FinalJSO2) (trueFn() ? i : (JavaScriptObject) null));
    assertTrue(finalJso2 == (FinalJSO2) (trueFn() ? jso2 : (JavaScriptObject) null));
    assertTrue(finalJso2 == (FinalJSO2) (trueFn() ? finalJso1 : (JavaScriptObject) null));

    assertTrue(i == (I) (trueFn() ? jso1 : (JavaScriptObject) null));
    assertTrue(i == (I) (trueFn() ? jso2 : (JavaScriptObject) null));
    assertTrue(i == (I) (trueFn() ? finalJso1 : (JavaScriptObject) null));
    assertTrue(i == (I) (trueFn() ? finalJso2 : (JavaScriptObject) null));
  }

  /**
   *
   * Test that nullability optimizations don't break the assumption that null is considered a JSO.
   */
  public void testNonNullableOptimization() {
    // TODO(rluble): fix semantics to be more coherent by adding a nullness check for devirtualized
    // methods in draft mode.
    JavaScriptObject nullJso =  (trueFn() ? null : JavaScriptObject.createArray());
    // This statement should throw NPE (at least in draft mode) but it does not due to JSO
    // devirtualization. These semantics are exploited in GWT standard library. Improvemnts and
    // fixes to optimization passes might break these assumptions.
    JSO1 someJso = nullJso.cast();
    assertTrue(someJso == null);
  }

  private boolean trueFn() {
    return true;
  }
}
