Perform necessary conversions before returning Java value to JavaScript from a Java callback
1.1 --- a/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotations.java Sun Apr 17 13:13:39 2016 +0200
1.2 +++ b/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotations.java Sun Apr 17 13:16:31 2016 +0200
1.3 @@ -17,6 +17,7 @@
1.4 */
1.5 package org.apidesign.bck2brwsr.vmtest.impl;
1.6
1.7 +import java.util.concurrent.Callable;
1.8 import net.java.html.js.JavaScriptBody;
1.9 import net.java.html.js.JavaScriptResource;
1.10
1.11 @@ -92,4 +93,10 @@
1.12
1.13 @JavaScriptBody(args = { "date" }, body = "return date.getFullYear()")
1.14 public static native int year(Object date);
1.15 +
1.16 + @JavaScriptBody(args = { "call" }, javacall = true, body = ""
1.17 + + "var b = call.@java.util.concurrent.Callable::call()();\n"
1.18 + + "return b ? 'yes' : 'no';\n"
1.19 + )
1.20 + public static native String yesNo(Callable<Boolean> call);
1.21 }
2.1 --- a/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java Sun Apr 17 13:13:39 2016 +0200
2.2 +++ b/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java Sun Apr 17 13:16:31 2016 +0200
2.3 @@ -17,6 +17,7 @@
2.4 */
2.5 package org.apidesign.bck2brwsr.vmtest.impl;
2.6
2.7 +import java.util.concurrent.Callable;
2.8 import org.apidesign.bck2brwsr.core.JavaScriptBody;
2.9 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
2.10 import org.apidesign.bck2brwsr.vmtest.VMTest;
2.11 @@ -82,6 +83,26 @@
2.12 Object april = HtmlAnnotations.april2016();
2.13 assertEquals(HtmlAnnotations.year(april), 2016);
2.14 }
2.15 +
2.16 + @BrwsrTest public void yes() throws Exception {
2.17 + String yes = HtmlAnnotations.yesNo(new Callable<Boolean>() {
2.18 + @Override
2.19 + public Boolean call() throws Exception {
2.20 + return Boolean.TRUE;
2.21 + }
2.22 + });
2.23 + assertEquals(yes, "yes", "TRUE is true");
2.24 + }
2.25 +
2.26 + @BrwsrTest public void no() throws Exception {
2.27 + String no = HtmlAnnotations.yesNo(new Callable<Boolean>() {
2.28 + @Override
2.29 + public Boolean call() throws Exception {
2.30 + return Boolean.FALSE;
2.31 + }
2.32 + });
2.33 + assertEquals(no, "no", "FALSE is false");
2.34 + }
2.35
2.36 private static void assertEquals(double real, double exp) {
2.37 if (real - exp < 0.01) {
2.38 @@ -90,6 +111,16 @@
2.39 assert false : "Expecting " + exp + " but was " + real;
2.40 }
2.41
2.42 + private static void assertEquals(Object real, Object exp, String msg) {
2.43 + if (real == exp) {
2.44 + return;
2.45 + }
2.46 + if (real != null && real.equals(exp)) {
2.47 + return;
2.48 + }
2.49 + throw new AssertionError(msg + " expected: " + exp + " real: " + real);
2.50 + }
2.51 +
2.52 private static void assertNotNull(Object obj, String msg) {
2.53 assert obj != null : msg;
2.54 }
3.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Apr 17 13:13:39 2016 +0200
3.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Apr 17 13:16:31 2016 +0200
3.3 @@ -1997,7 +1997,7 @@
3.4 return mn;
3.5 }
3.6
3.7 - private static CharSequence mangleCallbacks(String pkgName, String body) {
3.8 + private CharSequence mangleCallbacks(String pkgName, String body) {
3.9 StringBuilder sb = new StringBuilder();
3.10 int pos = 0;
3.11 for (;;) {
3.12 @@ -2029,14 +2029,18 @@
3.13 String params = body.substring(sigBeg, sigEnd + 1);
3.14
3.15 int paramBeg = body.indexOf('(', sigEnd + 1);
3.16 -
3.17 + int paramEnd = closingParenthesis(body, paramBeg);
3.18 +
3.19 + sb.append(accessClass("java_lang_Class")).append("(false).toJS(");
3.20 sb.append("vm.").append(mangleClassName(pkgName)).append("_$JsCallbacks$(false)._VM().");
3.21 sb.append(mangleJsCallbacks(fqn, method, params, false));
3.22 sb.append("(").append(refId);
3.23 if (body.charAt(paramBeg + 1) != ')') {
3.24 sb.append(",");
3.25 }
3.26 - pos = paramBeg + 1;
3.27 + sb.append(body.substring(paramBeg + 1, paramEnd));
3.28 + sb.append(")");
3.29 + pos = paramEnd;
3.30 }
3.31 sb = null;
3.32 pos = 0;
3.33 @@ -2066,11 +2070,15 @@
3.34 String params = body.substring(sigBeg, sigEnd + 1);
3.35
3.36 int paramBeg = body.indexOf('(', sigEnd + 1);
3.37 -
3.38 + int paramEnd = closingParenthesis(body, paramBeg);
3.39 +
3.40 + sb.append(accessClass("java_lang_Class")).append("(false).toJS(");
3.41 sb.append("vm.").append(mangleClassName(pkgName)).append("_$JsCallbacks$(false)._VM().");
3.42 sb.append(mangleJsCallbacks(fqn, method, params, true));
3.43 sb.append("(");
3.44 - pos = paramBeg + 1;
3.45 + sb.append(body.substring(paramBeg + 1, paramEnd));
3.46 + sb.append(")");
3.47 + pos = paramEnd;
3.48 }
3.49 }
3.50
3.51 @@ -2449,6 +2457,19 @@
3.52 System.err.println(msg);
3.53 }
3.54
3.55 + private static int closingParenthesis(String body, int at) {
3.56 + int cnt = 0;
3.57 + for (;;) {
3.58 + switch (body.charAt(at++)) {
3.59 + case '(': cnt++; break;
3.60 + case ')': cnt--; break;
3.61 + }
3.62 + if (cnt == 0) {
3.63 + return at;
3.64 + }
3.65 + }
3.66 + }
3.67 +
3.68 private class GenerateAnno extends AnnotationParser {
3.69 public GenerateAnno(boolean textual, boolean iterateArray) {
3.70 super(textual, iterateArray);