1.1 --- a/emul/src/main/java/java/lang/Class.java Tue Dec 04 15:32:18 2012 +0100
1.2 +++ b/emul/src/main/java/java/lang/Class.java Wed Dec 05 09:28:31 2012 +0100
1.3 @@ -616,7 +616,7 @@
1.4 * @since JDK1.1
1.5 */
1.6 public Method[] getMethods() throws SecurityException {
1.7 - throw new SecurityException();
1.8 + return Method.findMethods(this);
1.9 }
1.10
1.11 /**
2.1 --- a/emul/src/main/java/java/lang/String.java Tue Dec 04 15:32:18 2012 +0100
2.2 +++ b/emul/src/main/java/java/lang/String.java Wed Dec 05 09:28:31 2012 +0100
2.3 @@ -1767,7 +1767,7 @@
2.4 * or {@code -1} if there is no such occurrence.
2.5 */
2.6 @JavaScriptBody(args = { "self", "str", "fromIndex" }, body =
2.7 - "return self.toString().indexOf(str.toString(), fromIndex) >= 0;"
2.8 + "return self.toString().indexOf(str.toString(), fromIndex);"
2.9 )
2.10 public int indexOf(String str, int fromIndex) {
2.11 return indexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
3.1 --- a/emul/src/main/java/java/lang/reflect/Method.java Tue Dec 04 15:32:18 2012 +0100
3.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java Wed Dec 05 09:28:31 2012 +0100
3.3 @@ -54,6 +54,7 @@
3.4 private final Class<?> clazz;
3.5 private final String name;
3.6 private final Object data;
3.7 + private final String sig;
3.8 private int modifiers;
3.9
3.10 // Generics infrastructure
3.11 @@ -65,12 +66,12 @@
3.12 * instantiation of these objects in Java code from the java.lang
3.13 * package via sun.reflect.LangReflectAccess.
3.14 */
3.15 - Method(Class<?> declaringClass,
3.16 - String name, Object data)
3.17 + Method(Class<?> declaringClass, String name, Object data, String sig)
3.18 {
3.19 this.clazz = declaringClass;
3.20 this.name = name;
3.21 this.data = data;
3.22 + this.sig = sig;
3.23 }
3.24
3.25 /**
3.26 @@ -594,29 +595,52 @@
3.27 // bck2brwsr implementation
3.28 //
3.29
3.30 - @JavaScriptBody(args = { "clazz", "name", "params" },
3.31 - body = "if (params.length > 0) return null;\n"
3.32 + @JavaScriptBody(args = { "clazz", "prefix" },
3.33 + body = ""
3.34 + "var c = clazz.cnstr.prototype;"
3.35 - + "var prefix = name + '__';\n"
3.36 + + "var arr = new Array();\n"
3.37 + "for (m in c) {\n"
3.38 - + " if (m.indexOf(prefix) === 0) {"
3.39 - + " return c[m];\n"
3.40 + + " if (m.indexOf(prefix) === 0) {\n"
3.41 + + " arr.push(m);\n"
3.42 + + " arr.push(c[m]);\n"
3.43 + " }"
3.44 + "}\n"
3.45 - + "return null;"
3.46 + + "return arr;"
3.47 )
3.48 - private static native Object findMethodData(
3.49 - Class<?> clazz, String name, Class<?>... parameterTypes
3.50 + private static native Object[] findMethodData(
3.51 + Class<?> clazz, String prefix
3.52 );
3.53 -
3.54 +
3.55 // XXX should not be public
3.56 public static Method findMethod(
3.57 Class<?> clazz, String name, Class<?>... parameterTypes
3.58 ) {
3.59 - Object data = findMethodData(clazz, name, parameterTypes);
3.60 - if (data == null) {
3.61 + Object[] data = findMethodData(clazz, name + "__");
3.62 + if (data.length == 0) {
3.63 return null;
3.64 }
3.65 - return new Method(clazz, name, data);
3.66 + String sig = ((String)data[0]).substring(name.length() + 2);
3.67 + return new Method(clazz, name, data[1], sig);
3.68 + }
3.69 +
3.70 + public static Method[] findMethods(Class<?> clazz) {
3.71 + Object[] namesAndData = findMethodData(clazz, "");
3.72 + int cnt = 0;
3.73 + for (int i = 0; i < namesAndData.length; i += 2) {
3.74 + String sig = (String) namesAndData[i];
3.75 + Object data = namesAndData[i + 1];
3.76 + int middle = sig.indexOf("__");
3.77 + if (middle == -1) {
3.78 + continue;
3.79 + }
3.80 + String name = sig.substring(0, middle);
3.81 + sig = sig.substring(middle + 2);
3.82 + namesAndData[cnt++] = new Method(clazz, name, data, sig);
3.83 + }
3.84 + Method[] arr = new Method[cnt];
3.85 + for (int i = 0; i < cnt; i++) {
3.86 + arr[i] = (Method)namesAndData[i];
3.87 + }
3.88 + return arr;
3.89 }
3.90 }
4.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Tue Dec 04 15:32:18 2012 +0100
4.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Wed Dec 05 09:28:31 2012 +0100
4.3 @@ -89,7 +89,16 @@
4.4 @Test public void jsInvokeMethod() throws Exception {
4.5 assertExec("Calls the name() method via reflection", Classes.class,
4.6 "reflectiveMethodCall__Ljava_lang_Object_2Z",
4.7 - "java.io.IOException"
4.8 + "java.io.IOException", true
4.9 + );
4.10 + }
4.11 + @Test public void javaFindMethod() throws Exception {
4.12 + assertEquals(Classes.reflectiveMethodCall(false), "java.io.IOException", "Calls the name() method via reflection");
4.13 + }
4.14 + @Test public void jsFindMethod() throws Exception {
4.15 + assertExec("Calls the name() method via reflection", Classes.class,
4.16 + "reflectiveMethodCall__Ljava_lang_Object_2Z",
4.17 + "java.io.IOException", false
4.18 );
4.19 }
4.20
5.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Tue Dec 04 15:32:18 2012 +0100
5.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Wed Dec 05 09:28:31 2012 +0100
5.3 @@ -21,6 +21,7 @@
5.4 import java.lang.annotation.Annotation;
5.5 import java.lang.reflect.Method;
5.6 import java.net.MalformedURLException;
5.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
5.8
5.9 /**
5.10 *
5.11 @@ -79,20 +80,32 @@
5.12 return null;
5.13 }
5.14
5.15 + @JavaScriptBody(args = "msg", body = "throw msg;")
5.16 + private static native void thrw(String msg);
5.17 +
5.18 public static Object reflectiveMethodCall(boolean direct) throws Exception {
5.19 - Method m;
5.20 - /*
5.21 + Method find = null;
5.22 + StringBuilder sb = new StringBuilder();
5.23 if (!direct) {
5.24 final Class<? extends Annotation> v = ClassesMarker.class;
5.25 - for (Method single : Classes.class.getMethods()) {
5.26 - if (single.getAnnotation(v)) {
5.27 - m = single;
5.28 + for (Method m : Classes.class.getMethods()) {
5.29 + sb.append("\n").append(m.getName());
5.30 + if (m.getName().equals("name")) {
5.31 + find = m;
5.32 break;
5.33 }
5.34 +// if (single.getAnnotation(v) != null) {
5.35 +// m = single;
5.36 +// break;
5.37 +// }
5.38 }
5.39 - } else*/ {
5.40 - m = Classes.class.getMethod("name");
5.41 + } else {
5.42 + find = Classes.class.getMethod("name");
5.43 }
5.44 - return m.invoke(null);
5.45 + if (find == null) {
5.46 + thrw(sb.toString());
5.47 + throw new NullPointerException(sb.toString());
5.48 + }
5.49 + return find.invoke(null);
5.50 }
5.51 }