--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Tue Jul 16 16:12:26 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Tue Jul 16 17:03:30 2013 +0200
@@ -552,35 +552,40 @@
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object concat(final Object self, final Object... args) {
final ArrayList<Object> list = new ArrayList<>();
- final Object selfToObject = Global.toObject(self);
+ concatToList(list, Global.toObject(self));
+
+ for (final Object obj : args) {
+ concatToList(list, obj);
+ }
+
+ return new NativeArray(list.toArray());
+ }
- if (isArray(selfToObject)) {
- final Iterator<Object> iter = arrayLikeIterator(selfToObject, true);
- while (iter.hasNext()) {
- list.add(iter.next());
+ private static void concatToList(final ArrayList<Object> list, final Object obj) {
+ final boolean isScriptArray = isArray(obj);
+ final boolean isScriptObject = isScriptArray || obj instanceof ScriptObject;
+ if (isScriptArray || obj instanceof Iterable || (obj != null && obj.getClass().isArray())) {
+ final Iterator<Object> iter = arrayLikeIterator(obj, true);
+ if (iter.hasNext()) {
+ for(int i = 0; iter.hasNext(); ++i) {
+ final Object value = iter.next();
+ if(value == ScriptRuntime.UNDEFINED && isScriptObject && !((ScriptObject)obj).has(i)) {
+ // TODO: eventually rewrite arrayLikeIterator to use a three-state enum for handling
+ // UNDEFINED instead of an "includeUndefined" boolean with states SKIP, INCLUDE,
+ // RETURN_EMPTY. Until then, this is how we'll make sure that empty elements don't make it
+ // into the concatenated array.
+ list.add(ScriptRuntime.EMPTY);
+ } else {
+ list.add(value);
+ }
+ }
+ } else if (!isScriptArray) {
+ list.add(obj); // add empty object, but not an empty array
}
} else {
// single element, add it
- list.add(selfToObject);
+ list.add(obj);
}
-
- for (final Object obj : args) {
- if (isArray(obj) || obj instanceof Iterable || (obj != null && obj.getClass().isArray())) {
- final Iterator<Object> iter = arrayLikeIterator(obj, true);
- if (iter.hasNext()) {
- while (iter.hasNext()) {
- list.add(iter.next());
- }
- } else if (!isArray(obj)) {
- list.add(obj); // add empty object, but not an empty array
- }
- } else {
- // single element, add it
- list.add(obj);
- }
- }
-
- return new NativeArray(list.toArray());
}
/**