From 409094f0f7dd481a53a4c1a3f95c59228cb84be7 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Mon, 25 Apr 2016 19:18:35 +0300 Subject: [PATCH] Make stdlib functions dependent on reified is checks available in JS. #KT-11346 Fixed --- libraries/stdlib/src/generated/_Arrays.kt | 32 +++++----- .../stdlib/src/generated/_Collections.kt | 32 +++++----- libraries/stdlib/src/generated/_Sequences.kt | 34 +++++------ .../stdlib/src/kotlin/collections/Arrays.kt | 21 +++++++ .../src/kotlin/collections/ArraysJVM.kt | 19 +++++- .../stdlib/test/collections/ArraysJVMTest.kt | 24 -------- .../stdlib/test/collections/ArraysTest.kt | 33 +++++++++++ .../stdlib/test/collections/CollectionTest.kt | 42 ++++++++++++++ .../src/templates/Filtering.kt | 58 +++++++++++++++++++ .../src/templates/SpecialJVM.kt | 57 +++++------------- 10 files changed, 232 insertions(+), 120 deletions(-) delete mode 100644 libraries/stdlib/test/collections/ArraysJVMTest.kt diff --git a/libraries/stdlib/src/generated/_Arrays.kt b/libraries/stdlib/src/generated/_Arrays.kt index 246b52fefd3..8712d560cbc 100644 --- a/libraries/stdlib/src/generated/_Arrays.kt +++ b/libraries/stdlib/src/generated/_Arrays.kt @@ -3233,6 +3233,21 @@ public inline fun > CharArray.filterIndexedTo(des return destination } +/** + * Returns a list containing all elements that are instances of specified type parameter R. + */ +public inline fun Array<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> { + return filterIsInstanceTo(ArrayList()) +} + +/** + * Appends all elements that are instances of specified type parameter R to the given [destination]. + */ +public inline fun > Array<*>.filterIsInstanceTo(destination: C): C { + for (element in this) if (element is R) destination.add(element) + return destination +} + /** * Returns a list containing all elements not matching the given [predicate]. */ @@ -12583,14 +12598,6 @@ public fun CharArray.fill(element: Char, fromIndex: Int = 0, toIndex: Int = size Arrays.fill(this, fromIndex, toIndex, element) } -/** - * Returns a list containing all elements that are instances of specified type parameter R. - */ -@kotlin.jvm.JvmVersion -public inline fun Array<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> { - return filterIsInstanceTo(ArrayList()) -} - /** * Returns a list containing all elements that are instances of specified class. */ @@ -12599,15 +12606,6 @@ public fun Array<*>.filterIsInstance(klass: Class): List { return filterIsInstanceTo(ArrayList(), klass) } -/** - * Appends all elements that are instances of specified type parameter R to the given [destination]. - */ -@kotlin.jvm.JvmVersion -public inline fun > Array<*>.filterIsInstanceTo(destination: C): C { - for (element in this) if (element is R) destination.add(element) - return destination -} - /** * Appends all elements that are instances of specified class to the given [destination]. */ diff --git a/libraries/stdlib/src/generated/_Collections.kt b/libraries/stdlib/src/generated/_Collections.kt index e0348dfa6b7..1ba5d15cd0c 100644 --- a/libraries/stdlib/src/generated/_Collections.kt +++ b/libraries/stdlib/src/generated/_Collections.kt @@ -626,6 +626,21 @@ public inline fun > Iterable.filterIndexedTo(d return destination } +/** + * Returns a list containing all elements that are instances of specified type parameter R. + */ +public inline fun Iterable<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> { + return filterIsInstanceTo(ArrayList()) +} + +/** + * Appends all elements that are instances of specified type parameter R to the given [destination]. + */ +public inline fun > Iterable<*>.filterIsInstanceTo(destination: C): C { + for (element in this) if (element is R) destination.add(element) + return destination +} + /** * Returns a list containing all elements not matching the given [predicate]. */ @@ -1871,14 +1886,6 @@ public fun Iterable.asSequence(): Sequence { return Sequence { this.iterator() } } -/** - * Returns a list containing all elements that are instances of specified type parameter R. - */ -@kotlin.jvm.JvmVersion -public inline fun Iterable<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> { - return filterIsInstanceTo(ArrayList()) -} - /** * Returns a list containing all elements that are instances of specified class. */ @@ -1887,15 +1894,6 @@ public fun Iterable<*>.filterIsInstance(klass: Class): List { return filterIsInstanceTo(ArrayList(), klass) } -/** - * Appends all elements that are instances of specified type parameter R to the given [destination]. - */ -@kotlin.jvm.JvmVersion -public inline fun > Iterable<*>.filterIsInstanceTo(destination: C): C { - for (element in this) if (element is R) destination.add(element) - return destination -} - /** * Appends all elements that are instances of specified class to the given [destination]. */ diff --git a/libraries/stdlib/src/generated/_Sequences.kt b/libraries/stdlib/src/generated/_Sequences.kt index b39b300bee3..b11d7f0c3ae 100644 --- a/libraries/stdlib/src/generated/_Sequences.kt +++ b/libraries/stdlib/src/generated/_Sequences.kt @@ -332,6 +332,22 @@ public inline fun > Sequence.filterIndexedTo(d return destination } +/** + * Returns a sequence containing all elements that are instances of specified type parameter R. + */ +public inline fun Sequence<*>.filterIsInstance(): Sequence<@kotlin.internal.NoInfer R> { + @Suppress("UNCHECKED_CAST") + return filter { it is R } as Sequence +} + +/** + * Appends all elements that are instances of specified type parameter R to the given [destination]. + */ +public inline fun > Sequence<*>.filterIsInstanceTo(destination: C): C { + for (element in this) if (element is R) destination.add(element) + return destination +} + /** * Returns a sequence containing all elements not matching the given [predicate]. */ @@ -1176,15 +1192,6 @@ public inline fun Sequence.asSequence(): Sequence { return this } -/** - * Returns a sequence containing all elements that are instances of specified type parameter R. - */ -@kotlin.jvm.JvmVersion -public inline fun Sequence<*>.filterIsInstance(): Sequence<@kotlin.internal.NoInfer R> { - @Suppress("UNCHECKED_CAST") - return filter { it is R } as Sequence -} - /** * Returns a sequence containing all elements that are instances of specified class. */ @@ -1194,15 +1201,6 @@ public fun Sequence<*>.filterIsInstance(klass: Class): Sequence { return filter { klass.isInstance(it) } as Sequence } -/** - * Appends all elements that are instances of specified type parameter R to the given [destination]. - */ -@kotlin.jvm.JvmVersion -public inline fun > Sequence<*>.filterIsInstanceTo(destination: C): C { - for (element in this) if (element is R) destination.add(element) - return destination -} - /** * Appends all elements that are instances of specified class to the given [destination]. */ diff --git a/libraries/stdlib/src/kotlin/collections/Arrays.kt b/libraries/stdlib/src/kotlin/collections/Arrays.kt index 640ec52cf8b..b90a42453d1 100644 --- a/libraries/stdlib/src/kotlin/collections/Arrays.kt +++ b/libraries/stdlib/src/kotlin/collections/Arrays.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + @file:kotlin.jvm.JvmMultifileClass @file:kotlin.jvm.JvmName("ArraysKt") @@ -6,6 +22,11 @@ package kotlin.collections import java.util.* + +/** Returns the array if it's not `null`, or an empty array otherwise. */ +public inline fun Array?.orEmpty(): Array = this ?: arrayOf() + + /** * Returns a single list of all elements from all arrays in the given array. */ diff --git a/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt b/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt index 858cb784044..b0a90eba837 100644 --- a/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt +++ b/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + @file:kotlin.jvm.JvmMultifileClass @file:kotlin.jvm.JvmName("ArraysKt") @@ -25,9 +41,6 @@ public inline fun Collection.toTypedArray(): Array { return thisCollection.toArray(arrayOfNulls(thisCollection.size())) as Array } -/** Returns the array if it's not `null`, or an empty array otherwise. */ -public inline fun Array?.orEmpty(): Array = this ?: arrayOf() - /** Internal unsafe construction of array based on reference array type */ internal fun arrayOfNulls(reference: Array, size: Int): Array { @Suppress("UNCHECKED_CAST") diff --git a/libraries/stdlib/test/collections/ArraysJVMTest.kt b/libraries/stdlib/test/collections/ArraysJVMTest.kt deleted file mode 100644 index fce4f892f9e..00000000000 --- a/libraries/stdlib/test/collections/ArraysJVMTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package test.collections - -import kotlin.test.* -import org.junit.Test as test - -class ArraysJVMTest { - - @test fun orEmptyNull() { - val x: Array? = null - val y: Array? = null - val xArray = x.orEmpty() - val yArray = y.orEmpty() - expect(0) { xArray.size } - expect(0) { yArray.size } - } - - @test fun orEmptyNotNull() { - val x: Array? = arrayOf("1", "2") - val xArray = x.orEmpty() - expect(2) { xArray.size } - expect("1") { xArray[0] } - expect("2") { xArray[1] } - } -} diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index a4cebbec7b0..e684939b57d 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package test.collections import test.collections.behaviors.listBehavior @@ -20,6 +36,23 @@ fun assertArrayNotSameButEquals(expected: BooleanArray, actual: BooleanArray, me class ArraysTest { + @test fun orEmptyNull() { + val x: Array? = null + val y: Array? = null + val xArray = x.orEmpty() + val yArray = y.orEmpty() + expect(0) { xArray.size } + expect(0) { yArray.size } + } + + @test fun orEmptyNotNull() { + val x: Array? = arrayOf("1", "2") + val xArray = x.orEmpty() + expect(2) { xArray.size } + expect("1") { xArray[0] } + expect("2") { xArray[1] } + } + @test fun emptyArrayLastIndex() { val arr1 = IntArray(0) assertEquals(-1, arr1.lastIndex) diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index 06724638c8e..3bb00377b34 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -95,6 +95,48 @@ class CollectionTest { } } + @test fun filterIsInstanceList() { + val values: List = listOf(1, 2, 3.0, "abc", "cde") + + val numberValues: List = values.filterIsInstance() + assertEquals(listOf(1, 2, 3.0), numberValues) + + // doesn't distinguish double from int in JS +// val doubleValues: List = values.filterIsInstance() +// assertEquals(listOf(3.0), doubleValues) + + val stringValues: List = values.filterIsInstance() + assertEquals(listOf("abc", "cde"), stringValues) + + // is Any doesn't work in JS, see KT-7665 +// val anyValues: List = values.filterIsInstance() +// assertEquals(values.toList(), anyValues) + + val charValues: List = values.filterIsInstance() + assertEquals(0, charValues.size) + } + + @test fun filterIsInstanceArray() { + val src: Array = arrayOf(1, 2, 3.0, "abc", "cde") + + val numberValues: List = src.filterIsInstance() + assertEquals(listOf(1, 2, 3.0), numberValues) + + // doesn't distinguish double from int in JS +// val doubleValues: List = src.filterIsInstance() +// assertEquals(listOf(3.0), doubleValues) + + val stringValues: List = src.filterIsInstance() + assertEquals(listOf("abc", "cde"), stringValues) + + // is Any doesn't work in JS, see KT-7665 +// val anyValues: List = src.filterIsInstance() +// assertEquals(src.toList(), anyValues) + + val charValues: List = src.filterIsInstance() + assertEquals(0, charValues.size) + } + @test fun foldIndexed() { expect(42) { val numbers = listOf(1, 2, 3, 4) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt index 626a74c735d..d46fb6b6cbf 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package templates import templates.Family.* @@ -543,6 +559,48 @@ fun filtering(): List { } } + templates add f("filterIsInstanceTo(destination: C)") { + doc { "Appends all elements that are instances of specified type parameter R to the given [destination]." } + typeParam("reified R") + typeParam("C : MutableCollection") + inline(true) + receiverAsterisk(true) + returns("C") + exclude(ArraysOfPrimitives, Strings) + body { + """ + for (element in this) if (element is R) destination.add(element) + return destination + """ + } + } + + templates add f("filterIsInstance()") { + doc { "Returns a list containing all elements that are instances of specified type parameter R." } + typeParam("reified R") + returns("List<@kotlin.internal.NoInfer R>") + inline(true) + receiverAsterisk(true) + body { + """ + return filterIsInstanceTo(ArrayList()) + """ + } + exclude(ArraysOfPrimitives, Strings) + + doc(Sequences) { "Returns a sequence containing all elements that are instances of specified type parameter R." } + returns(Sequences) { "Sequence<@kotlin.internal.NoInfer R>" } + inline(true) + receiverAsterisk(true) + body(Sequences) { + """ + @Suppress("UNCHECKED_CAST") + return filter { it is R } as Sequence + """ + } + } + + templates add f("slice(indices: Iterable)") { only(Strings, Lists, ArraysOfPrimitives, ArraysOfObjects) doc { "Returns a list containing elements at specified [indices]." } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt index 7aae0af1ca2..82d27e25c6c 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/SpecialJVM.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package templates import templates.Family.* @@ -231,47 +247,6 @@ fun specialJVM(): List { } } - templates add f("filterIsInstanceTo(destination: C)") { - doc { "Appends all elements that are instances of specified type parameter R to the given [destination]." } - typeParam("reified R") - typeParam("C : MutableCollection") - inline(true) - receiverAsterisk(true) - returns("C") - exclude(ArraysOfPrimitives, Strings) - body { - """ - for (element in this) if (element is R) destination.add(element) - return destination - """ - } - } - - templates add f("filterIsInstance()") { - doc { "Returns a list containing all elements that are instances of specified type parameter R." } - typeParam("reified R") - returns("List<@kotlin.internal.NoInfer R>") - inline(true) - receiverAsterisk(true) - body { - """ - return filterIsInstanceTo(ArrayList()) - """ - } - exclude(ArraysOfPrimitives, Strings) - - doc(Sequences) { "Returns a sequence containing all elements that are instances of specified type parameter R." } - returns(Sequences) { "Sequence<@kotlin.internal.NoInfer R>" } - inline(true) - receiverAsterisk(true) - body(Sequences) { - """ - @Suppress("UNCHECKED_CAST") - return filter { it is R } as Sequence - """ - } - } - templates add f("asList()") { only(ArraysOfObjects, ArraysOfPrimitives) doc { "Returns a [List] that wraps the original array." }