Ensure vararg copy behavior for specific case of arrayListOf in JS.

This commit is contained in:
Ilya Gorbunov
2015-10-16 05:12:43 +03:00
parent 446cdc087d
commit 59f88cfb52
4 changed files with 39 additions and 9 deletions
+10 -5
View File
@@ -16,13 +16,18 @@
package java.util
public fun HashSet<E>(c: Collection<E>): HashSet<E> = HashSet<E>(c.size()).apply { addAll(c) }
public fun HashSet<E>(c: Collection<E>): HashSet<E>
= HashSet<E>(c.size()).apply { addAll(c) }
public fun LinkedHashSet<E>(c: Collection<E>): HashSet<E> = LinkedHashSet<E>(c.size()).apply { addAll(c) }
public fun LinkedHashSet<E>(c: Collection<E>): HashSet<E>
= LinkedHashSet<E>(c.size()).apply { addAll(c) }
public fun HashMap<K, V>(m: Map<K, V>): HashMap<K, V> = HashMap<K, V>(m.size()).apply { putAll(m) }
public fun HashMap<K, V>(m: Map<K, V>): HashMap<K, V>
= HashMap<K, V>(m.size()).apply { putAll(m) }
public fun LinkedHashMap<K, V>(m: Map<K, V>): LinkedHashMap<K, V> = LinkedHashMap<K, V>(m.size()).apply { putAll(m) }
public fun LinkedHashMap<K, V>(m: Map<K, V>): LinkedHashMap<K, V>
= LinkedHashMap<K, V>(m.size()).apply { putAll(m) }
public fun ArrayList<E>(c: Collection<E>): ArrayList<E> = ArrayList<E>().apply { asDynamic().array = c.toTypedArray<Any?>() } // black dynamic magic
public fun ArrayList<E>(c: Collection<E>): ArrayList<E>
= ArrayList<E>().apply { asDynamic().array = c.toTypedArray<Any?>() } // black dynamic magic
+4
View File
@@ -91,3 +91,7 @@ internal fun <T> arrayPlusCollection(array: dynamic, collection: Collection<T>):
for (element in collection) result[index++] = element
return result
}
// copies vararg array due to different spread vararg behavior in JS.
// After fixing #KT-6491 may return `this`
internal inline fun <T> Array<out T>.varargToArrayOfAny(): Array<out Any?> = this.copyOf()
@@ -50,8 +50,8 @@ private class ArrayAsCollection<T>(val values: Array<out T>): Collection<T> {
override fun contains(o: T): Boolean = values.contains(o)
override fun containsAll(c: Collection<T>): Boolean = c.all { contains(it) }
override fun iterator(): Iterator<T> = values.iterator()
// override of hidden toArray method implementation to prevent copying of values array
public fun toArray(): Array<out Any?> = values
// override hidden toArray implementation to prevent copying of values array
public fun toArray(): Array<out Any?> = values.varargToArrayOfAny()
}
/** Returns an empty read-only list. The returned list is serializable (JVM). */
@@ -72,10 +72,12 @@ public fun <T> listOf(value: T): List<T> = Collections.singletonList(value)
/** Returns a new [LinkedList] with the given elements. */
@JvmVersion
public fun <T> linkedListOf(vararg values: T): LinkedList<T> = LinkedList(ArrayAsCollection(values))
public fun <T> linkedListOf(vararg values: T): LinkedList<T>
= if (values.size() == 0) LinkedList() else LinkedList(ArrayAsCollection(values))
/** Returns a new [ArrayList] with the given elements. */
public fun <T> arrayListOf(vararg values: T): ArrayList<T> = ArrayList(ArrayAsCollection(values))
public fun <T> arrayListOf(vararg values: T): ArrayList<T>
= if (values.size() == 0) ArrayList() else ArrayList(ArrayAsCollection(values))
/** Returns a new read-only list either of single given element, if it is not null, or empty list it the element is null. The returned list is serializable (JVM). */
public fun <T : Any> listOfNotNull(value: T?): List<T> = if (value != null) listOf(value) else emptyList()
@@ -146,6 +148,11 @@ internal fun <T> Iterable<T>.convertToSetForSetOperation(): Collection<T> =
else -> toHashSet()
}
// copies typed varargs array to array of objects
@JvmVersion
private fun <T> Array<out T>.varargToArrayOfAny(): Array<Any?>
= Arrays.copyOf(this, this.size(), Array<Any?>::class.java)
/**
* Searches this list or its range for the provided [element] index using binary search algorithm.
* The list is expected to be sorted into ascending order according to the Comparable natural ordering of its elements.
@@ -34,4 +34,18 @@ class JavautilCollectionsTest {
val array = TEST_LIST.toTypedArray()
assertEquals(array.toList(), TEST_LIST)
}
@test fun arrayListDoesNotCreateArrayView() {
val array = arrayOf(1)
val list = arrayListOf(*array)
assertEquals(1, list[0])
array[0] = 2
assertEquals(1, list[0])
val arrayOfAny = arrayOf<Any>("first")
val listOfAny = arrayListOf(*arrayOfAny)
assertEquals("first", listOfAny[0])
arrayOfAny[0] = "last"
assertEquals("first", listOfAny[0])
}
}