/*
 * 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.
 */
/**********************
 * * DO NOT FORMAT * *
 **********************/
package com.google.gwt.dev.jjs.test;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.UnsafeNativeLong;
import com.google.gwt.junit.client.GWTTestCase;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Tests several tricky aspects of Development Mode.
 */
public class HostedTest extends GWTTestCase {

  /**
   * Tests that we can use a source level name for a nested type instead of the
   * binary name.
   */
  static class A {

    static class B {
      int b = 1;

      public native int getUsingBinaryRef() /*-{
        return this.@com.google.gwt.dev.jjs.test.HostedTest$A$B::b;
      }-*/;

      public native int getUsingSourceRef() /*-{
        return this.@com.google.gwt.dev.jjs.test.HostedTest.A.B::b;
      }-*/;
    }
  }

  private static class TestCovariantChild extends TestCovariantSuper {
    @Override
    public native String foo(String val) /*-{
      return val;
    }-*/;
  }

  private static class TestCovariantSuper {
    public native Object foo(String val) /*-{
      return val;
    }-*/;
  }

  private static enum TestEnum {
    VAL1, VAL2, VAL3() {
      @Override
      public native String foo() /*-{
        return "VAL3-foo";
      }-*/;
    };

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

    public native String foo() /*-{
      return "foo";
    }-*/;
  }

  private static class TestGenericList extends AbstractList<Object> {
    @Override
    public Object get(int index) {
      return this;
    }

    @Override
    public int size() {
      return 42;
    }
  }

  static String sFoo(String s) {
    return s + "foo";
  }

  private native static JavaScriptObject getBoxedBooleanAsObject(boolean v) /*-{
    return new Boolean(v);
  }-*/;

  private native static JavaScriptObject getBoxedNumberAsObject(double v) /*-{
    return new Number(v);
  }-*/;

  private native static double getDouble(double v) /*-{
    return -v;
  }-*/;

  private static native float getFloat() /*-{
    return myFloatValue;
  }-*/;

  private static native float getFloatString() /*-{
    return Number(myFloatValue.toString());
  }-*/;

  private native static int getInt(int v) /*-{
    return -v;
  }-*/;

  // this should cause an exception
  private static native Object getIntAsObject() /*-{
    return 5;
  }-*/;

  private native static String getJSOAsString(JavaScriptObject jso) /*-{
    return "" + jso;
  }-*/;

  private native static Object getObject(Object o) /*-{
    return o;
  }-*/;

  private static native JavaScriptObject getsFooFunc() /*-{
    return @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;);
  }-*/;

  private native static String getString(String s) /*-{
    return s + "me";
  }-*/;

  // ok to return JS string from an Object method
  private static native Object getStringAsObject() /*-{
    return "test";
  }-*/;

  private native static int getStringLength(String s) /*-{
    return s.length;
  }-*/;

  private static native boolean jsIdentical(Object o1, Object o2) /*-{
    return o1 === o2;
  }-*/;

  private static native boolean jsniInstanceFunctionsIdentical(Object o) /*-{
    return o.@java.lang.Object::toString() === o.@java.lang.Object::toString();
  }-*/;

  private static native boolean jsniStaticFunctionsIdentical() /*-{
    return @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;) === @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;);
  }-*/;

  private static native String sFooCall(String s) /*-{
    var func = @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;);
    return func.call(null, s);
  }-*/;

  private static native String sFooDirect(String s) /*-{
    return @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;)(s);
  }-*/;

  private static native String sFooFuncAsStr() /*-{
    var f = @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;);
    return "" + f;
  }-*/;

  private static native String sFooFuncToString() /*-{
    var f = @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;);
    return f.toString();
  }-*/;

  private static native String sFooInvoke(String s) /*-{
    var func = @com.google.gwt.dev.jjs.test.HostedTest::sFoo(Ljava/lang/String;);
    return func(s);
  }-*/;

  private static native String sFooRoundTrip(JavaScriptObject fooFunc, String s) /*-{
    return fooFunc(s);
  }-*/;

  private static native void storeFloat(float f) /*-{
    myFloatValue = f;
  }-*/;

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

  public void testAssertionsAlwaysOn() {
    if (!GWT.isScript()) {
      assertTrue(HostedTest.class.desiredAssertionStatus());
    }
  }

  /*
   * Test that returning JavaScript boxed primitives works as expected. Note
   * that Boolean and Number cannot be supported properly in Production Mode, so
   * we do not support it in Development Mode and therefore do not test it here.
   * Also we no longer support string boxing.
   */
  public void testAutoBoxing() {
    JavaScriptObject bvo = getBoxedBooleanAsObject(true);
    assertEquals(getJSOAsString(bvo), "true");
    JavaScriptObject nvo = getBoxedNumberAsObject(42);
    assertEquals(getJSOAsString(nvo), "42");
  }

  public void testBasic() {
    int iv = getInt(14);
    assertEquals(iv, -14);
    double dv = getDouble(31.5);
    assertEquals(dv, -31.5, 0.0);
    String sv = getString("test");
    assertEquals(sv, "testme");
    Object oin = String.class;
    Object oout = getObject(oin);
    assertEquals(oin, oout);
  }

  public void testByteMarshalling() {
    byte b = 100;
    assertEquals(100, byteAsInt(b));
    b = -125;
    assertEquals(-125, byteAsInt(b));
  }

  public void testCovariant() {
    TestCovariantSuper parent = new TestCovariantSuper();
    TestCovariantChild child = new TestCovariantChild();
    Object val1 = parent.foo("bar");
    assertTrue(val1 instanceof String);
    assertEquals("bar", val1);
    String val2 = child.foo("bar");
    assertEquals("bar", val2);
  }

  public void testEmbeddedNullsInStrings() {
    String s = "Pre\u0000Post";
    assertEquals(s.length(), getStringLength(s));
    assertEquals(s + "me", getString(s));
  }

  public void testEnum() {
    TestEnum val = enumSimple(TestEnum.VAL2);
    assertEquals(TestEnum.VAL2, val);
    int ord = enumValue(val);
    assertEquals(TestEnum.VAL2.ordinal(), ord);
    String name = enumName(val);
    assertEquals(TestEnum.VAL2.name(), name);
  }

  public void testEnumJsni() {
    assertEquals("sFoo", TestEnum.sFoo());
    assertEquals("sFoo", TestEnum.VAL1.sFoo());
    assertEquals("foo", TestEnum.VAL1.foo());
    assertEquals("VAL3-foo", TestEnum.VAL3.foo());
  }

  public void testFloat() {
    storeFloat(Float.MIN_VALUE);
    float f = getFloat();
    assertTrue(f == Float.MIN_VALUE);
    f = getFloatString();
    assertTrue(f == Float.MIN_VALUE);
    storeFloat(Float.MAX_VALUE);
    f = getFloat();
    assertTrue(f == Float.MAX_VALUE);
    f = getFloatString();
    assertTrue(f == Float.MAX_VALUE);
  }

  public void testFunctionCaching() {
    assertEquals("barfoo", sFooCall("bar"));
    assertEquals("barfoo", sFooDirect("bar"));
    assertEquals("barfoo", sFooInvoke("bar"));
    assertEquals("barfoo", sFooRoundTrip(getsFooFunc(), "bar"));

    assertEquals("barfoo", fooCall("bar"));
    assertEquals("barfoo", fooDirect("bar"));
    assertEquals("barfoo", fooRoundTrip(getFooFunc(), "bar"));

    String sFooString = getsFooFunc().toString();
    assertEquals(sFooString, sFooFuncAsStr());
    assertEquals(sFooString, sFooFuncToString());
    String fooString = getFooFunc().toString();
    assertEquals(fooString, fooFuncAsStr());
    assertEquals(fooString, fooFuncToString());
  }

  public void testGenerics() {
    String s = genericSimple("test");
    assertEquals("test", s);
    String v = genericGet(s);
    assertEquals("test", v);
    List<String> list = new ArrayList<String>();
    list.add("foo");
    Object obj = genericWildcard(list);
    assertTrue(obj instanceof String);
    assertEquals("foo", obj);
    obj = genericSubtype("test");
    List<Object> list2 = genericSubtype(new TestGenericList());
    assertTrue(list2 instanceof TestGenericList);
    assertEquals(42, list2.size());
    assertEquals(list2, list2.get(0));
    String[] array = new String[] {"foo", "bar"};
    String[] ret = genericArray(array);
    assertEquals(2, ret.length);
    assertEquals("bar", ret[1]);
    assertTrue(Arrays.deepEquals(array, ret));
  }

  /**
   * Tests that we are able to use binary and source level names when
   * referencing a Java identifier from JSNI.
   */
  public void testJavaMemberRefResolution() {
    A.B b = new A.B();
    assertEquals(1, b.getUsingSourceRef());
    assertEquals(1, b.getUsingBinaryRef());
  }

  public void testJavaObjectIdentityInJS() {
    Object o = new Object();
    assertTrue(jsIdentical(o, o));
    assertTrue(jsniInstanceFunctionsIdentical(o));
    assertTrue(jsniStaticFunctionsIdentical());
  }

  public void testJsniFormats() {
    jsniA();
    jsniB();
    jsniC();
    jsniD();
    jsniE();
    jsniF();
    jsniG();
    jsniH();
    jsniI();
    jsniJ();
    jsniK();
    jsniL();
  }

  /**
   * Tests passing primitive type arguments to JSNI methods. See issue 2426.
   */
  public void testJsniParamUnboxedPrimitives() {
    class Inner {
      native boolean nativeJsniParamUnboxedBoolean(boolean param) /*-{
        return (param == true);
      }-*/;

      native boolean nativeJsniParamUnboxedByte(byte param) /*-{
        return (param == 99);
      }-*/;

      native boolean nativeJsniParamUnboxedCharacter(char param) /*-{
        return (param == 77);
      }-*/;

      native boolean nativeJsniParamUnboxedDouble(double param) /*-{
        return (param == 1234.56789);
      }-*/;

      native boolean nativeJsniParamUnboxedFloat(float param) /*-{
        return (param == 1234.5);
      }-*/;

      native boolean nativeJsniParamUnboxedInteger(int param) /*-{
        return (param == 9876543);
      }-*/;

      native boolean nativeJsniParamUnboxedShort(short param) /*-{
        return (param == 1234);
      }-*/;
    }
    Inner inner = new Inner();

    assertTrue("Unboxed boolean", inner.nativeJsniParamUnboxedBoolean(true));
    assertTrue("Unboxed byte", inner.nativeJsniParamUnboxedByte((byte) 99));
    assertTrue("Unboxed char", inner.nativeJsniParamUnboxedCharacter((char) 77));
    assertTrue("Unboxed double", inner.nativeJsniParamUnboxedDouble(1234.56789));
    assertTrue("Unboxed float",
        inner.nativeJsniParamUnboxedFloat((float) 1234.5));
    assertTrue("Unboxed int", inner.nativeJsniParamUnboxedInteger(9876543));
    // long type intentionally omitted - it is emulated and not usable in JS
    assertTrue("Unboxed short", inner.nativeJsniParamUnboxedShort((short) 1234));
  }

  /**
   * More test cases resulting from issue 2426 to show that primitives can be
   * passed through JSNI methods unmolested.
   */
  public void testJsniPassthroughPrimitives() {
    class Inner {
      native boolean nativeBoolean(boolean param) /*-{
        return param;
      }-*/;

      native byte nativeByte(byte param) /*-{
        return param;
      }-*/;

      native char nativeCharacter(char param) /*-{
        return param;
      }-*/;

      native double nativeDouble(double param) /*-{
        return param;
      }-*/;

      native float nativeFloat(float param) /*-{
        return param;
      }-*/;

      native int nativeInteger(int param) /*-{
        return param;
      }-*/;

      @UnsafeNativeLong
      native long nativeLong(long param) /*-{
        return param;
      }-*/;

      native short nativeShort(short param) /*-{
        return param;
      }-*/;
    }
    Inner inner = new Inner();

    assertEquals("nativeBoolean", inner.nativeBoolean(true), true);
    assertEquals("nativeBoolean", inner.nativeBoolean(false), false);

    assertEquals("nativeByte", inner.nativeByte((byte) 0), (byte) 0);
    assertEquals("nativeByte", inner.nativeByte((byte) 1), (byte) 1);
    assertEquals("nativeByte", inner.nativeByte((byte) -1), (byte) -1);
    assertEquals("nativeByte", inner.nativeByte((byte) 127), (byte) 127);
    assertEquals("nativeByte", inner.nativeByte((byte) -127), (byte) -127);
    assertEquals("nativeByte", inner.nativeByte(Byte.MAX_VALUE), Byte.MAX_VALUE);
    assertEquals("nativeByte", inner.nativeByte(Byte.MIN_VALUE), Byte.MIN_VALUE);

    assertEquals("nativeCharacter", inner.nativeCharacter((char) 0), (char) 0);
    assertEquals("nativeCharacter", inner.nativeCharacter((char) 1), (char) 1);
    assertEquals("nativeCharacter", inner.nativeCharacter((char) -1), (char) -1);
    assertEquals("nativeCharacter", inner.nativeCharacter((char) 32767),
        (char) 32767);
    assertEquals("nativeCharacter", inner.nativeCharacter((char) -32767),
        (char) -32767);
    assertEquals("nativeCharacter", inner.nativeCharacter(Character.MAX_VALUE),
        Character.MAX_VALUE);
    assertEquals("nativeCharacter", inner.nativeCharacter(Character.MIN_VALUE),
        Character.MIN_VALUE);

    assertEquals("nativeDouble", inner.nativeDouble(0.0), 0.0);
    assertEquals("nativeDouble", inner.nativeDouble(1.0), 1.0);
    assertEquals("nativeDouble", inner.nativeDouble(-1.0), -1.0);
    assertEquals("nativeDouble", inner.nativeDouble(100000000000.0),
        100000000000.0);
    assertEquals("nativeDouble", inner.nativeDouble(-100000000000.0),
        -100000000000.0);
    assertEquals("nativeDouble MAX", inner.nativeDouble(Double.MAX_VALUE),
        Double.MAX_VALUE);
    assertEquals("nativeDouble MIN", inner.nativeDouble(Double.MIN_VALUE),
        Double.MIN_VALUE);

    assertEquals("nativeFloat", inner.nativeFloat((float) 0.0), (float) 0.0);
    assertEquals("nativeFloat", inner.nativeFloat((float) 1.0), (float) 1.0);
    assertEquals("nativeFloat", inner.nativeFloat((float) -1.0), (float) -1.0);
    assertEquals("nativeFloat", inner.nativeFloat((float) 1000000.0),
        (float) 1000000.0);
    assertEquals("nativeFloat", inner.nativeFloat((float) -1000000.0),
        (float) -1000000.0);
    assertEquals("nativeFloat", inner.nativeFloat(Float.MAX_VALUE),
        Float.MAX_VALUE);
    assertEquals("nativeFloat", inner.nativeFloat(Float.MIN_VALUE),
        Float.MIN_VALUE);

    assertEquals("nativeInteger", inner.nativeInteger(0), 0);
    assertEquals("nativeInteger", inner.nativeInteger(1), 1);
    assertEquals("nativeInteger", inner.nativeInteger(-1), -1);
    assertEquals("nativeInteger", inner.nativeInteger(2147483647), 2147483647);
    assertEquals("nativeInteger", inner.nativeInteger(-2147483647), -2147483647);
    assertEquals("nativeInteger MAX", inner.nativeInteger(Integer.MAX_VALUE),
        Integer.MAX_VALUE);
    assertEquals("nativeInteger MIN", inner.nativeInteger(Integer.MIN_VALUE),
        Integer.MIN_VALUE);

    assertEquals("nativeLong", inner.nativeLong(0L), 0L);
    assertEquals("nativeLong", inner.nativeLong(1L), 1L);
    assertEquals("nativeLong", inner.nativeLong(-1L), -1L);
    assertEquals("nativeLong", inner.nativeLong(9223372036854775807L),
        9223372036854775807L);
    assertEquals("nativeLong", inner.nativeLong(-9223372036854775807L),
        -9223372036854775807L);
    assertEquals("nativeLong", inner.nativeLong(Long.MAX_VALUE), Long.MAX_VALUE);
    assertEquals("nativeLong", inner.nativeLong(Long.MIN_VALUE), Long.MIN_VALUE);

    assertEquals("nativeShort", inner.nativeShort((short) 0), (short) 0);
    assertEquals("nativeShort", inner.nativeShort((short) 1), (short) 1);
    assertEquals("nativeShort", inner.nativeShort((short) -1), (short) -1);
    assertEquals("nativeShort", inner.nativeShort((short) 32767), (short) 32767);
    assertEquals("nativeShort", inner.nativeShort((short) -32767),
        (short) -32767);
    assertEquals("nativeShort MAX", inner.nativeShort(Short.MAX_VALUE),
        Short.MAX_VALUE);
    assertEquals("nativeShort MIN", inner.nativeLong(Short.MIN_VALUE),
        Short.MIN_VALUE);
  }

  /**
   * Tests returning primitive type arguments from JSNI methods. See issue 2426.
   */
  public void testJsniReturnUnboxedPrimitives() {
    class Inner {
      native boolean nativeJsniReturnUnboxedBoolean() /*-{
        return true;
      }-*/;

      native byte nativeJsniReturnUnboxedByte() /*-{
        return 99;
      }-*/;

      native char nativeJsniReturnUnboxedCharacter() /*-{
        return 77;
      }-*/;

      native double nativeJsniReturnUnboxedDouble() /*-{
        return 1234.56789;
      }-*/;

      native float nativeJsniReturnUnboxedFloat() /*-{
        return 1234.5;
      }-*/;

      native int nativeJsniReturnUnboxedInteger() /*-{
        return 9876543;
      }-*/;

      native short nativeJsniReturnUnboxedShort() /*-{
        return 1234;
      }-*/;
    }
    Inner inner = new Inner();

    assertTrue("Unboxed boolean",
        inner.nativeJsniReturnUnboxedBoolean() == true);
    assertTrue("Unboxed byte", inner.nativeJsniReturnUnboxedByte() == (byte) 99);
    assertTrue("Unboxed char",
        inner.nativeJsniReturnUnboxedCharacter() == (char) 77);
    assertTrue("Unboxed double",
        inner.nativeJsniReturnUnboxedDouble() == 1234.56789);
    assertTrue("Unboxed float",
        inner.nativeJsniReturnUnboxedFloat() == (float) 1234.5);
    assertTrue("Unboxed int", inner.nativeJsniReturnUnboxedInteger() == 9876543);
    // long type intentionally omitted - it is emulated and not usable in JS
    assertTrue("Unboxed short",
        inner.nativeJsniReturnUnboxedShort() == (short) 1234);
  }

  /**
   * Tests that using the JavaScript toString method results in a call to the
   * java.lang.Object::toString() method.
   */
  public void testJSNIToStringResolution() {
    class Foo {
      @Override
      public String toString() {
        return "FOO";
      }
    }

    assertEquals("FOO", callJSNIToString(new Foo()));
  }

  /*
   * Test that returning strings from methods declared as returning Object
   * works, and that returning a primitive does not.
   */
  public void testObjectReturns() {
    String str = (String) getStringAsObject();
    assertEquals(str, "test");
    try {
      getIntAsObject();
      // should have thrown an exception in Development Mode,
      // so fail unless we are in Production Mode
      assertTrue(GWT.isScript());
    } catch (IllegalArgumentException e) {
      // expected exception
    }
  }

  public void testVarargs() {
    String[] strs = varargsHelper("foo", "bar");
    assertEquals(2, strs.length);
    assertEquals("bar", strs[1]);
    // TODO: not sure if we want to support this or not.
    // strs = varargsFromJS1();
    // assertEquals(2, strs.length);
    // assertEquals("bar", strs[1]);
    strs = varargsFromJS2(strs);
    assertEquals(2, strs.length);
    assertEquals("bar", strs[1]);
  }

  String foo(String s) {
    return s + "foo";
  }

  private native int byteAsInt(byte b) /*-{
    return b;
  }-*/;

  private native String callJSNIToString(Object obj) /*-{
    return obj.toString();
  }-*/;

  private native String enumName(TestEnum val) /*-{
    return val.@java.lang.Enum::name()();
  }-*/;

  private native TestEnum enumSimple(TestEnum val) /*-{
    return val;
  }-*/;

  private native int enumValue(TestEnum val) /*-{
    return val.@java.lang.Enum::ordinal()();
  }-*/;

  private native String fooCall(String s) /*-{
    var f = this.@com.google.gwt.dev.jjs.test.HostedTest::foo(Ljava/lang/String;);
    return f.call(this, s);
  }-*/;

  private native String fooDirect(String s) /*-{
    return this.@com.google.gwt.dev.jjs.test.HostedTest::foo(Ljava/lang/String;)(s);
  }-*/;

  private native String fooFuncAsStr() /*-{
    var f = this.@com.google.gwt.dev.jjs.test.HostedTest::foo(Ljava/lang/String;);
    return "" + f;
  }-*/;

  private native String fooFuncToString() /*-{
    var f = this.@com.google.gwt.dev.jjs.test.HostedTest::foo(Ljava/lang/String;);
    return f.toString();
  }-*/;

  private native String fooRoundTrip(JavaScriptObject fooFunc, String s) /*-{
    return fooFunc.call(this, s);
  }-*/;

  // Make this a JSNI method calling the Java method when that is implemented.
  private native <T> T[] genericArray(T[] array) /*-{
    // return genericPassthrough(array);
    return this.@com.google.gwt.dev.jjs.test.HostedTest::genericPassthrough([Ljava/lang/Object;)(array);
  }-*/;

  /*
   * Since we can't generate a generic instance from within JS, K and V have to
   * actually be compatible.
   */
  private native <K, V> V genericGet(K key) /*-{
    return key;
  }-*/;

  @SuppressWarnings("unused")
  // called by JSNI
  private <T> T[] genericPassthrough(T[] array) {
    return array;
  }

  // generics helper methods
  private native <T> T genericSimple(T val) /*-{
    return val;
  }-*/;

  private native <T, U extends T> T genericSubtype(U val) /*-{
    return val;
  }-*/;

  private native Object genericWildcard(List<?> list) /*-{
    return list.@java.util.List::get(I)(0);
  }-*/;

  private native JavaScriptObject getFooFunc() /*-{
    return this.@com.google.gwt.dev.jjs.test.HostedTest::foo(Ljava/lang/String;);
  }-*/;

  private native void jsniA()/*-{

  }-*/;

  private native void jsniB()/*-{

  }-*/;

  private native void jsniC()
  /*-{

  }-*/;

  private native void jsniD()
  /*-{

  }-*/;

  /**
   * comment.
   */
  private native void jsniE()/*-{

  }-*/;

  /** comment. */
  private native void jsniF()/*-{

  }-*/;

  /** comment. */
  private native void jsniG()/*-{

  }-*/;

  /*
   * comment
   */
  private native void jsniH()/*-{

  }-*/;

  /* comment */private native void jsniI()/*-{

  }-*/;

  // comment
  private native void jsniJ()/*-{

  }-*/;

  private native void jsniK()
  /*-{

  }-*/;

  /*-{
    try to mess with compiler
  }-*/
  private native void jsniL()/*-{

  }-*/;

  // test that JS can pass a series of arguments to a varargs function
  // TODO: not sure if we want to support this
  // private native String[] varargsFromJS1() /*-{
  // return
  // this.@com.google.gwt.dev.jjs.test.HostedTest::varargsPassthrough([Ljava/lang
  // /String;)("foo",
  // "bar");
  // }-*/;

  // test that JS can pass a Java-created array to a varargs function
  private native String[] varargsFromJS2(String[] arr) /*-{
    return this.@com.google.gwt.dev.jjs.test.HostedTest::varargsPassthrough([Ljava/lang/String;)(arr);
  }-*/;

  private native String[] varargsHelper(String... args) /*-{
    return args;
  }-*/;

  @SuppressWarnings("unused")
  // called from JSNI
  private String[] varargsPassthrough(String... args) {
    return args;
  }

}
