Support for reflection on primitive types. All tests finish in the browser. launcher
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 20 Dec 2012 08:59:47 +0100
branchlauncher
changeset 355eea0065bcc1a
parent 354 002b7c3d5157
child 356 e078953818d2
Support for reflection on primitive types. All tests finish in the browser.
emul/src/main/java/java/lang/Class.java
emul/src/main/java/java/lang/reflect/Method.java
javap/src/main/java/org/apidesign/javap/ClassData.java
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.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
vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java
     1.1 --- a/emul/src/main/java/java/lang/Class.java	Wed Dec 19 16:43:37 2012 +0100
     1.2 +++ b/emul/src/main/java/java/lang/Class.java	Thu Dec 20 08:59:47 2012 +0100
     1.3 @@ -287,7 +287,12 @@
     1.4       * @return  {@code true} if this object represents an interface;
     1.5       *          {@code false} otherwise.
     1.6       */
     1.7 -    public native boolean isInterface();
     1.8 +    public boolean isInterface() {
     1.9 +        return (getAccess() & 0x200) != 0;
    1.10 +    }
    1.11 +    
    1.12 +    @JavaScriptBody(args = "self", body = "return self.access;")
    1.13 +    private native int getAccess();
    1.14  
    1.15  
    1.16      /**
     2.1 --- a/emul/src/main/java/java/lang/reflect/Method.java	Wed Dec 19 16:43:37 2012 +0100
     2.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java	Thu Dec 20 08:59:47 2012 +0100
     2.3 @@ -524,13 +524,34 @@
     2.4  
     2.5      private static Object fromPrimitive(Class<?> type, Object o) {
     2.6          if (type == Integer.TYPE) {
     2.7 -            return fromInteger(o);
     2.8 +            return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
     2.9          }
    2.10 -        return o;
    2.11 +        if (type == Long.TYPE) {
    2.12 +            return fromRaw(Long.class, "valueOf__Ljava_lang_Long_2J", o);
    2.13 +        }
    2.14 +        if (type == Double.TYPE) {
    2.15 +            return fromRaw(Double.class, "valueOf__Ljava_lang_Double_2D", o);
    2.16 +        }
    2.17 +        if (type == Float.TYPE) {
    2.18 +            return fromRaw(Float.class, "valueOf__Ljava_lang_Float_2F", o);
    2.19 +        }
    2.20 +        if (type == Byte.TYPE) {
    2.21 +            return fromRaw(Byte.class, "valueOf__Ljava_lang_Byte_2B", o);
    2.22 +        }
    2.23 +        if (type == Boolean.TYPE) {
    2.24 +            return fromRaw(Boolean.class, "valueOf__Ljava_lang_Boolean_2Z", o);
    2.25 +        }
    2.26 +        if (type == Short.TYPE) {
    2.27 +            return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
    2.28 +        }
    2.29 +//            case 'V': return Void.TYPE;
    2.30 +        throw new IllegalStateException("Can't convert " + o);
    2.31      }
    2.32      
    2.33 -    @JavaScriptBody(args = "o", body = "return vm.java_lang_Integer(false).valueOf__Ljava_lang_Integer_2I(o);")
    2.34 -    private static native Integer fromInteger(Object o);
    2.35 +    @JavaScriptBody(args = { "cls", "m", "o" }, 
    2.36 +        body = "return cls.cnstr(false)[m](o);"
    2.37 +    )
    2.38 +    private static native Integer fromRaw(Class<?> cls, String m, Object o);
    2.39      
    2.40      /**
    2.41       * Returns {@code true} if this method is a bridge
     3.1 --- a/javap/src/main/java/org/apidesign/javap/ClassData.java	Wed Dec 19 16:43:37 2012 +0100
     3.2 +++ b/javap/src/main/java/org/apidesign/javap/ClassData.java	Thu Dec 20 08:59:47 2012 +0100
     3.3 @@ -326,6 +326,10 @@
     3.4              return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
     3.5          }
     3.6      }
     3.7 +    
     3.8 +    public int getAccessFlags() {
     3.9 +        return access;
    3.10 +    }
    3.11  
    3.12      /**
    3.13       * Returns true if it is a class
     4.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java	Wed Dec 19 16:43:37 2012 +0100
     4.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java	Thu Dec 20 08:59:47 2012 +0100
     4.3 @@ -56,11 +56,6 @@
     4.4          setAttr("result", "value", res);
     4.5      }
     4.6      
     4.7 -    @JavaScriptBody(args = "o", body = "return '' + o;")
     4.8 -    private static String tS(Object o) {
     4.9 -        return o.toString();
    4.10 -    }
    4.11 -    
    4.12      public static void harness(String url) {
    4.13          log("Connecting to " + url);
    4.14          try {
    4.15 @@ -77,13 +72,10 @@
    4.16                  log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
    4.17  
    4.18                  Object result = invokeMethod(c.getClassName(), c.getMethodName());
    4.19 -
    4.20 +                
    4.21                  log("Result: " + result);
    4.22 -                
    4.23 -                String toSend = tS(result);
    4.24 -                
    4.25 -                log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + toSend);
    4.26 -                u = new URL(url + "?request=" + c.getRequestId() + "&result=" + toSend);
    4.27 +                log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
    4.28 +                u = new URL(url + "?request=" + c.getRequestId() + "&result=" + result);
    4.29              }
    4.30              
    4.31              
     5.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Dec 19 16:43:37 2012 +0100
     5.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Thu Dec 20 08:59:47 2012 +0100
     5.3 @@ -155,6 +155,7 @@
     5.4          out.append(accessClass("java_lang_Class(true);"));
     5.5          out.append("\n    CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
     5.6          out.append("\n    CLS.$class.superclass = sprcls;");
     5.7 +        out.append("\n    CLS.$class.access = ").append(jc.getAccessFlags()+";");
     5.8          out.append("\n    CLS.$class.cnstr = CLS;");
     5.9          byte[] classAnno = jc.findAnnotationData(false);
    5.10          if (classAnno != null) {
     6.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java	Wed Dec 19 16:43:37 2012 +0100
     6.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java	Thu Dec 20 08:59:47 2012 +0100
     6.3 @@ -103,8 +103,14 @@
     6.4      }
     6.5      @Test public void primitiveReturnType() throws Exception {
     6.6          assertExec("Tries to get an integer via reflection", Classes.class, 
     6.7 -            "primitiveType__Ljava_lang_String_2", 
     6.8 -            Classes.primitiveType()
     6.9 +            "primitiveType__Ljava_lang_String_2Ljava_lang_String_2", 
    6.10 +            Classes.primitiveType("primitive"), "primitive"
    6.11 +        );
    6.12 +    }
    6.13 +    @Test public void primitiveBoolReturnType() throws Exception {
    6.14 +        assertExec("Tries to get an integer via reflection", Classes.class, 
    6.15 +            "primitiveType__Ljava_lang_String_2Ljava_lang_String_2", 
    6.16 +            Classes.primitiveType("primitiveB"), "primitiveB"
    6.17          );
    6.18      }
    6.19      @Test public void javaAnnotatedMethod() throws Exception {
    6.20 @@ -122,7 +128,20 @@
    6.21              "java.io.IOException"
    6.22          );
    6.23      }
    6.24 -    
    6.25 +    @Test public void noInterface() throws Exception {
    6.26 +        assertExec("Calls Class.isInterface", Classes.class, 
    6.27 +            "isInterface__ZLjava_lang_String_2", 
    6.28 +            0.0, "java.lang.String"
    6.29 +        );
    6.30 +    }
    6.31 +    /*
    6.32 +    @Test public void isInterface() throws Exception {
    6.33 +        assertExec("Calls Class.isInterface", Classes.class, 
    6.34 +            "isInterface__ZLjava_lang_String_2", 
    6.35 +            1.0, "java.lang.Runnable"
    6.36 +        );
    6.37 +    }
    6.38 +    */
    6.39      @Test public void integerType() throws Exception {
    6.40          assertExec("Computes the type", Classes.class, 
    6.41              "intType__Ljava_lang_String_2", 
     7.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Wed Dec 19 16:43:37 2012 +0100
     7.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Thu Dec 20 08:59:47 2012 +0100
     7.3 @@ -38,6 +38,10 @@
     7.4          return c.getName();
     7.5      }
     7.6      
     7.7 +    public static boolean isInterface(String s) throws ClassNotFoundException {
     7.8 +        return Class.forName(s).isInterface();
     7.9 +    }
    7.10 +    
    7.11      public static boolean equalsClassesOfExceptions() {
    7.12          return MalformedURLException.class.getSuperclass() == IOException.class;
    7.13      }
    7.14 @@ -95,9 +99,12 @@
    7.15      public static int primitive() {
    7.16          return 1;
    7.17      }
    7.18 +    public static boolean primitiveB() {
    7.19 +        return true;
    7.20 +    }
    7.21      
    7.22 -    public static String primitiveType() throws Exception {
    7.23 -        return reflectiveMethodCall(false, "primitive").getClass().getName();
    7.24 +    public static String primitiveType(String method) throws Exception {
    7.25 +        return reflectiveMethodCall(false, method).getClass().getName();
    7.26      }
    7.27      
    7.28      @JavaScriptBody(args = "msg", body = "throw msg;")
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Thu Dec 20 08:59:47 2012 +0100
     8.3 @@ -0,0 +1,43 @@
     8.4 +/**
     8.5 + * Back 2 Browser Bytecode Translator
     8.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     8.7 + *
     8.8 + * This program is free software: you can redistribute it and/or modify
     8.9 + * it under the terms of the GNU General Public License as published by
    8.10 + * the Free Software Foundation, version 2 of the License.
    8.11 + *
    8.12 + * This program is distributed in the hope that it will be useful,
    8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.15 + * GNU General Public License for more details.
    8.16 + *
    8.17 + * You should have received a copy of the GNU General Public License
    8.18 + * along with this program. Look for COPYING file in the top folder.
    8.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    8.20 + */
    8.21 +package org.apidesign.bck2brwsr.tck;
    8.22 +
    8.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
    8.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
    8.25 +import org.testng.annotations.Factory;
    8.26 +
    8.27 +/**
    8.28 + *
    8.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    8.30 + */
    8.31 +public class ReflectionTest {
    8.32 +    @Compare public String intType() {
    8.33 +        return Integer.TYPE.toString();
    8.34 +    }
    8.35 +
    8.36 +    @Compare public String longClass() {
    8.37 +        return long.class.toString();
    8.38 +    }
    8.39 +    
    8.40 +    
    8.41 +    @Factory
    8.42 +    public static Object[] create() {
    8.43 +        return VMTest.create(ReflectionTest.class);
    8.44 +    }
    8.45 +    
    8.46 +}