Perform necessary conversions before returning Java value to JavaScript from a Java callback
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 17 Apr 2016 13:16:31 +0200
changeset 19234185cdeeee7e
parent 1922 2d4597793958
child 1924 cf3873164b9f
Perform necessary conversions before returning Java value to JavaScript from a Java callback
rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotations.java
rt/emul/compacttest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
     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);