Ability to control prototypes. Making sure any JavaScript Object is instance of Java object
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/core/src/main/java/org/apidesign/bck2brwsr/core/JavaScriptPrototype.java Sun Dec 02 21:00:12 2012 +0100
1.3 @@ -0,0 +1,41 @@
1.4 +/**
1.5 + * Back 2 Browser Bytecode Translator
1.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
1.7 + *
1.8 + * This program is free software: you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License as published by
1.10 + * the Free Software Foundation, version 2 of the License.
1.11 + *
1.12 + * This program is distributed in the hope that it will be useful,
1.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.15 + * GNU General Public License for more details.
1.16 + *
1.17 + * You should have received a copy of the GNU General Public License
1.18 + * along with this program. Look for COPYING file in the top folder.
1.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
1.20 + */
1.21 +package org.apidesign.bck2brwsr.core;
1.22 +
1.23 +import java.lang.annotation.ElementType;
1.24 +import java.lang.annotation.Retention;
1.25 +import java.lang.annotation.RetentionPolicy;
1.26 +import java.lang.annotation.Target;
1.27 +
1.28 +/** Controls how JavaScript inheritance should be handled.
1.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.30 + */
1.31 +@Retention(RetentionPolicy.CLASS)
1.32 +@Target({ ElementType.TYPE })
1.33 +public @interface JavaScriptPrototype {
1.34 + /** Expression that identifies the function where all methods
1.35 + * should be added into.
1.36 + * @return name of function to contain methods found in given class
1.37 + */
1.38 + String container();
1.39 + /** Expression that defines the way to construct prototype for this
1.40 + * class.
1.41 + * @return expression to construct prototype
1.42 + */
1.43 + String prototype();
1.44 +}
2.1 --- a/emul/src/main/java/java/lang/Object.java Sun Dec 02 06:25:28 2012 +0100
2.2 +++ b/emul/src/main/java/java/lang/Object.java Sun Dec 02 21:00:12 2012 +0100
2.3 @@ -26,6 +26,7 @@
2.4 package java.lang;
2.5
2.6 import org.apidesign.bck2brwsr.core.JavaScriptBody;
2.7 +import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
2.8
2.9 /**
2.10 * Class {@code Object} is the root of the class hierarchy.
2.11 @@ -36,6 +37,7 @@
2.12 * @see java.lang.Class
2.13 * @since JDK1.0
2.14 */
2.15 +@JavaScriptPrototype(container = "Object.prototype", prototype = "new Object")
2.16 public class Object {
2.17
2.18 @JavaScriptBody(args = {}, body = "")
3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Dec 02 06:25:28 2012 +0100
3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Dec 02 21:00:12 2012 +0100
3.3 @@ -82,6 +82,10 @@
3.4 return null;
3.5 }
3.6 }
3.7 + String[] proto = findAnnotation(arrData, jc,
3.8 + "org.apidesign.bck2brwsr.core.JavaScriptPrototype",
3.9 + "container", "prototype"
3.10 + );
3.11 StringArray toInitilize = new StringArray();
3.12 final String className = className(jc);
3.13 out.append("\n\n").append(assignClass(className));
3.14 @@ -92,25 +96,26 @@
3.15 out.append("\n CLS.").append(v.getName()).append(initField(v));
3.16 }
3.17 }
3.18 - // ClassName sc = jc.getSuperClass();
3.19 - String sc = jc.getSuperClassName(); // with _
3.20 - if (sc != null) {
3.21 + if (proto == null) {
3.22 + String sc = jc.getSuperClassName(); // with _
3.23 out.append("\n var p = CLS.prototype = ").
3.24 append(sc.replace('/', '_')).append("(true);");
3.25 + out.append("\n var c = p;");
3.26 } else {
3.27 - out.append("\n var p = CLS.prototype;");
3.28 + out.append("\n var p = ").append(proto[1]).append(";");
3.29 + out.append("\n var c = ").append(proto[0]).append(";");
3.30 }
3.31 for (MethodData m : jc.getMethods()) {
3.32 if (m.isStatic()) {
3.33 - generateStaticMethod("\n p.", m, toInitilize);
3.34 + generateStaticMethod("\n c.", m, toInitilize);
3.35 } else {
3.36 - generateInstanceMethod("\n p.", m);
3.37 + generateInstanceMethod("\n c.", m);
3.38 }
3.39 }
3.40 - out.append("\n p.constructor = CLS;");
3.41 - out.append("\n p.$instOf_").append(className).append(" = true;");
3.42 + out.append("\n c.constructor = CLS;");
3.43 + out.append("\n c.$instOf_").append(className).append(" = true;");
3.44 for (String superInterface : jc.getSuperInterfaces()) {
3.45 - out.append("\n p.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
3.46 + out.append("\n c.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
3.47 }
3.48 out.append("\n }");
3.49 out.append("\n if (arguments.length === 0) {");
4.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Sun Dec 02 06:25:28 2012 +0100
4.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Sun Dec 02 21:00:12 2012 +0100
4.3 @@ -117,4 +117,12 @@
4.4
4.5 return constructor(x) == constructor(y);
4.6 }
4.7 + @JavaScriptBody(args = {}, body = "return {};")
4.8 + private static Object jsObj() {
4.9 + return null;
4.10 + }
4.11 +
4.12 + public static boolean iofObject() {
4.13 + return jsObj() instanceof Object;
4.14 + }
4.15 }
5.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Sun Dec 02 06:25:28 2012 +0100
5.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Sun Dec 02 21:00:12 2012 +0100
5.3 @@ -123,6 +123,14 @@
5.4 Double.valueOf(0)
5.5 );
5.6 }
5.7 +
5.8 + @Test public void jsObjectIsLikeJavaObject() throws Exception {
5.9 + assertExec(
5.10 + "JavaScript object is instance of Java Object",
5.11 + Instance.class, "iofObjectZ",
5.12 + Double.valueOf(1)
5.13 + );
5.14 + }
5.15
5.16 protected String startCompilationWith() {
5.17 return "org/apidesign/vm4brwsr/Instance";