for (var x in array) should return only expected values
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 23 Sep 2014 21:52:27 +0200
changeset 1702228f26fc1159
parent 1701 0e061b0f80eb
child 1703 3340ef531830
for (var x in array) should return only expected values
rt/emul/mini/src/main/java/java/lang/Class.java
rt/emul/mini/src/main/java/java/lang/reflect/Array.java
rt/emul/mini/src/main/java/java/lang/reflect/Method.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/Array.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java
     1.1 --- a/rt/emul/mini/src/main/java/java/lang/Class.java	Sat Sep 20 12:52:47 2014 +0200
     1.2 +++ b/rt/emul/mini/src/main/java/java/lang/Class.java	Tue Sep 23 21:52:27 2014 +0200
     1.3 @@ -1615,12 +1615,12 @@
     1.4          "var c = Array[sig];\n" +
     1.5          "if (!c) {\n" +
     1.6          "  c = vm.java_lang_Class(true);\n" +
     1.7 -        "  c.jvmName = sig;\n" +
     1.8 -        "  c.superclass = vm.java_lang_Object(false).$class;\n" +
     1.9 -        "  c.array = true;\n" +
    1.10 +        "  Object.defineProperty(c, 'jvmName', { 'configurable': true, 'writable': true, 'value': sig });\n" +
    1.11 +        "  Object.defineProperty(c, 'superclass', { 'configurable': true, 'writable': true, 'value' : vm.java_lang_Object(false).$class });\n" +
    1.12 +        "  Object.defineProperty(c, 'array', { 'configurable': true, 'writable': true, 'value': true });\n" +
    1.13          "  Array[sig] = c;\n" +
    1.14          "}\n" +
    1.15 -        "if (!c.fnc) c.fnc = fnc;\n" +
    1.16 +        "if (!c.fnc) Object.defineProperty(c, 'fnc', { 'configurable': true, 'writable': true, 'value' : fnc });\n" +
    1.17          "return c;"
    1.18      )
    1.19      private static native Class<?> defineArray(String sig, Object fnc);
     2.1 --- a/rt/emul/mini/src/main/java/java/lang/reflect/Array.java	Sat Sep 20 12:52:47 2014 +0200
     2.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Array.java	Tue Sep 23 21:52:27 2014 +0200
     2.3 @@ -26,7 +26,6 @@
     2.4  package java.lang.reflect;
     2.5  
     2.6  import org.apidesign.bck2brwsr.core.Exported;
     2.7 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
     2.8  import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
     2.9  
    2.10  /**
    2.11 @@ -135,12 +134,9 @@
    2.12          if (!array.getClass().isArray()) {
    2.13              throw new IllegalArgumentException("Argument is not an array");
    2.14          }
    2.15 -        return length(array);
    2.16 +        return Method.arrayLength(array);
    2.17      }
    2.18      
    2.19 -    @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
    2.20 -    private static native int length(Object arr);
    2.21 -
    2.22      /**
    2.23       * Returns the value of the indexed component in the specified
    2.24       * array object.  The value is automatically wrapped in an object
    2.25 @@ -600,17 +596,10 @@
    2.26       * Private
    2.27       */
    2.28  
    2.29 -    @JavaScriptBody(args = { "primitive", "sig", "fn", "length" }, body =
    2.30 -          "var arr = new Array(length);\n"
    2.31 -        + "var value = primitive ? 0 : null;\n"
    2.32 -        + "for(var i = 0; i < length; i++) arr[i] = value;\n"
    2.33 -        + "arr.jvmName = sig;\n"
    2.34 -        + "arr.fnc = fn;\n"
    2.35 -//        + "java.lang.System.out.println('Assigned ' + arr.jvmName + ' fn: ' + (!!arr.fnc));\n"
    2.36 -        + "return arr;"
    2.37 -    )
    2.38      @Exported
    2.39 -    private static native Object newArray(boolean primitive, String sig, Object fn, int length);
    2.40 +    private static Object newArray(boolean primitive, String sig, Object fn, int length) {
    2.41 +        return Method.newArray(primitive, sig, fn, length);
    2.42 +    }
    2.43  
    2.44      @Exported
    2.45      private static boolean isInstance(Object arr, String sig)  {
    2.46 @@ -635,14 +624,11 @@
    2.47                  return false;
    2.48              }
    2.49          }
    2.50 -        Class<?> t = classFromFn(fn);
    2.51 +        Class<?> t = Method.classFromFn(fn);
    2.52  //        log(" to check: " + t);
    2.53          return t.isAssignableFrom(c);
    2.54      }
    2.55      
    2.56 -    @JavaScriptBody(args = { "cntstr" }, body = "return cntstr(false).constructor.$class;")
    2.57 -    private static native Class<?> classFromFn(Object cntstr);
    2.58 -
    2.59  //    @JavaScriptBody(args = { "m" }, body = "java.lang.System.out.println(m.toString().toString());")
    2.60  //    private static native void log(Object m);
    2.61      
    2.62 @@ -660,17 +646,11 @@
    2.63          String compsig = sig.substring(1);
    2.64          int len = getLength(arr);
    2.65          for (int i = 0; i < len; i++) {
    2.66 -            setArray(arr, i, multiNewArray(compsig, dims, index + 1, fn));
    2.67 +            Method.setArray(arr, i, multiNewArray(compsig, dims, index + 1, fn));
    2.68          }
    2.69          return arr;
    2.70      }
    2.71      private static Object fromPrimitive(Class<?> t, Object array, int index) {
    2.72 -        return Method.fromPrimitive(t, atArray(array, index));
    2.73 +        return Method.fromPrimitive(t, Method.atArray(array, index));
    2.74      }
    2.75 -    
    2.76 -    @JavaScriptBody(args = { "array", "index" }, body = "return array[index];")
    2.77 -    private static native Object atArray(Object array, int index);
    2.78 -
    2.79 -    @JavaScriptBody(args = { "array", "index", "v" }, body = "array[index] = v;")
    2.80 -    private static native Object setArray(Object array, int index, Object v);
    2.81  }
     3.1 --- a/rt/emul/mini/src/main/java/java/lang/reflect/Method.java	Sat Sep 20 12:52:47 2014 +0200
     3.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Method.java	Tue Sep 23 21:52:27 2014 +0200
     3.3 @@ -744,4 +744,31 @@
     3.4              }
     3.5          };
     3.6      }
     3.7 +    
     3.8 +    //
     3.9 +    // helper methods for Array
    3.10 +    //
    3.11 +    
    3.12 +    @JavaScriptBody(args = { "primitive", "sig", "fn", "length" }, body =
    3.13 +          "var arr = new Array(length);\n"
    3.14 +        + "var value = primitive ? 0 : null;\n"
    3.15 +        + "for(var i = 0; i < length; i++) arr[i] = value;\n"
    3.16 +        + "Object.defineProperty(arr, 'jvmName', { 'configurable': true, 'writable': true, 'value': sig });\n"
    3.17 +        + "Object.defineProperty(arr, 'fnc', { 'configurable': true, 'writable': true, 'value' : fn });\n"
    3.18 +//        + "java.lang.System.out.println('Assigned ' + arr.jvmName + ' fn: ' + (!!arr.fnc));\n"
    3.19 +        + "return arr;"
    3.20 +    )
    3.21 +    static native Object newArray(boolean primitive, String sig, Object fn, int length);
    3.22 +    
    3.23 +    @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
    3.24 +    static native int arrayLength(Object arr);
    3.25 +    
    3.26 +    @JavaScriptBody(args = { "cntstr" }, body = "return cntstr(false).constructor.$class;")
    3.27 +    static native Class<?> classFromFn(Object cntstr);
    3.28 +    @JavaScriptBody(args = { "array", "index" }, body = "return array[index];")
    3.29 +    static native Object atArray(Object array, int index);
    3.30 +
    3.31 +    @JavaScriptBody(args = { "array", "index", "v" }, body = "array[index] = v;")
    3.32 +    static native Object setArray(Object array, int index, Object v);
    3.33 +    
    3.34  }
     4.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sat Sep 20 12:52:47 2014 +0200
     4.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Sep 23 21:52:27 2014 +0200
     4.3 @@ -378,9 +378,11 @@
     4.4          final LocalsMapper lmapper =
     4.5                  new LocalsMapper(stackMapIterator.getArguments());
     4.6  
     4.7 -        boolean obj = "java/lang/Object".equals(jc.getClassName());
     4.8 +        boolean defineProp = 
     4.9 +            "java/lang/Object".equals(jc.getClassName()) ||
    4.10 +            "java/lang/reflect/Array".equals(jc.getClassName());
    4.11          
    4.12 -        if (obj) {
    4.13 +        if (defineProp) {
    4.14              append("Object.defineProperty(").append(destObject).
    4.15              append(", '").append(name).append("', { configurable: true, writable: true, value: function(");
    4.16          } else {
    4.17 @@ -394,10 +396,11 @@
    4.18              append("  throw 'no code found for ")
    4.19                 .append(jc.getClassName()).append('.')
    4.20                 .append(m.getName()).append("';\n");
    4.21 -            if (obj) {
    4.22 -                append("}");
    4.23 +            if (defineProp) {
    4.24 +                append("}});");
    4.25 +            } else {
    4.26 +                append("};");
    4.27              }
    4.28 -            append("};");
    4.29              return;
    4.30          }
    4.31  
    4.32 @@ -1463,7 +1466,7 @@
    4.33          while (openBraces-- > 0) {
    4.34              append('}');
    4.35          }
    4.36 -        if (obj) {
    4.37 +        if (defineProp) {
    4.38              append("\n}});");
    4.39          } else {
    4.40              append("\n};");
     5.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Sat Sep 20 12:52:47 2014 +0200
     5.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Tue Sep 23 21:52:27 2014 +0200
     5.3 @@ -207,4 +207,16 @@
     5.4      public static int multiLen() {
     5.5          return new int[1][0].length;
     5.6      }
     5.7 +    
     5.8 +    @JavaScriptBody(args = { "arr" }, body = 
     5.9 +        "var cnt = '';\n" +
    5.10 +        "if (arr === null) arr = [];\n" +
    5.11 +        "for (var i in arr) { cnt += i; }\n" +
    5.12 +        "return cnt;\n"
    5.13 +    )
    5.14 +    private static native String iterateArray(Object[] arr);
    5.15 +    
    5.16 +    public static String iterateArray(boolean javaArray) {
    5.17 +        return iterateArray(javaArray ? new String[0] : null);
    5.18 +    }
    5.19  }
     6.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Sat Sep 20 12:52:47 2014 +0200
     6.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Tue Sep 23 21:52:27 2014 +0200
     6.3 @@ -71,6 +71,18 @@
     6.4              Double.valueOf(0)
     6.5          );
     6.6      }
     6.7 +
     6.8 +    @Test public void iterateEmptyArray() throws Exception {
     6.9 +        assertExec("No elements in empty array", Array.class, "iterateArray__Ljava_lang_String_2Z", 
    6.10 +            "", false
    6.11 +        );
    6.12 +    }
    6.13 +
    6.14 +    @Test public void iterateEmptyJavaArray() throws Exception {
    6.15 +        assertExec("No elements in empty array", Array.class, "iterateArray__Ljava_lang_String_2Z", 
    6.16 +            "", true
    6.17 +        );
    6.18 +    }
    6.19      
    6.20      @Test public void doesCopyArrayWork() throws Exception {
    6.21          assertExec("Returns 'a'", Array.class, "copyArray__C", Double.valueOf('a'));