nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
changeset 18885 6b6801c3b81a
parent 18851 bdb92c95f886
child 19088 153f268bfa72
equal deleted inserted replaced
18884:b2032ab50ac4 18885:6b6801c3b81a
   550      * @return resulting NativeArray
   550      * @return resulting NativeArray
   551      */
   551      */
   552     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
   552     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
   553     public static Object concat(final Object self, final Object... args) {
   553     public static Object concat(final Object self, final Object... args) {
   554         final ArrayList<Object> list = new ArrayList<>();
   554         final ArrayList<Object> list = new ArrayList<>();
   555         final Object selfToObject = Global.toObject(self);
   555         concatToList(list, Global.toObject(self));
   556 
   556 
   557         if (isArray(selfToObject)) {
   557         for (final Object obj : args) {
   558             final Iterator<Object> iter = arrayLikeIterator(selfToObject, true);
   558             concatToList(list, obj);
   559             while (iter.hasNext()) {
   559         }
   560                 list.add(iter.next());
   560 
       
   561         return new NativeArray(list.toArray());
       
   562     }
       
   563 
       
   564     private static void concatToList(final ArrayList<Object> list, final Object obj) {
       
   565         final boolean isScriptArray = isArray(obj);
       
   566         final boolean isScriptObject = isScriptArray || obj instanceof ScriptObject;
       
   567         if (isScriptArray || obj instanceof Iterable || (obj != null && obj.getClass().isArray())) {
       
   568             final Iterator<Object> iter = arrayLikeIterator(obj, true);
       
   569             if (iter.hasNext()) {
       
   570                 for(int i = 0; iter.hasNext(); ++i) {
       
   571                     final Object value = iter.next();
       
   572                     if(value == ScriptRuntime.UNDEFINED && isScriptObject && !((ScriptObject)obj).has(i)) {
       
   573                         // TODO: eventually rewrite arrayLikeIterator to use a three-state enum for handling
       
   574                         // UNDEFINED instead of an "includeUndefined" boolean with states SKIP, INCLUDE,
       
   575                         // RETURN_EMPTY. Until then, this is how we'll make sure that empty elements don't make it
       
   576                         // into the concatenated array.
       
   577                         list.add(ScriptRuntime.EMPTY);
       
   578                     } else {
       
   579                         list.add(value);
       
   580                     }
       
   581                 }
       
   582             } else if (!isScriptArray) {
       
   583                 list.add(obj); // add empty object, but not an empty array
   561             }
   584             }
   562         } else {
   585         } else {
   563             // single element, add it
   586             // single element, add it
   564             list.add(selfToObject);
   587             list.add(obj);
   565         }
   588         }
   566 
       
   567         for (final Object obj : args) {
       
   568             if (isArray(obj) || obj instanceof Iterable || (obj != null && obj.getClass().isArray())) {
       
   569                 final Iterator<Object> iter = arrayLikeIterator(obj, true);
       
   570                 if (iter.hasNext()) {
       
   571                     while (iter.hasNext()) {
       
   572                         list.add(iter.next());
       
   573                     }
       
   574                 } else if (!isArray(obj)) {
       
   575                     list.add(obj); // add empty object, but not an empty array
       
   576                 }
       
   577             } else {
       
   578                 // single element, add it
       
   579                 list.add(obj);
       
   580             }
       
   581         }
       
   582 
       
   583         return new NativeArray(list.toArray());
       
   584     }
   589     }
   585 
   590 
   586     /**
   591     /**
   587      * ECMA 15.4.4.5 Array.prototype.join (separator)
   592      * ECMA 15.4.4.5 Array.prototype.join (separator)
   588      *
   593      *