public void testGenericInterface() throws IOException {
   CompilationUnit unit = translateType("A", "interface A<E> extends java.util.Collection<E> {}");
   List<AbstractTypeDeclaration> decls = unit.getTypes();
   assertEquals(1, decls.size());
   assertEquals(
       "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;",
       SignatureGenerator.createClassSignature(decls.get(0).getTypeBinding()));
 }
 public void testMultipleBounds() throws IOException {
   CompilationUnit unit =
       translateType("A", "class A <T extends Number & java.io.Serializable >{}");
   List<AbstractTypeDeclaration> decls = unit.getTypes();
   assertEquals(1, decls.size());
   assertEquals(
       "<T:Ljava/lang/Number;:Ljava/io/Serializable;>Ljava/lang/Object;",
       SignatureGenerator.createClassSignature(decls.get(0).getTypeBinding()));
 }
  public void testJniSignatures() throws IOException {
    CompilationUnit unit =
        translateType(
            "D",
            "package foo.bar; class D {"
                + "native void foo(int i, float f, String s);"
                + "native void a_b$c();"
                + "native void 你好世界();"
                + "native void bar();"
                + "native void bar(String s);"
                + "native void bar(boolean b, String s);"
                + "native void bar(String[] s); "
                + "static class 测试 { native void mumble(); }}");
    List<AbstractTypeDeclaration> decls = unit.getTypes();
    assertEquals(2, decls.size());
    IMethodBinding[] methods = decls.get(0).getTypeBinding().getDeclaredMethods();
    assertEquals(8, methods.length); // methods[0] is the default constructor.

    // Expected JNI signatures were copied from javah output.

    // Verify no parameters, since foo isn't overloaded.
    assertEquals("Java_foo_bar_D_foo", SignatureGenerator.createJniFunctionSignature(methods[6]));

    // Verify underscores and dollar signs in names are mangled.
    assertEquals(
        "Java_foo_bar_D_a_1b_00024c", SignatureGenerator.createJniFunctionSignature(methods[1]));

    // Verify Unicode characters are mangled.
    assertEquals(
        "Java_foo_bar_D__04f60_0597d_04e16_0754c",
        SignatureGenerator.createJniFunctionSignature(methods[7]));

    // Verify overloaded methods have parameter suffixes.
    assertEquals("Java_foo_bar_D_bar__", SignatureGenerator.createJniFunctionSignature(methods[2]));
    assertEquals(
        "Java_foo_bar_D_bar__Ljava_lang_String_2",
        SignatureGenerator.createJniFunctionSignature(methods[3]));
    assertEquals(
        "Java_foo_bar_D_bar__ZLjava_lang_String_2",
        SignatureGenerator.createJniFunctionSignature(methods[4]));
    assertEquals(
        "Java_foo_bar_D_bar___3Ljava_lang_String_2",
        SignatureGenerator.createJniFunctionSignature(methods[5]));

    // Check Unicode class name mangling.
    methods = decls.get(1).getTypeBinding().getDeclaredMethods();
    assertEquals(2, methods.length);
    assertEquals(
        "Java_foo_bar_D_00024_06d4b_08bd5_mumble",
        SignatureGenerator.createJniFunctionSignature(methods[1]));
  }
  public void testMethodSignatures() throws IOException {
    CompilationUnit unit =
        translateType(
            "A",
            "class A<X,Y> { "
                + "void a() {} "
                + "int b(boolean z) { return 0; } "
                + "void c(int i) throws IndexOutOfBoundsException {} "
                + "X d() { return null; } "
                + "void e(X x, Y y) {} "
                + "<T extends Throwable> void rethrow(Throwable t) {}"
                + "}");
    IMethodBinding[] methods = unit.getTypes().get(0).getTypeBinding().getDeclaredMethods();
    assertEquals(7, methods.length); // methods[0] is the default constructor.

    // Verify a, b and c don't return a signature, since they aren't generic types.
    assertNull(SignatureGenerator.createMethodTypeSignature(methods[1]));
    assertNull(SignatureGenerator.createMethodTypeSignature(methods[2]));
    assertNull(SignatureGenerator.createMethodTypeSignature(methods[3]));

    assertEquals("()TX;", SignatureGenerator.createMethodTypeSignature(methods[4]));
    assertEquals("(TX;TY;)V", SignatureGenerator.createMethodTypeSignature(methods[5]));
    assertEquals(
        "<T:Ljava/lang/Throwable;>(Ljava/lang/Throwable;)V",
        SignatureGenerator.createMethodTypeSignature(methods[6]));
  }
  public void testClassSignatures() throws IOException {
    CompilationUnit unit =
        translateType(
            "A",
            "import java.lang.ref.*; import java.util.concurrent.*; "
                + "class A {} "
                + "class B<X> {} "
                + "class C<X,Y,Z> {} "
                + "abstract class D extends java.util.AbstractList<String> {} "
                + "class E<C extends Comparable<? super C>> {}"
                + "class F extends WeakReference<ForkJoinTask<?>> { "
                + "  F(ForkJoinTask<?> task, Throwable ex, F next) { super(task, null); }}");
    List<AbstractTypeDeclaration> decls = unit.getTypes();
    assertEquals(6, decls.size());

    // Verify A doesn't return a signature, since it isn't a generic type.
    assertNull(SignatureGenerator.createClassSignature(decls.get(0).getTypeBinding()));

    assertEquals(
        "<X:Ljava/lang/Object;>Ljava/lang/Object;",
        SignatureGenerator.createClassSignature(decls.get(1).getTypeBinding()));
    assertEquals(
        "<X:Ljava/lang/Object;Y:Ljava/lang/Object;Z:Ljava/lang/Object;>Ljava/lang/Object;",
        SignatureGenerator.createClassSignature(decls.get(2).getTypeBinding()));
    assertEquals(
        "Ljava/util/AbstractList<Ljava/lang/String;>;",
        SignatureGenerator.createClassSignature(decls.get(3).getTypeBinding()));
    assertEquals(
        "<C::Ljava/lang/Comparable<-TC;>;>Ljava/lang/Object;",
        SignatureGenerator.createClassSignature(decls.get(4).getTypeBinding()));
    assertEquals(
        "Ljava/lang/ref/WeakReference<Ljava/util/concurrent/ForkJoinTask<*>;>;",
        SignatureGenerator.createClassSignature(decls.get(5).getTypeBinding()));
  }
  public void testFieldSignatures() throws IOException {
    CompilationUnit unit =
        translateType(
            "A",
            "class A<X,Y,Z> { int a; double[] b; X c; Y[] d; "
                + "Class<?> e; java.util.List<X> f; Comparable<? super X> g; "
                + "A<? extends Number, ?, String> h; }");
    IVariableBinding[] vars = unit.getTypes().get(0).getTypeBinding().getDeclaredFields();
    assertEquals(8, vars.length);

    // Verify a and b don't return a signature, since they aren't generic types.
    assertNull(SignatureGenerator.createFieldTypeSignature(vars[0]));
    assertNull(SignatureGenerator.createFieldTypeSignature(vars[1]));

    assertEquals("TX;", SignatureGenerator.createFieldTypeSignature(vars[2]));
    assertEquals("[TY;", SignatureGenerator.createFieldTypeSignature(vars[3]));
    assertEquals("Ljava/lang/Class<*>;", SignatureGenerator.createFieldTypeSignature(vars[4]));
    assertEquals("Ljava/util/List<TX;>;", SignatureGenerator.createFieldTypeSignature(vars[5]));
    assertEquals(
        "Ljava/lang/Comparable<-TX;>;", SignatureGenerator.createFieldTypeSignature(vars[6]));
    assertEquals(
        "LA<+Ljava/lang/Number;*Ljava/lang/String;>;",
        SignatureGenerator.createFieldTypeSignature(vars[7]));
  }