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 lazy
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 28 Nov 2012 13:41:33 +0100
branchlazy
changeset 2139dc53108d3df
parent 212 597f96a8e998
child 214 a0f4460130b9
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
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/VMLazy.java
vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java
     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    };");