# HG changeset patch # User Jaroslav Tulach # Date 1354696111 -3600 # Node ID ed0c92c81ea4969b6242cf3e83ab0b99998aa3df # Parent 683719ffcfe7343d012aee9ee97b2c9e638f2ef3 Implementation of Class.getMethods diff -r 683719ffcfe7 -r ed0c92c81ea4 emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Tue Dec 04 15:32:18 2012 +0100 +++ b/emul/src/main/java/java/lang/Class.java Wed Dec 05 09:28:31 2012 +0100 @@ -616,7 +616,7 @@ * @since JDK1.1 */ public Method[] getMethods() throws SecurityException { - throw new SecurityException(); + return Method.findMethods(this); } /** diff -r 683719ffcfe7 -r ed0c92c81ea4 emul/src/main/java/java/lang/String.java --- a/emul/src/main/java/java/lang/String.java Tue Dec 04 15:32:18 2012 +0100 +++ b/emul/src/main/java/java/lang/String.java Wed Dec 05 09:28:31 2012 +0100 @@ -1767,7 +1767,7 @@ * or {@code -1} if there is no such occurrence. */ @JavaScriptBody(args = { "self", "str", "fromIndex" }, body = - "return self.toString().indexOf(str.toString(), fromIndex) >= 0;" + "return self.toString().indexOf(str.toString(), fromIndex);" ) public int indexOf(String str, int fromIndex) { return indexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex); diff -r 683719ffcfe7 -r ed0c92c81ea4 emul/src/main/java/java/lang/reflect/Method.java --- a/emul/src/main/java/java/lang/reflect/Method.java Tue Dec 04 15:32:18 2012 +0100 +++ b/emul/src/main/java/java/lang/reflect/Method.java Wed Dec 05 09:28:31 2012 +0100 @@ -54,6 +54,7 @@ private final Class clazz; private final String name; private final Object data; + private final String sig; private int modifiers; // Generics infrastructure @@ -65,12 +66,12 @@ * instantiation of these objects in Java code from the java.lang * package via sun.reflect.LangReflectAccess. */ - Method(Class declaringClass, - String name, Object data) + Method(Class declaringClass, String name, Object data, String sig) { this.clazz = declaringClass; this.name = name; this.data = data; + this.sig = sig; } /** @@ -594,29 +595,52 @@ // bck2brwsr implementation // - @JavaScriptBody(args = { "clazz", "name", "params" }, - body = "if (params.length > 0) return null;\n" + @JavaScriptBody(args = { "clazz", "prefix" }, + body = "" + "var c = clazz.cnstr.prototype;" - + "var prefix = name + '__';\n" + + "var arr = new Array();\n" + "for (m in c) {\n" - + " if (m.indexOf(prefix) === 0) {" - + " return c[m];\n" + + " if (m.indexOf(prefix) === 0) {\n" + + " arr.push(m);\n" + + " arr.push(c[m]);\n" + " }" + "}\n" - + "return null;" + + "return arr;" ) - private static native Object findMethodData( - Class clazz, String name, Class... parameterTypes + private static native Object[] findMethodData( + Class clazz, String prefix ); - + // XXX should not be public public static Method findMethod( Class clazz, String name, Class... parameterTypes ) { - Object data = findMethodData(clazz, name, parameterTypes); - if (data == null) { + Object[] data = findMethodData(clazz, name + "__"); + if (data.length == 0) { return null; } - return new Method(clazz, name, data); + String sig = ((String)data[0]).substring(name.length() + 2); + return new Method(clazz, name, data[1], sig); + } + + public static Method[] findMethods(Class clazz) { + Object[] namesAndData = findMethodData(clazz, ""); + int cnt = 0; + for (int i = 0; i < namesAndData.length; i += 2) { + String sig = (String) namesAndData[i]; + Object data = namesAndData[i + 1]; + int middle = sig.indexOf("__"); + if (middle == -1) { + continue; + } + String name = sig.substring(0, middle); + sig = sig.substring(middle + 2); + namesAndData[cnt++] = new Method(clazz, name, data, sig); + } + Method[] arr = new Method[cnt]; + for (int i = 0; i < cnt; i++) { + arr[i] = (Method)namesAndData[i]; + } + return arr; } } diff -r 683719ffcfe7 -r ed0c92c81ea4 vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Tue Dec 04 15:32:18 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Wed Dec 05 09:28:31 2012 +0100 @@ -89,7 +89,16 @@ @Test public void jsInvokeMethod() throws Exception { assertExec("Calls the name() method via reflection", Classes.class, "reflectiveMethodCall__Ljava_lang_Object_2Z", - "java.io.IOException" + "java.io.IOException", true + ); + } + @Test public void javaFindMethod() throws Exception { + assertEquals(Classes.reflectiveMethodCall(false), "java.io.IOException", "Calls the name() method via reflection"); + } + @Test public void jsFindMethod() throws Exception { + assertExec("Calls the name() method via reflection", Classes.class, + "reflectiveMethodCall__Ljava_lang_Object_2Z", + "java.io.IOException", false ); } diff -r 683719ffcfe7 -r ed0c92c81ea4 vm/src/test/java/org/apidesign/vm4brwsr/Classes.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Tue Dec 04 15:32:18 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Wed Dec 05 09:28:31 2012 +0100 @@ -21,6 +21,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.MalformedURLException; +import org.apidesign.bck2brwsr.core.JavaScriptBody; /** * @@ -79,20 +80,32 @@ return null; } + @JavaScriptBody(args = "msg", body = "throw msg;") + private static native void thrw(String msg); + public static Object reflectiveMethodCall(boolean direct) throws Exception { - Method m; - /* + Method find = null; + StringBuilder sb = new StringBuilder(); if (!direct) { final Class v = ClassesMarker.class; - for (Method single : Classes.class.getMethods()) { - if (single.getAnnotation(v)) { - m = single; + for (Method m : Classes.class.getMethods()) { + sb.append("\n").append(m.getName()); + if (m.getName().equals("name")) { + find = m; break; } +// if (single.getAnnotation(v) != null) { +// m = single; +// break; +// } } - } else*/ { - m = Classes.class.getMethod("name"); + } else { + find = Classes.class.getMethod("name"); } - return m.invoke(null); + if (find == null) { + thrw(sb.toString()); + throw new NullPointerException(sb.toString()); + } + return find.invoke(null); } }