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 }