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 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]));
  }
  @Override
  public void endVisit(CompilationUnit unit) {
    for (SuperMethodBindingPair superMethod : superMethods) {
      String funcName = getSuperFunctionName(superMethod);
      String signature = getSuperFunctionSignature(superMethod.method);

      // Add declarations for the function pointers to call.
      unit.getNativeBlocks()
          .add(
              NativeDeclaration.newOuterDeclaration(
                  null, "static " + UnicodeUtils.format(signature, funcName) + ";"));

      // Look up the implementations in the static initialization.
      AbstractTypeDeclaration typeNode = typeMap.get(superMethod.type.getTypeDeclaration());
      assert typeNode != null : "Type is expected to be in this compilation unit";
      String superclassName = nameTable.getFullName(superMethod.type.getSuperclass());
      typeNode
          .getClassInitStatements()
          .add(
              0,
              new NativeStatement(
                  UnicodeUtils.format(
                      "%s = (%s)[%s instanceMethodForSelector:@selector(%s)];",
                      funcName,
                      UnicodeUtils.format(signature, ""),
                      superclassName,
                      nameTable.getMethodSelector(superMethod.method))));
    }
  }
示例#7
0
 public void testVariableDeclarationsInSwitchStatement2() throws IOException {
   CompilationUnit unit =
       translateType(
           "A",
           "public class A { public void doSomething(int i) { switch (i) { "
               + "case 1: int j = i * 2; log(j); break; "
               + "case 2: log(i); break; "
               + "case 3: log(i); int k = i, l = 42; break; }}"
               + "private void log(int i) {}}");
   TypeDeclaration testType = (TypeDeclaration) unit.getTypes().get(0);
   MethodDeclaration method = TreeUtil.getMethodDeclarationsList(testType).get(0);
   List<Statement> stmts = method.getBody().getStatements();
   assertEquals(1, stmts.size());
   Block block = (Block) stmts.get(0);
   stmts = block.getStatements();
   assertEquals(3, stmts.size());
   assertTrue(stmts.get(0) instanceof VariableDeclarationStatement);
   assertTrue(stmts.get(1) instanceof VariableDeclarationStatement);
   assertTrue(stmts.get(2) instanceof SwitchStatement);
 }
示例#8
0
  /**
   * Verify that interface methods declaring methods implemented by super-class have a forwarding
   * method.
   */
  public void testInterfaceOfSuperclassMethodInAnonymousInner() {
    String source =
        "interface Equateable { boolean equals(Object o); }"
            + "public class Test { public void foo() { Equateable e = new Equateable() { }; } } ";
    CompilationUnit unit = translateType("Test", source);
    assertEquals(3, unit.getTypes().size());
    TypeDeclaration innerType = (TypeDeclaration) unit.getTypes().get(2);
    assertEquals("$1", innerType.getName().toString());

    List<MethodDeclaration> methods = TreeUtil.getMethodDeclarationsList(innerType);
    assertEquals(2, methods.size()); // isEqual, init
    MethodDeclaration equalsMethod = methods.get(0);
    assertEquals("isEqual", equalsMethod.getName().getIdentifier());
    assertEquals(1, equalsMethod.getParameters().size());
    assertTrue(equalsMethod.getParameters().get(0) instanceof SingleVariableDeclaration);
    List<Statement> stmts = equalsMethod.getBody().getStatements();
    assertEquals(1, stmts.size());
    Statement stmt = stmts.get(0);
    assertTrue(stmt instanceof ReturnStatement);
    assertTrue(((ReturnStatement) stmt).getExpression() instanceof SuperMethodInvocation);
  }
示例#9
0
  /** Verify that super-interface methods are also added. */
  public void testAbstractClassGrandfatherInterface() {
    String source =
        "public class Test {"
            + "  public interface I1 { void foo(); } "
            + "  public interface I2 extends I1 { void bar(); } "
            + "  public abstract class Inner implements I2 { } }";
    CompilationUnit unit = translateType("Test", source);
    List<AbstractTypeDeclaration> types = unit.getTypes();
    assertEquals(4, types.size());
    assertTrue(types.get(3) instanceof TypeDeclaration);
    TypeDeclaration innerType = (TypeDeclaration) types.get(3);
    assertEquals("Inner", innerType.getName().toString());

    List<MethodDeclaration> methods = TreeUtil.getMethodDeclarationsList(innerType);
    assertEquals(3, methods.size());
    String name0 = methods.get(0).getName().getIdentifier();
    assertTrue(name0.matches("foo|bar"));
    String name1 = methods.get(1).getName().getIdentifier();
    assertTrue(name1.matches("foo|bar"));
    assertNotSame(name0, name1);
  }
示例#10
0
  /** List has a toArray() method that uses array types. */
  public void testAbstractMethodsAddedWithArrayType() {
    String source =
        "import java.util.List; public abstract class Test implements List<Object> { "
            + "public boolean isEmpty() { return true; } }";
    CompilationUnit unit = translateType("Test", source);
    List<AbstractTypeDeclaration> types = unit.getTypes();
    assertEquals(1, types.size());
    assertTrue(types.get(0) instanceof TypeDeclaration);
    TypeDeclaration testType = (TypeDeclaration) types.get(0);
    List<MethodDeclaration> methods = TreeUtil.getMethodDeclarationsList(testType);
    assertEquals(26, methods.size());

    // verify added methods are abstract, and that existing method wasn't changed
    for (MethodDeclaration m : methods) {
      int modifiers = m.getModifiers();
      String name = m.getName().getIdentifier();
      if (name.equals("isEmpty")) {
        assertFalse(Modifier.isAbstract(modifiers));
      } else if (name.equals(NameTable.FINALIZE_METHOD)
          || name.equals(NameTable.DEALLOC_METHOD)
          || name.equals(NameTable.INIT_NAME)) {
        // it's ok.
      } else {
        // it's an added method
        assertTrue(Modifier.isAbstract(modifiers));
        ITypeBinding returnType = m.getReturnType().getTypeBinding();
        if (name.equals("toArray")) {
          assertEquals("IOSObjectArray", returnType.getName());
          if (!m.getParameters().isEmpty()) {
            assertEquals(1, m.getParameters().size());
            SingleVariableDeclaration param = m.getParameters().get(0);
            IVariableBinding paramBinding = param.getVariableBinding();
            assertTrue(paramBinding.getType().isArray());
          }
        }
      }
    }
  }
示例#11
0
  /** Verifies that abstract methods to implement an interface are added to an abstract class. */
  public void testAbstractMethodsAdded() {
    String source =
        "import java.util.Iterator; public abstract class Test implements Iterator<Test> { "
            + "public boolean hasNext() { return true; } }";
    CompilationUnit unit = translateType("Test", source);
    List<AbstractTypeDeclaration> types = unit.getTypes();
    assertEquals(1, types.size());
    assertTrue(types.get(0) instanceof TypeDeclaration);
    TypeDeclaration testType = (TypeDeclaration) types.get(0);
    List<MethodDeclaration> methods = TreeUtil.getMethodDeclarationsList(testType);
    assertEquals(4, methods.size());

    // verify added methods are abstract, and that existing method wasn't changed
    for (MethodDeclaration m : methods) {
      int modifiers = m.getModifiers();
      String name = m.getName().getIdentifier();
      if (name.equals("hasNext")) {
        assertFalse(Modifier.isAbstract(modifiers));
      } else if (name.equals(NameTable.FINALIZE_METHOD)
          || name.equals(NameTable.DEALLOC_METHOD)
          || name.equals(NameTable.INIT_NAME)) {
        // it's ok.
      } else {
        // it's an added method
        assertTrue(Modifier.isAbstract(modifiers));
        assertEquals(0, m.getParameters().size());
        if (name.equals("next")) {
          assertEquals(testType.getTypeBinding(), m.getReturnType().getTypeBinding());
        } else if (name.equals("remove")) {
          ITypeBinding voidType = Types.resolveJavaType("void");
          assertEquals(voidType, m.getReturnType().getTypeBinding());
        } else {
          fail("unknown method added: " + name);
        }
      }
    }
  }
  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]));
  }