1.1 --- a/boot-fx/src/test/java/org/apidesign/html/boot/fx/FXPresenterTst.java Thu Jul 11 16:39:39 2013 +0200
1.2 +++ b/boot-fx/src/test/java/org/apidesign/html/boot/fx/FXPresenterTst.java Thu Jul 11 17:58:45 2013 +0200
1.3 @@ -38,7 +38,7 @@
1.4 @JavaScriptBody(args = { "r" }, javacall = true, body = "r.@java.lang.Runnable::run()();")
1.5 private static native void callback(Runnable r);
1.6
1.7 - public static class R implements Runnable {
1.8 + private static class R implements Runnable {
1.9 int cnt;
1.10
1.11 @Override
2.1 --- a/boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java Thu Jul 11 16:39:39 2013 +0200
2.2 +++ b/boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java Thu Jul 11 17:58:45 2013 +0200
2.3 @@ -23,7 +23,6 @@
2.4 import java.io.InputStream;
2.5 import java.io.InputStreamReader;
2.6 import java.io.Reader;
2.7 -import java.lang.reflect.Method;
2.8 import java.net.URL;
2.9 import java.util.ArrayList;
2.10 import java.util.Collections;
2.11 @@ -83,44 +82,10 @@
2.12 protected CharSequence callMethod(
2.13 String ident, String fqn, String method, String params
2.14 ) {
2.15 - try {
2.16 - StringBuilder sb = new StringBuilder();
2.17 - sb.append(ident);
2.18 - if (fqn.equals(ownName.replace('/', '.'))) {
2.19 - if (!ownMethods.containsKey(method + params)) {
2.20 - throw new IllegalStateException("Wrong reference to " + method + params);
2.21 - }
2.22 - sb.append("['").append(method).append("(");
2.23 - final Type[] argTps = Type.getArgumentTypes(params);
2.24 - Class<?>[] argCls = new Class<?>[argTps.length];
2.25 - String sep = "";
2.26 - for (int i = 0; i < argCls.length; i++) {
2.27 - sb.append(sep).append(toClass(argTps[i], loader).getName());
2.28 - sep = ",";
2.29 - }
2.30 - sb.append(")']");
2.31 - } else {
2.32 - Class<?> clazz = Class.forName(fqn, false, loader);
2.33 - final Type[] argTps = Type.getArgumentTypes(params);
2.34 - Class<?>[] argCls = new Class<?>[argTps.length];
2.35 - for (int i = 0; i < argCls.length; i++) {
2.36 - argCls[i] = toClass(argTps[i], loader);
2.37 - }
2.38 - Method m = clazz.getMethod(method, argCls);
2.39 - sb.append("['").append(m.getName()).append("(");
2.40 - String sep = "";
2.41 - for (Class<?> pt : m.getParameterTypes()) {
2.42 - sb.append(sep).append(pt.getName());
2.43 - sep = ",";
2.44 - }
2.45 - sb.append(")']");
2.46 - }
2.47 - return sb;
2.48 - } catch (ClassNotFoundException ex) {
2.49 - throw new IllegalStateException("Can't parse " + body, ex);
2.50 - } catch (NoSuchMethodException ex) {
2.51 - throw new IllegalStateException("Can't parse " + body, ex);
2.52 - }
2.53 + StringBuilder sb = new StringBuilder();
2.54 + sb.append("vm.").append(mangle(fqn, method, params));
2.55 + sb.append("(").append(ident);
2.56 + return sb;
2.57 }
2.58
2.59 }.parse(body);
2.60 @@ -145,26 +110,4 @@
2.61 throw new IllegalStateException("Can't execute " + resource, ex);
2.62 }
2.63 }
2.64 - static Class<?> toClass(final Type t, ClassLoader loader) throws ClassNotFoundException {
2.65 - if (t == Type.INT_TYPE) {
2.66 - return Integer.TYPE;
2.67 - } else if (t == Type.VOID_TYPE) {
2.68 - return Void.TYPE;
2.69 - } else if (t == Type.BOOLEAN_TYPE) {
2.70 - return Boolean.TYPE;
2.71 - } else if (t == Type.BYTE_TYPE) {
2.72 - return Byte.TYPE;
2.73 - } else if (t == Type.CHAR_TYPE) {
2.74 - return Character.TYPE;
2.75 - } else if (t == Type.SHORT_TYPE) {
2.76 - return Short.TYPE;
2.77 - } else if (t == Type.DOUBLE_TYPE) {
2.78 - return Double.TYPE;
2.79 - } else if (t == Type.FLOAT_TYPE) {
2.80 - return Float.TYPE;
2.81 - } else if (t == Type.LONG_TYPE) {
2.82 - return Long.TYPE;
2.83 - }
2.84 - return Class.forName(t.getClassName(), false, loader);
2.85 - }
2.86 }
3.1 --- a/boot/src/main/java/org/apidesign/html/boot/impl/JavaScriptProcesor.java Thu Jul 11 16:39:39 2013 +0200
3.2 +++ b/boot/src/main/java/org/apidesign/html/boot/impl/JavaScriptProcesor.java Thu Jul 11 17:58:45 2013 +0200
3.3 @@ -22,7 +22,6 @@
3.4
3.5 import java.io.IOException;
3.6 import java.io.Writer;
3.7 -import java.util.ArrayList;
3.8 import java.util.Collections;
3.9 import java.util.HashMap;
3.10 import java.util.HashSet;
3.11 @@ -145,7 +144,7 @@
3.12 continue;
3.13 }
3.14 if (m.getSimpleName().contentEquals(method)) {
3.15 - String paramTypes = findParamTypes((ExecutableElement)m, true);
3.16 + String paramTypes = findParamTypes((ExecutableElement)m);
3.17 if (paramTypes.equals(params)) {
3.18 found = (ExecutableElement) m;
3.19 break;
3.20 @@ -170,18 +169,16 @@
3.21 mangledOnes = new TreeMap<String, ExecutableElement>();
3.22 javacalls.put(findPkg(e), mangledOnes);
3.23 }
3.24 - String mangled = JsCallback.mangle(fqn, method, findParamTypes(found, false));
3.25 + String mangled = JsCallback.mangle(fqn, method, findParamTypes(found));
3.26 mangledOnes.put(mangled, found);
3.27 }
3.28 return "";
3.29 }
3.30
3.31 - private String findParamTypes(ExecutableElement method, boolean surround) {
3.32 + private String findParamTypes(ExecutableElement method) {
3.33 ExecutableType t = (ExecutableType) method.asType();
3.34 StringBuilder sb = new StringBuilder();
3.35 - if (surround) {
3.36 - sb.append('(');
3.37 - }
3.38 + sb.append('(');
3.39 for (TypeMirror tm : t.getParameterTypes()) {
3.40 if (tm.getKind().isPrimitive()) {
3.41 switch (tm.getKind()) {
3.42 @@ -206,9 +203,7 @@
3.43 sb.append(';');
3.44 }
3.45 }
3.46 - if (surround) {
3.47 - sb.append(')');
3.48 - }
3.49 + sb.append(')');
3.50 return sb.toString();
3.51 }
3.52 }
3.53 @@ -219,8 +214,8 @@
3.54 Map<String, ExecutableElement> map = pkgEn.getValue();
3.55 StringBuilder source = new StringBuilder();
3.56 source.append("package ").append(pkgName).append(";\n");
3.57 - source.append("final class $JsCallbacks$ {\n");
3.58 - source.append(" public static final $JsCallbacks$ VM = new $JsCallbacks$();\n");
3.59 + source.append("public final class $JsCallbacks$ {\n");
3.60 + source.append(" static final $JsCallbacks$ VM = new $JsCallbacks$();\n");
3.61 source.append(" private $JsCallbacks$() {}\n");
3.62 for (Map.Entry<String, ExecutableElement> entry : map.entrySet()) {
3.63 final String mangled = entry.getKey();
4.1 --- a/boot/src/main/java/org/apidesign/html/boot/impl/JsCallback.java Thu Jul 11 16:39:39 2013 +0200
4.2 +++ b/boot/src/main/java/org/apidesign/html/boot/impl/JsCallback.java Thu Jul 11 17:58:45 2013 +0200
4.3 @@ -36,9 +36,12 @@
4.4 return sb.toString();
4.5 }
4.6 int ident = next;
4.7 - while (ident > 0 && Character.isJavaIdentifierPart(body.charAt(--ident))) {
4.8 + while (ident > 0) {
4.9 + if (!Character.isJavaIdentifierPart(body.charAt(--ident))) {
4.10 + ident++;
4.11 + break;
4.12 + }
4.13 }
4.14 - ident++;
4.15 String refId = body.substring(ident, next);
4.16
4.17 sb.append(body.substring(pos, ident));
4.18 @@ -52,9 +55,14 @@
4.19 String fqn = body.substring(next + 2, colon4);
4.20 String method = body.substring(colon4 + 2, sigBeg);
4.21 String params = body.substring(sigBeg, sigEnd + 1);
4.22 +
4.23 + int paramBeg = body.indexOf('(', sigEnd + 1);
4.24
4.25 sb.append(callMethod(refId, fqn, method, params));
4.26 - pos = sigEnd + 1;
4.27 + if (body.charAt(paramBeg + 1) != (')')) {
4.28 + sb.append(",");
4.29 + }
4.30 + pos = paramBeg + 1;
4.31 }
4.32 }
4.33
4.34 @@ -63,6 +71,12 @@
4.35 );
4.36
4.37 static String mangle(String fqn, String method, String params) {
4.38 + if (params.startsWith("(")) {
4.39 + params = params.substring(1);
4.40 + }
4.41 + if (params.endsWith(")")) {
4.42 + params = params.substring(0, params.length() - 1);
4.43 + }
4.44 return
4.45 replace(fqn) + "__" + replace(method) + "__" + replace(params);
4.46 }
5.1 --- a/boot/src/main/java/org/apidesign/html/boot/impl/JsClassLoader.java Thu Jul 11 16:39:39 2013 +0200
5.2 +++ b/boot/src/main/java/org/apidesign/html/boot/impl/JsClassLoader.java Thu Jul 11 17:58:45 2013 +0200
5.3 @@ -225,11 +225,14 @@
5.4 super.visitLdcInsn(body);
5.5 super.visitIntInsn(Opcodes.SIPUSH, args.size());
5.6 super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
5.7 + boolean needsVM = false;
5.8 for (int i = 0; i < args.size(); i++) {
5.9 - String name = args.get(i);
5.10 + assert !needsVM;
5.11 + String argName = args.get(i);
5.12 + needsVM = "vm".equals(argName);
5.13 super.visitInsn(Opcodes.DUP);
5.14 super.visitIntInsn(Opcodes.BIPUSH, i);
5.15 - super.visitLdcInsn(name);
5.16 + super.visitLdcInsn(argName);
5.17 super.visitInsn(Opcodes.AASTORE);
5.18 }
5.19 super.visitMethodInsn(Opcodes.INVOKESTATIC,
5.20 @@ -327,6 +330,15 @@
5.21 SignatureReader sr = new SignatureReader(desc);
5.22 sr.accept(sv);
5.23
5.24 + if (needsVM) {
5.25 + FindInMethod.super.visitInsn(Opcodes.DUP);
5.26 + FindInMethod.super.visitIntInsn(Opcodes.SIPUSH, sv.index);
5.27 + int lastSlash = FindInClass.this.name.lastIndexOf('/');
5.28 + String jsCallbacks = FindInClass.this.name.substring(0, lastSlash + 1) + "$JsCallbacks$";
5.29 + FindInMethod.super.visitFieldInsn(Opcodes.GETSTATIC, jsCallbacks, "VM", "L" + jsCallbacks + ";");
5.30 + FindInMethod.super.visitInsn(Opcodes.AASTORE);
5.31 + }
5.32 +
5.33 super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
5.34 "org/apidesign/html/boot/spi/Fn", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"
5.35 );
5.36 @@ -408,10 +420,11 @@
5.37 @Override
5.38 public void visitEnd() {
5.39 if (body != null) {
5.40 - generateJSBody(args, javacall ?
5.41 - FnUtils.callback(body, JsClassLoader.this, FindInClass.this.name, FindInClass.this.methods) :
5.42 - body
5.43 - );
5.44 + if (javacall) {
5.45 + body = FnUtils.callback(body, JsClassLoader.this, FindInClass.this.name, FindInClass.this.methods);
5.46 + args.add("vm");
5.47 + }
5.48 + generateJSBody(args, body);
5.49 }
5.50 }
5.51 }