# HG changeset patch # User Jaroslav Tulach # Date 1415525768 -3600 # Node ID fd3a354d6e8f586b0664050e34e1e8885a6a1e10 # Parent 15f7116b57b6e8c4ce1d5e0d2f166cabf0ca6a41 Don't initialize @JavaScriptBody resources sooner than their methods are called. diff -r 15f7116b57b6 -r fd3a354d6e8f rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/HtmlAnnotationsTest.java Sun Nov 09 10:36:08 2014 +0100 @@ -17,6 +17,7 @@ */ package org.apidesign.bck2brwsr.vmtest.impl; +import org.apidesign.bck2brwsr.core.JavaScriptBody; import org.apidesign.bck2brwsr.vmtest.BrwsrTest; import org.apidesign.bck2brwsr.vmtest.VMTest; import org.testng.annotations.Factory; @@ -26,29 +27,44 @@ * @author Jaroslav Tulach */ public class HtmlAnnotationsTest { + static int firstCheck; + + private void assertMulNotDefinedForTheFirstTime() { + if (firstCheck++ == 0) { + Object mul = windowMul(); + assert mul == null : "htmlannotations.js should not be processed before first call to HtmlAnnotations class"; + } + } + @BrwsrTest public void fourtyTwo() throws Exception { + assertMulNotDefinedForTheFirstTime(); assertEquals(HtmlAnnotations.fourtyTwo(), 42); } @BrwsrTest public void externalMul() throws Exception { + assertMulNotDefinedForTheFirstTime(); assertEquals(HtmlAnnotations.useExternalMul(7, 6), 42); } @BrwsrTest public void callRunnableFromJS() throws Exception { + assertMulNotDefinedForTheFirstTime(); assertEquals(HtmlAnnotations.callback(), 1); } @BrwsrTest public void callStaticMethodFromJS() throws Exception { + assertMulNotDefinedForTheFirstTime(); assertEquals(HtmlAnnotations.staticCallback(), 1); } @BrwsrTest public void callbackWithFourParamsAndReturnType() throws Exception { + assertMulNotDefinedForTheFirstTime(); Object instance = HtmlAnnotations.create(); assertNotNull(instance, "Instance created"); assertEquals(HtmlAnnotations.first(instance, 42, 31), 42); } @BrwsrTest public void callbackWithObjectParamsAndReturnType() throws Exception { + assertMulNotDefinedForTheFirstTime(); Object instance = HtmlAnnotations.create(); assertNotNull(instance, "Instance created"); assertEquals(HtmlAnnotations.onError(instance, 42.0), 42.0); @@ -65,6 +81,9 @@ assert obj != null : msg; } + @JavaScriptBody(args = {}, body = "return window.mul ? window.mul : null;") + private static native Object windowMul(); + @Factory public static Object[] create() { return VMTest.create(HtmlAnnotationsTest.class); } diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Nov 09 10:36:08 2014 +0100 @@ -70,6 +70,8 @@ */ protected abstract void requireScript(String resourcePath) throws IOException; + protected abstract void requireResource(String resourcePath) throws IOException; + /** Allows subclasses to redefine what field a function representing a * class gets assigned. By default it returns the suggested name followed * by " = "; @@ -165,6 +167,7 @@ } } } + final String jsResource; { String[] arr = findAnnotation(arrData, jc, "net.java.html.js.JavaScriptResource", @@ -172,13 +175,13 @@ ); if (arr != null) { if (arr[0].startsWith("/")) { - requireScript(arr[0]); + jsResource = arr[0]; } else { int last = jc.getClassName().lastIndexOf('/'); - requireScript( - jc.getClassName().substring(0, last + 1).replace('.', '/') + arr[0] - ); + jsResource = jc.getClassName().substring(0, last + 1).replace('.', '/') + arr[0]; } + } else { + jsResource = null; } } String[] proto = findAnnotation(arrData, jc, @@ -303,6 +306,11 @@ for (String init : toInitilize.toArray()) { append("\n ").append(init).append("();"); } + + if (jsResource != null) { + requireResource(jsResource); + } + append("\n }"); append("\n if (arguments.length === 0) {"); append("\n if (!(this instanceof CLS)) {"); diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sun Nov 09 10:36:08 2014 +0100 @@ -235,11 +235,7 @@ while (resource.startsWith("/")) { resource = resource.substring(1); } - InputStream emul = resources.get(resource); - if (emul == null) { - throw new IOException("Can't find " + resource); - } - readResource(emul, this); + requireResourceImpl(resource); asBinary.remove(resource); } scripts = new StringArray(); @@ -260,6 +256,14 @@ } } + final void requireResourceImpl(String resource) throws IOException { + InputStream emul = resources.get(resource); + if (emul == null) { + throw new IOException("Can't find " + resource); + } + readResource(emul, this); + } + private static void readResource(InputStream emul, Appendable out) throws IOException { try { int state = 0; @@ -703,6 +707,11 @@ out.append("\n return vm.").append(cls).append("(instance);"); out.append("\n}"); } + + @Override + protected void requireResource(String resourcePath) throws IOException { + requireResourceImpl(resourcePath); + } } private static final class Extension extends VM { @@ -795,5 +804,10 @@ out.append(cls).append(" = f;})(instance);"); out.append("\n}"); } + + @Override + protected void requireResource(String resourcePath) throws IOException { + requireResourceImpl(resourcePath); + } } } diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Sun Nov 09 10:36:08 2014 +0100 @@ -146,5 +146,10 @@ String accessClass(String classOperation) { return "vm." + classOperation; } + + @Override + protected void requireResource(String resourcePath) throws IOException { + requireReference(resourcePath); + } } } diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/test/java/org/apidesign/vm4brwsr/Resources.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Resources.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Resources.java Sun Nov 09 10:36:08 2014 +0100 @@ -23,11 +23,13 @@ import java.util.Enumeration; import net.java.html.js.JavaScriptBody; import net.java.html.js.JavaScriptResource; +import org.apidesign.bck2brwsr.core.ExtraJavaScript; /** * * @author Jaroslav Tulach */ +@ExtraJavaScript(resource = "org/apidesign/vm4brwsr/var.js", processByteCode = true) @JavaScriptResource("obj.js") public class Resources { @JavaScriptBody(args = {}, body = "return obj;") @@ -38,8 +40,8 @@ public static boolean isObj() { return retObj() != null; } - public static boolean isResource() { - return Resources.class.getResource("obj.js") != null; + public static boolean isResource(String name) { + return Resources.class.getResource(name) != null; } public static String loadKO() throws IOException { diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/test/java/org/apidesign/vm4brwsr/ResourcesWithExtensionsTest.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/ResourcesWithExtensionsTest.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/ResourcesWithExtensionsTest.java Sun Nov 09 10:36:08 2014 +0100 @@ -54,7 +54,13 @@ } @Test public void objJSIsFound() throws Exception { assertExec("The resources used as @JavaScriptResource aren't available", - Resources.class, "isResource__Z", 0.0 + Resources.class, "isResource__ZLjava_lang_String_2", 0.0, "obj" + ); + } + + @Test public void thisObjJSIsFound() throws Exception { + assertExec("The resources used as @JavaScriptResource aren't available", + Resources.class, "isResource__ZLjava_lang_String_2", 0.0, "thisObj" ); } diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Sun Nov 09 10:36:08 2014 +0100 @@ -171,7 +171,7 @@ ScriptEngine js = sem.getEngineByExtension("js"); eng[0] = js; Bck2Brwsr.newCompiler().resources(new EmulationResources()) - .obfuscation(ObfuscationLevel.FULL).generate(sb); + .obfuscation(ObfuscationLevel.NONE).generate(sb); } Set exp = new HashSet(); for (String n : names) { diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVM.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVM.java Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVM.java Sun Nov 09 10:36:08 2014 +0100 @@ -43,4 +43,8 @@ @Override protected void requireScript(String resourcePath) { } + + @Override + protected void requireResource(String resourcePath) throws IOException { + } } diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/test/resources/org/apidesign/vm4brwsr/obj.js --- a/rt/vm/src/test/resources/org/apidesign/vm4brwsr/obj.js Sun Nov 09 10:35:21 2014 +0100 +++ b/rt/vm/src/test/resources/org/apidesign/vm4brwsr/obj.js Sun Nov 09 10:36:08 2014 +0100 @@ -15,6 +15,6 @@ * along with this program. Look for COPYING file in the top folder. * If not, see http://opensource.org/licenses/GPL-2.0. */ -var obj = {}; +this.thisObj = {}; diff -r 15f7116b57b6 -r fd3a354d6e8f rt/vm/src/test/resources/org/apidesign/vm4brwsr/var.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/vm/src/test/resources/org/apidesign/vm4brwsr/var.js Sun Nov 09 10:36:08 2014 +0100 @@ -0,0 +1,20 @@ +/* + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +var obj = {}; + +