Use Java bodies of @JavaScriptBody methods if there is no presenter
authorJaroslav Tulach <jaroslav.tulach@netbeans.org>
Fri, 10 Jan 2014 15:49:27 +0100
changeset 451b75c076615a3
parent 450 bc89281a90d5
child 452 059e6c2cc82b
Use Java bodies of @JavaScriptBody methods if there is no presenter
boot/src/main/java/org/apidesign/html/boot/spi/Fn.java
boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java
boot/src/test/java/org/netbeans/html/boot/impl/JsClassLoaderBase.java
boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java
     1.1 --- a/boot/src/main/java/org/apidesign/html/boot/spi/Fn.java	Fri Jan 10 11:35:47 2014 +0100
     1.2 +++ b/boot/src/main/java/org/apidesign/html/boot/spi/Fn.java	Fri Jan 10 15:49:27 2014 +0100
     1.3 @@ -88,7 +88,7 @@
     1.4       * @return true, if proper presenter is used
     1.5       */
     1.6      public final boolean isValid() {
     1.7 -        return FnContext.currentPresenter(false) == presenter;
     1.8 +        return presenter != null && FnContext.currentPresenter(false) == presenter;
     1.9      }
    1.10      
    1.11      /** Helper method to check if the provided instance is valid function.
    1.12 @@ -110,10 +110,12 @@
    1.13       * @param code the body of the function (can reference <code>this</code> and <code>names</code> variables)
    1.14       * @param names names of individual parameters
    1.15       * @return the function object that can be {@link Fn#invoke(java.lang.Object, java.lang.Object...) invoked}
    1.16 +     *    - can return <code>null</code> if there is {@link #activePresenter() no presenter}
    1.17       * @since 0.7
    1.18       */
    1.19      public static Fn define(Class<?> caller, String code, String... names) {
    1.20 -        return FnContext.currentPresenter(false).defineFn(code, names);
    1.21 +        final Presenter p = FnContext.currentPresenter(false);
    1.22 +        return p == null ? null : p.defineFn(code, names);
    1.23      }
    1.24      
    1.25      private static final Map<String,Set<Presenter>> LOADED = new HashMap<String, Set<Presenter>>();
     2.1 --- a/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java	Fri Jan 10 11:35:47 2014 +0100
     2.2 +++ b/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java	Fri Jan 10 15:49:27 2014 +0100
     2.3 @@ -252,10 +252,10 @@
     2.4                  if (body == null) {
     2.5                      return;
     2.6                  }
     2.7 -                generateBody();
     2.8 +                generateBody(true);
     2.9              }
    2.10  
    2.11 -            private boolean generateBody() {
    2.12 +            private boolean generateBody(boolean hasCode) {
    2.13                  if (bodyGenerated) {
    2.14                      return false;
    2.15                  }
    2.16 @@ -295,6 +295,11 @@
    2.17                          "org/apidesign/html/boot/spi/Fn", "define",
    2.18                          "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/String;)Lorg/apidesign/html/boot/spi/Fn;"
    2.19                  );
    2.20 +                Label noPresenter = new Label();
    2.21 +                if (hasCode) {
    2.22 +                    super.visitInsn(Opcodes.DUP);
    2.23 +                    super.visitJumpInsn(Opcodes.IFNULL, noPresenter);
    2.24 +                }
    2.25                  if (resource != null) {
    2.26                      super.visitLdcInsn(Type.getObjectType(FindInClass.this.name));
    2.27                      super.visitLdcInsn(resource);
    2.28 @@ -460,6 +465,10 @@
    2.29                          );
    2.30                          super.visitInsn(sv.returnType.getOpcode(Opcodes.IRETURN));
    2.31                  }
    2.32 +                if (hasCode) {
    2.33 +                    super.visitLabel(noPresenter);
    2.34 +                    super.visitCode();
    2.35 +                }
    2.36                  return true;
    2.37              }
    2.38  
    2.39 @@ -467,7 +476,7 @@
    2.40              public void visitEnd() {
    2.41                  super.visitEnd();
    2.42                  if (body != null) {
    2.43 -                    if (generateBody()) {
    2.44 +                    if (generateBody(false)) {
    2.45                          // native method
    2.46                          super.visitMaxs(1, 0);
    2.47                      }
     3.1 --- a/boot/src/test/java/org/netbeans/html/boot/impl/JsClassLoaderBase.java	Fri Jan 10 11:35:47 2014 +0100
     3.2 +++ b/boot/src/test/java/org/netbeans/html/boot/impl/JsClassLoaderBase.java	Fri Jan 10 15:49:27 2014 +0100
     3.3 @@ -42,9 +42,11 @@
     3.4   */
     3.5  package org.netbeans.html.boot.impl;
     3.6  
     3.7 +import java.io.Closeable;
     3.8  import java.lang.reflect.InvocationTargetException;
     3.9  import java.lang.reflect.Method;
    3.10  import java.lang.reflect.Modifier;
    3.11 +import org.apidesign.html.boot.spi.Fn;
    3.12  import static org.testng.Assert.*;
    3.13  import org.testng.annotations.BeforeMethod;
    3.14  import org.testng.annotations.Test;
    3.15 @@ -199,6 +201,29 @@
    3.16          assertEquals(st.invoke(methodClass.newInstance(), "Hello"), "Hello", "The same parameter returned");
    3.17      }
    3.18      
    3.19 +    @Test public void plusOrMul() throws Throwable {
    3.20 +        Method st = methodClass.getMethod("plusOrMul", int.class, int.class);
    3.21 +        assertNotNull(Fn.activePresenter(), "Is there a presenter?");
    3.22 +        Closeable c = Fn.activate(null);
    3.23 +        try {
    3.24 +            assertNull(Fn.activePresenter(), "No presenter now");
    3.25 +            assertEquals(st.invoke(null, 6, 7), 42, "Mul in Java");
    3.26 +        } finally {
    3.27 +            c.close();
    3.28 +        }
    3.29 +        assertNotNull(Fn.activePresenter(), "Is there a presenter again");
    3.30 +        assertEquals(st.invoke(null, 6, 7), 13, "Plus in JavaScript");
    3.31 +        c = Fn.activate(null);
    3.32 +        try {
    3.33 +            assertNull(Fn.activePresenter(), "No presenter again");
    3.34 +            assertEquals(st.invoke(null, 6, 7), 42, "Mul in Java");
    3.35 +        } finally {
    3.36 +            c.close();
    3.37 +        }
    3.38 +        assertNotNull(Fn.activePresenter(), "Is there a presenter again");
    3.39 +        assertEquals(st.invoke(null, 6, 7), 13, "Plus in JavaScript again");
    3.40 +    }
    3.41 +    
    3.42      @Test public void arrayInOut() throws Throwable {
    3.43          String[] arr = { "Ahoj" };
    3.44          Method st = methodClass.getMethod("arr", Object[].class);
     4.1 --- a/boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java	Fri Jan 10 11:35:47 2014 +0100
     4.2 +++ b/boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java	Fri Jan 10 15:49:27 2014 +0100
     4.3 @@ -129,4 +129,9 @@
     4.4        + "return this.@org.netbeans.html.boot.impl.JsMethods::getError()();"
     4.5      )
     4.6      public native Object recordError(Object err);
     4.7 +    
     4.8 +    @JavaScriptBody(args = { "x", "y" }, body = "return x + y;")
     4.9 +    public static int plusOrMul(int x, int y) {
    4.10 +        return x * y;
    4.11 +    }
    4.12  }