Using named function expression allows an easy self reference from inside the function. Plus giving byte code tranlators a chance to customize the field to store the method into
1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Nov 28 00:29:00 2012 +0100
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Nov 28 13:41:33 2012 +0100
1.3 @@ -49,6 +49,16 @@
1.4 * @param resourcePath name of resources to read
1.5 */
1.6 protected abstract void requireScript(String resourcePath);
1.7 +
1.8 + /** Allows subclasses to redefine what field a function representing a
1.9 + * class gets assigned. By default it returns the suggested name followed
1.10 + * by <code>" = "</code>;
1.11 + *
1.12 + * @param className suggested name of the class
1.13 + */
1.14 + protected String assignClass(String className) {
1.15 + return className + " = ";
1.16 + }
1.17
1.18 /**
1.19 * Converts a given class file to a JavaScript version.
1.20 @@ -74,23 +84,21 @@
1.21 }
1.22 StringArray toInitilize = new StringArray();
1.23 final String className = className(jc);
1.24 - out.append("\n\n").append(className);
1.25 - out.append(" = function() {");
1.26 - out.append("\n if (!").append(className).
1.27 - append(".prototype.$instOf_").append(className).append(") {");
1.28 + out.append("\n\n").append(assignClass(className));
1.29 + out.append("function CLS() {");
1.30 + out.append("\n if (!CLS.prototype.$instOf_").append(className).append(") {");
1.31 for (FieldData v : jc.getFields()) {
1.32 if (v.isStatic()) {
1.33 - generateStaticField(v);
1.34 + out.append("\n CLS.").append(v.getName()).append(initField(v));
1.35 }
1.36 }
1.37 // ClassName sc = jc.getSuperClass();
1.38 String sc = jc.getSuperClassName(); // with _
1.39 if (sc != null) {
1.40 - out.append("\n var p = ").append(className)
1.41 - .append(".prototype = ").
1.42 + out.append("\n var p = CLS.prototype = ").
1.43 append(sc.replace('/', '_')).append("(true);");
1.44 } else {
1.45 - out.append("\n var p = ").append(className).append(".prototype;");
1.46 + out.append("\n var p = CLS.prototype;");
1.47 }
1.48 for (MethodData m : jc.getMethods()) {
1.49 if (m.isStatic()) {
1.50 @@ -104,7 +112,7 @@
1.51 out.append("\n p.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
1.52 }
1.53 out.append("\n if (arguments.length === 0) {");
1.54 - out.append("\n return new ").append(className).append("();");
1.55 + out.append("\n return new CLS();");
1.56 out.append("\n }");
1.57 out.append("\n }");
1.58 out.append("\n if (arguments.length === 0) {");
1.59 @@ -116,7 +124,7 @@
1.60 }
1.61 out.append("\n return this;");
1.62 out.append("\n }");
1.63 - out.append("\n return new ").append(className).append(";");
1.64 + out.append("\n return new CLS;");
1.65 out.append("\n}");
1.66 StringBuilder sb = new StringBuilder();
1.67 for (String init : toInitilize.toArray()) {
1.68 @@ -833,12 +841,6 @@
1.69 }
1.70 }
1.71
1.72 - private void generateStaticField(FieldData v) throws IOException {
1.73 - out.append("\n ")
1.74 - .append(className(jc))
1.75 - .append('.').append(v.getName()).append(initField(v));
1.76 - }
1.77 -
1.78 private String findMethodName(MethodData m, StringBuilder cnt) {
1.79 StringBuilder name = new StringBuilder();
1.80 if ("<init>".equals(m.getName())) { // NOI18N
2.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazy.java Wed Nov 28 00:29:00 2012 +0100
2.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMLazy.java Wed Nov 28 13:41:33 2012 +0100
2.3 @@ -43,4 +43,9 @@
2.4 @Override
2.5 protected void requireScript(String resourcePath) {
2.6 }
2.7 +
2.8 + @Override
2.9 + protected String assignClass(String className) {
2.10 + return "arguments[0][arguments[1]]=";
2.11 + }
2.12 }
3.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Wed Nov 28 00:29:00 2012 +0100
3.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Wed Nov 28 13:41:33 2012 +0100
3.3 @@ -53,9 +53,7 @@
3.4 sb.append("\n this.constructor.prototype.loadClass = function(res, name) {");
3.5 sb.append("\n var script = org_apidesign_vm4brwsr_VMLazy(true).toJavaScriptLjava_lang_StringAB(loader.get(res + '.class'));");
3.6 sb.append("\n try {");
3.7 - sb.append("\n new Function(");
3.8 - sb.append("\n 'arguments[0][arguments[1]]=' + script + ';'");
3.9 - sb.append("\n )(self, name);");
3.10 + sb.append("\n new Function(script)(self, name);");
3.11 sb.append("\n } catch (ex) {");
3.12 sb.append("\n throw 'Cannot compile ' + res + ' error: ' + ex + ' script:\\n' + script;");
3.13 sb.append("\n };");