emul/src/main/java/java/lang/reflect/Method.java
changeset 418 c0bbf144c2c6
parent 416 b2464b3fd015
child 420 3497ecd097df
     1.1 --- a/emul/src/main/java/java/lang/reflect/Method.java	Mon Jan 07 18:40:20 2013 +0100
     1.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java	Tue Jan 08 16:01:25 2013 +0100
     1.3 @@ -26,6 +26,7 @@
     1.4  package java.lang.reflect;
     1.5  
     1.6  import java.lang.annotation.Annotation;
     1.7 +import java.util.Enumeration;
     1.8  import org.apidesign.bck2brwsr.core.JavaScriptBody;
     1.9  import org.apidesign.bck2brwsr.emul.AnnotationImpl;
    1.10  import org.apidesign.bck2brwsr.emul.MethodImpl;
    1.11 @@ -140,24 +141,7 @@
    1.12       * @return the return type for the method this object represents
    1.13       */
    1.14      public Class<?> getReturnType() {
    1.15 -        switch (sig.charAt(0)) {
    1.16 -            case 'I': return Integer.TYPE;
    1.17 -            case 'J': return Long.TYPE;
    1.18 -            case 'D': return Double.TYPE;
    1.19 -            case 'F': return Float.TYPE;
    1.20 -            case 'B': return Byte.TYPE;
    1.21 -            case 'Z': return Boolean.TYPE;
    1.22 -            case 'S': return Short.TYPE;
    1.23 -            case 'V': return Void.TYPE;
    1.24 -            case 'L': try {
    1.25 -                int up = sig.indexOf("_2");
    1.26 -                String type = sig.substring(1, up);
    1.27 -                return Class.forName(type);
    1.28 -            } catch (ClassNotFoundException ex) {
    1.29 -                // should not happen
    1.30 -            }
    1.31 -        }
    1.32 -        throw new UnsupportedOperationException(sig);
    1.33 +        return MethodImpl.signatureParser(sig).nextElement();
    1.34      }
    1.35  
    1.36      /**
    1.37 @@ -199,8 +183,13 @@
    1.38       * represents
    1.39       */
    1.40      public Class<?>[] getParameterTypes() {
    1.41 -        throw new UnsupportedOperationException();
    1.42 -        //return (Class<?>[]) parameterTypes.clone();
    1.43 +        Class[] arr = new Class[MethodImpl.signatureElements(sig) - 1];
    1.44 +        Enumeration<Class> en = MethodImpl.signatureParser(sig);
    1.45 +        en.nextElement(); // return type
    1.46 +        for (int i = 0; i < arr.length; i++) {
    1.47 +            arr[i] = en.nextElement();
    1.48 +        }
    1.49 +        return arr;
    1.50      }
    1.51  
    1.52      /**
    1.53 @@ -512,21 +501,41 @@
    1.54          throws IllegalAccessException, IllegalArgumentException,
    1.55             InvocationTargetException
    1.56      {
    1.57 -        if ((getModifiers() & Modifier.STATIC) == 0 && obj == null) {
    1.58 +        final boolean isStatic = (getModifiers() & Modifier.STATIC) == 0;
    1.59 +        if (isStatic && obj == null) {
    1.60              throw new NullPointerException();
    1.61          }
    1.62 -        Object res = invoke0(this, obj, args);
    1.63 +        Class[] types = getParameterTypes();
    1.64 +        if (types.length != args.length) {
    1.65 +            throw new IllegalArgumentException("Types len " + types.length + " args: " + args.length);
    1.66 +        } else {
    1.67 +            args = args.clone();
    1.68 +            for (int i = 0; i < types.length; i++) {
    1.69 +                Class c = types[i];
    1.70 +                if (c.isPrimitive()) {
    1.71 +                    args[i] = toPrimitive(c, args[i]);
    1.72 +                }
    1.73 +            }
    1.74 +        }
    1.75 +        Object res = invoke0(isStatic, this, obj, args);
    1.76          if (getReturnType().isPrimitive()) {
    1.77              res = fromPrimitive(getReturnType(), res);
    1.78          }
    1.79          return res;
    1.80      }
    1.81      
    1.82 -    @JavaScriptBody(args = { "method", "self", "args" }, body =
    1.83 -          "if (args.length > 0) throw 'unsupported now';"
    1.84 -        + "return method.fld_data(self);"
    1.85 +    @JavaScriptBody(args = { "st", "method", "self", "args" }, body =
    1.86 +          "var p;\n"
    1.87 +        + "if (st) {\n"
    1.88 +        + "  p = new Array(1);\n"
    1.89 +        + "  p[0] = self;\n"
    1.90 +        + "  p = p.concat(args);\n"
    1.91 +        + "} else {\n"
    1.92 +        + "  p = args;\n"
    1.93 +        + "}\n"
    1.94 +        + "return method.fld_data.apply(self, p);\n"
    1.95      )
    1.96 -    private static native Object invoke0(Method m, Object self, Object[] args);
    1.97 +    private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
    1.98  
    1.99      private static Object fromPrimitive(Class<?> type, Object o) {
   1.100          if (type == Integer.TYPE) {
   1.101 @@ -560,6 +569,39 @@
   1.102          body = "return cls.cnstr(false)[m](o);"
   1.103      )
   1.104      private static native Integer fromRaw(Class<?> cls, String m, Object o);
   1.105 +
   1.106 +    private static Object toPrimitive(Class<?> type, Object o) {
   1.107 +        if (type == Integer.TYPE) {
   1.108 +            return toRaw("intValue__I", o);
   1.109 +        }
   1.110 +        if (type == Long.TYPE) {
   1.111 +            return toRaw("longValue__J", o);
   1.112 +        }
   1.113 +        if (type == Double.TYPE) {
   1.114 +            return toRaw("doubleValue__D", o);
   1.115 +        }
   1.116 +        if (type == Float.TYPE) {
   1.117 +            return toRaw("floatValue__F", o);
   1.118 +        }
   1.119 +        if (type == Byte.TYPE) {
   1.120 +            return toRaw("byteValue__B", o);
   1.121 +        }
   1.122 +        if (type == Boolean.TYPE) {
   1.123 +            return toRaw("booleanValue__Z", o);
   1.124 +        }
   1.125 +        if (type == Short.TYPE) {
   1.126 +            return toRaw("shortValue__S", o);
   1.127 +        }
   1.128 +        if (type.getName().equals("void")) {
   1.129 +            return o;
   1.130 +        }
   1.131 +        throw new IllegalStateException("Can't convert " + o);
   1.132 +    }
   1.133 +    
   1.134 +    @JavaScriptBody(args = { "m", "o" }, 
   1.135 +        body = "return o[m](o);"
   1.136 +    )
   1.137 +    private static native Object toRaw(String m, Object o);
   1.138      
   1.139      /**
   1.140       * Returns {@code true} if this method is a bridge