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