Correct getDeclaringClass for returned methods reflection
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 03 Feb 2013 22:58:42 +0100
branchreflection
changeset 65426a86cc00224
parent 653 bcdfc29fd004
child 655 044c72732424
Correct getDeclaringClass for returned methods
emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/AnnotationImpl.java
emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java
vm/src/test/java/org/apidesign/vm4brwsr/Classes.java
     1.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/AnnotationImpl.java	Sun Feb 03 19:39:34 2013 +0100
     1.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/AnnotationImpl.java	Sun Feb 03 22:58:42 2013 +0100
     1.3 @@ -27,8 +27,14 @@
     1.4   * @author Jaroslav Tulach <jtulach@netbeans.org>
     1.5   */
     1.6  public final class AnnotationImpl implements Annotation {
     1.7 +    private final Class<? extends Annotation> type;
     1.8 +
     1.9 +    public AnnotationImpl(Class<? extends Annotation> type) {
    1.10 +        this.type = type;
    1.11 +    }
    1.12 +    
    1.13      public Class<? extends Annotation> annotationType() {
    1.14 -        return getClass();
    1.15 +        return type;
    1.16      }
    1.17  
    1.18      @JavaScriptBody(args = { "a", "n", "arr", "values" }, body = ""
    1.19 @@ -52,7 +58,7 @@
    1.20      );
    1.21      
    1.22      public static <T extends Annotation> T create(Class<T> annoClass, Object values) {
    1.23 -        return create(new AnnotationImpl(), 
    1.24 +        return create(new AnnotationImpl(annoClass), 
    1.25              annoClass.getName().replace('.', '_'), 
    1.26              findProps(annoClass), values
    1.27          );
    1.28 @@ -63,14 +69,14 @@
    1.29          Annotation[] ret = new Annotation[names.length];
    1.30          for (int i = 0; i < names.length; i++) {
    1.31              String annoNameSlash = names[i].substring(1, names[i].length() - 1);
    1.32 -            Class<?> annoClass;
    1.33 +            Class<? extends Annotation> annoClass;
    1.34              try {
    1.35 -                annoClass = Class.forName(annoNameSlash.replace('/', '.'));
    1.36 +                annoClass = (Class<? extends Annotation>)Class.forName(annoNameSlash.replace('/', '.'));
    1.37              } catch (ClassNotFoundException ex) {
    1.38                  throw new IllegalStateException("Can't find annotation class " + annoNameSlash);
    1.39              }
    1.40              ret[i] = create(
    1.41 -                new AnnotationImpl(), 
    1.42 +                new AnnotationImpl(annoClass), 
    1.43                  annoNameSlash.replace('/', '_'),
    1.44                  findProps(annoClass),
    1.45                  findData(anno, names[i])
     2.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Sun Feb 03 19:39:34 2013 +0100
     2.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Sun Feb 03 22:58:42 2013 +0100
     2.3 @@ -56,8 +56,10 @@
     2.4          + "var arr = new Array();\n"
     2.5          + "for (m in c) {\n"
     2.6          + "  if (m.indexOf(prefix) === 0) {\n"
     2.7 +        + "     if (!c[m].cls) continue;\n"
     2.8          + "     arr.push(m);\n"
     2.9          + "     arr.push(c[m]);\n"
    2.10 +        + "     arr.push(c[m].cls.$class);\n"
    2.11          + "  }"
    2.12          + "}\n"
    2.13          + "return arr;")
    2.14 @@ -67,9 +69,10 @@
    2.15      public static Method findMethod(
    2.16          Class<?> clazz, String name, Class<?>... parameterTypes) {
    2.17          Object[] data = findMethodData(clazz, name + "__");
    2.18 -        BIG: for (int i = 0; i < data.length; i += 2) {
    2.19 -            String sig = ((String) data[0]).substring(name.length() + 2);
    2.20 -            Method tmp = INSTANCE.create(clazz, name, data[1], sig);
    2.21 +        BIG: for (int i = 0; i < data.length; i += 3) {
    2.22 +            String sig = ((String) data[i]).substring(name.length() + 2);
    2.23 +            Class<?> cls = (Class<?>) data[i + 2];
    2.24 +            Method tmp = INSTANCE.create(cls, name, data[i + 1], sig);
    2.25              Class<?>[] tmpParms = tmp.getParameterTypes();
    2.26              if (parameterTypes.length != tmpParms.length) {
    2.27                  continue;
    2.28 @@ -87,7 +90,7 @@
    2.29      public static Method[] findMethods(Class<?> clazz, int mask) {
    2.30          Object[] namesAndData = findMethodData(clazz, "");
    2.31          int cnt = 0;
    2.32 -        for (int i = 0; i < namesAndData.length; i += 2) {
    2.33 +        for (int i = 0; i < namesAndData.length; i += 3) {
    2.34              String sig = (String) namesAndData[i];
    2.35              Object data = namesAndData[i + 1];
    2.36              int middle = sig.indexOf("__");
    2.37 @@ -96,7 +99,8 @@
    2.38              }
    2.39              String name = sig.substring(0, middle);
    2.40              sig = sig.substring(middle + 2);
    2.41 -            final Method m = INSTANCE.create(clazz, name, data, sig);
    2.42 +            Class<?> cls = (Class<?>) namesAndData[i + 2];
    2.43 +            final Method m = INSTANCE.create(cls, name, data, sig);
    2.44              if ((m.getModifiers() & mask) == 0) {
    2.45                  continue;
    2.46              }
     3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Feb 03 19:39:34 2013 +0100
     3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Feb 03 22:58:42 2013 +0100
     3.3 @@ -175,6 +175,7 @@
     3.4                  out.append("\n    };");
     3.5              }
     3.6              out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";");
     3.7 +            out.append(prefix).append(mn).append(".cls = CLS;");
     3.8          }
     3.9          out.append("\n    c.constructor = CLS;");
    3.10          out.append("\n    c.$instOf_").append(className).append(" = true;");
     4.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java	Sun Feb 03 19:39:34 2013 +0100
     4.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java	Sun Feb 03 22:58:42 2013 +0100
     4.3 @@ -93,6 +93,9 @@
     4.4      @Test public void jsEnumAnnotation() throws Exception {
     4.5          assertExec("Check enum annotation", Classes.class, "getMarkerE__Ljava_lang_String_2", Classes.getMarkerE());
     4.6      }
     4.7 +    @Test public void jsRetentionAnnotation() throws Exception {
     4.8 +        assertExec("Check enum annotation", Classes.class, "getRetention__Ljava_lang_String_2", Classes.getRetention());
     4.9 +    }
    4.10      @Test public void jsStringAnnotation() throws Exception {
    4.11          assertExec("Check class annotation", Classes.class, "getNamer__Ljava_lang_String_2Z", "my text", true);
    4.12      }
    4.13 @@ -108,6 +111,14 @@
    4.14              "java.io.IOException", true, "name"
    4.15          );
    4.16      }
    4.17 +    
    4.18 +    @Test public void jsMethodDeclaredInObject() throws Exception {
    4.19 +        assertExec("Defined in Object", Classes.class, 
    4.20 +            "objectName__Ljava_lang_String_2", 
    4.21 +            "java.lang.Object"
    4.22 +        );
    4.23 +    }
    4.24 +    
    4.25      @Test public void jsInvokeParamMethod() throws Exception {
    4.26          assertExec("sums two numbers via reflection", Classes.class, 
    4.27              "reflectiveSum__III", Double.valueOf(5), 2, 3
     5.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Sun Feb 03 19:39:34 2013 +0100
     5.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Sun Feb 03 22:58:42 2013 +0100
     5.3 @@ -19,6 +19,8 @@
     5.4  
     5.5  import java.io.IOException;
     5.6  import java.lang.annotation.Annotation;
     5.7 +import java.lang.annotation.ElementType;
     5.8 +import java.lang.annotation.Retention;
     5.9  import java.lang.annotation.RetentionPolicy;
    5.10  import java.lang.reflect.Method;
    5.11  import java.net.MalformedURLException;
    5.12 @@ -42,6 +44,7 @@
    5.13      private static final Class<?> PRELOAD = Runnable.class;
    5.14      private static final Class<?> PRELOAD2 = ClassesMarker.E.class;
    5.15      private static final Class<?> PRELOAD3 = RetentionPolicy.class;
    5.16 +    private static final Class<?> PRELOAD4 = ElementType.class;
    5.17      
    5.18      public static boolean isInterface(String s) throws ClassNotFoundException {
    5.19          return Class.forName(s).isInterface();
    5.20 @@ -70,6 +73,11 @@
    5.21      public static String canonicalName() {
    5.22          return IOException.class.getCanonicalName();
    5.23      }
    5.24 +    
    5.25 +    public static String objectName() throws NoSuchMethodException {
    5.26 +        return IOException.class.getMethod("wait").getDeclaringClass().getName();
    5.27 +    }
    5.28 +    
    5.29      public static boolean newInstance() throws Exception {
    5.30          IOException ioe = IOException.class.newInstance();
    5.31          if (ioe instanceof IOException) {
    5.32 @@ -103,6 +111,16 @@
    5.33          }
    5.34          return sb.toString().toString();
    5.35      }
    5.36 +    @Retention(RetentionPolicy.CLASS)
    5.37 +    @interface Ann {
    5.38 +    }
    5.39 +    
    5.40 +    public static String getRetention() throws Exception {
    5.41 +        Retention r = Ann.class.getAnnotation(Retention.class);
    5.42 +        assert r != null : "Annotation is present";
    5.43 +        assert r.value() == RetentionPolicy.CLASS : "Policy value is OK: " + r.value();
    5.44 +        return r.annotationType().getName();
    5.45 +    }
    5.46      public static String getMarkerE() {
    5.47          ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
    5.48          if (cm == null) {