# HG changeset patch # User Jaroslav Tulach # Date 1460891791 -7200 # Node ID 4185cdeeee7e54691445a57e8789844e00ea3c0c # Parent 2d4597793958765c4f6a77d90b2f4d2e68fba49f Perform necessary conversions before returning Java value to JavaScript from a Java callback diff -r 2d4597793958 -r 4185cdeeee7e rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotations.java --- a/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotations.java Sun Apr 17 13:13:39 2016 +0200 +++ b/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotations.java Sun Apr 17 13:16:31 2016 +0200 @@ -17,6 +17,7 @@ */ package org.apidesign.bck2brwsr.vmtest.impl; +import java.util.concurrent.Callable; import net.java.html.js.JavaScriptBody; import net.java.html.js.JavaScriptResource; @@ -92,4 +93,10 @@ @JavaScriptBody(args = { "date" }, body = "return date.getFullYear()") public static native int year(Object date); + + @JavaScriptBody(args = { "call" }, javacall = true, body = "" + + "var b = call.@java.util.concurrent.Callable::call()();\n" + + "return b ? 'yes' : 'no';\n" + ) + public static native String yesNo(Callable call); } diff -r 2d4597793958 -r 4185cdeeee7e rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java --- a/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java Sun Apr 17 13:13:39 2016 +0200 +++ b/rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java Sun Apr 17 13:16:31 2016 +0200 @@ -17,6 +17,7 @@ */ package org.apidesign.bck2brwsr.vmtest.impl; +import java.util.concurrent.Callable; import org.apidesign.bck2brwsr.core.JavaScriptBody; import org.apidesign.bck2brwsr.vmtest.BrwsrTest; import org.apidesign.bck2brwsr.vmtest.VMTest; @@ -82,6 +83,26 @@ Object april = HtmlAnnotations.april2016(); assertEquals(HtmlAnnotations.year(april), 2016); } + + @BrwsrTest public void yes() throws Exception { + String yes = HtmlAnnotations.yesNo(new Callable() { + @Override + public Boolean call() throws Exception { + return Boolean.TRUE; + } + }); + assertEquals(yes, "yes", "TRUE is true"); + } + + @BrwsrTest public void no() throws Exception { + String no = HtmlAnnotations.yesNo(new Callable() { + @Override + public Boolean call() throws Exception { + return Boolean.FALSE; + } + }); + assertEquals(no, "no", "FALSE is false"); + } private static void assertEquals(double real, double exp) { if (real - exp < 0.01) { @@ -90,6 +111,16 @@ assert false : "Expecting " + exp + " but was " + real; } + private static void assertEquals(Object real, Object exp, String msg) { + if (real == exp) { + return; + } + if (real != null && real.equals(exp)) { + return; + } + throw new AssertionError(msg + " expected: " + exp + " real: " + real); + } + private static void assertNotNull(Object obj, String msg) { assert obj != null : msg; } diff -r 2d4597793958 -r 4185cdeeee7e rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Apr 17 13:13:39 2016 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Apr 17 13:16:31 2016 +0200 @@ -1997,7 +1997,7 @@ return mn; } - private static CharSequence mangleCallbacks(String pkgName, String body) { + private CharSequence mangleCallbacks(String pkgName, String body) { StringBuilder sb = new StringBuilder(); int pos = 0; for (;;) { @@ -2029,14 +2029,18 @@ String params = body.substring(sigBeg, sigEnd + 1); int paramBeg = body.indexOf('(', sigEnd + 1); - + int paramEnd = closingParenthesis(body, paramBeg); + + sb.append(accessClass("java_lang_Class")).append("(false).toJS("); sb.append("vm.").append(mangleClassName(pkgName)).append("_$JsCallbacks$(false)._VM()."); sb.append(mangleJsCallbacks(fqn, method, params, false)); sb.append("(").append(refId); if (body.charAt(paramBeg + 1) != ')') { sb.append(","); } - pos = paramBeg + 1; + sb.append(body.substring(paramBeg + 1, paramEnd)); + sb.append(")"); + pos = paramEnd; } sb = null; pos = 0; @@ -2066,11 +2070,15 @@ String params = body.substring(sigBeg, sigEnd + 1); int paramBeg = body.indexOf('(', sigEnd + 1); - + int paramEnd = closingParenthesis(body, paramBeg); + + sb.append(accessClass("java_lang_Class")).append("(false).toJS("); sb.append("vm.").append(mangleClassName(pkgName)).append("_$JsCallbacks$(false)._VM()."); sb.append(mangleJsCallbacks(fqn, method, params, true)); sb.append("("); - pos = paramBeg + 1; + sb.append(body.substring(paramBeg + 1, paramEnd)); + sb.append(")"); + pos = paramEnd; } } @@ -2449,6 +2457,19 @@ System.err.println(msg); } + private static int closingParenthesis(String body, int at) { + int cnt = 0; + for (;;) { + switch (body.charAt(at++)) { + case '(': cnt++; break; + case ')': cnt--; break; + } + if (cnt == 0) { + return at; + } + } + } + private class GenerateAnno extends AnnotationParser { public GenerateAnno(boolean textual, boolean iterateArray) { super(textual, iterateArray);