From 048a3ebcc1f2930025fe8a13d7bb381b5dcc6f83 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 10 Jul 2015 20:01:25 +0300 Subject: [PATCH] Implement plus for sequence as operand and refactor plus tests. --- libraries/stdlib/src/generated/_Generators.kt | 30 +++++++++++++++ .../kotlin/collections/MutableCollections.kt | 6 +++ .../stdlib/test/collections/CollectionTest.kt | 29 ++++++-------- .../stdlib/test/collections/IterableTests.kt | 24 ++++++------ .../stdlib/test/collections/SequenceTest.kt | 37 ++++++++---------- .../test/collections/SetOperationsTest.kt | 38 ++++++++++--------- .../src/templates/Generators.kt | 36 ++++++++++++++++-- 7 files changed, 127 insertions(+), 73 deletions(-) diff --git a/libraries/stdlib/src/generated/_Generators.kt b/libraries/stdlib/src/generated/_Generators.kt index 8f5ebf60411..669273ccc14 100644 --- a/libraries/stdlib/src/generated/_Generators.kt +++ b/libraries/stdlib/src/generated/_Generators.kt @@ -717,6 +717,26 @@ public fun Set.plus(element: T): Set { return result } +/** + * Returns a list containing all elements of the original collection and then all elements of the given [sequence]. + */ +public fun Collection.plus(sequence: Sequence): List { + val result = ArrayList(this.size() + 10) + result.addAll(this) + result.addAll(sequence) + return result +} + +/** + * Returns a list containing all elements of the original collection and then all elements of the given [sequence]. + */ +public fun Iterable.plus(sequence: Sequence): List { + val result = ArrayList() + result.addAll(this) + result.addAll(sequence) + return result +} + /** * Returns a sequence containing all elements of original sequence and then all elements of the given [sequence]. */ @@ -724,6 +744,16 @@ public fun Sequence.plus(sequence: Sequence): Sequence { return sequenceOf(this, sequence).flatten() } +/** + * Returns a set containing all elements both of the original set and the given [sequence]. + */ +public fun Set.plus(sequence: Sequence): Set { + val result = LinkedHashSet(mapCapacity(this.size() * 2)) + result.addAll(this) + result.addAll(sequence) + return result +} + /** * Returns a list of pairs built from elements of both collections with same indexes. List has length of shortest collection. */ diff --git a/libraries/stdlib/src/kotlin/collections/MutableCollections.kt b/libraries/stdlib/src/kotlin/collections/MutableCollections.kt index 9a243c1e70d..e88d6dd5eb5 100644 --- a/libraries/stdlib/src/kotlin/collections/MutableCollections.kt +++ b/libraries/stdlib/src/kotlin/collections/MutableCollections.kt @@ -21,6 +21,12 @@ public fun MutableCollection.plusAssign(array: Array) { this.addAll(array) } +/** + * Adds all elements of the given [sequence] to this mutable collection. + */ +public fun MutableCollection.plusAssign(sequence: Sequence) { + this.addAll(sequence) +} /** * Adds all elements of the given [iterable] to this [MutableCollection]. diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index e7ae486b969..99ec3b43b28 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -197,32 +197,23 @@ class CollectionTest { assertEquals(listOf(2, 4, 6), range) } - test fun plusElement() { + fun testPlus(doPlus: (List) -> List) { val list = listOf("foo", "bar") - val list2: List = list + "cheese" + val list2: List = doPlus(list) assertEquals(listOf("foo", "bar"), list) - assertEquals(listOf("foo", "bar", "cheese"), list2) + assertEquals(listOf("foo", "bar", "cheese", "wine"), list2) } + test fun plusElement() = testPlus { it + "cheese" + "wine" } + test fun plusCollection() = testPlus { it + listOf("cheese", "wine") } + test fun plusArray() = testPlus { it + arrayOf("cheese", "wine") } + test fun plusSequence() = testPlus { it + sequenceOf("cheese", "wine") } + test fun plusCollectionBug() { val list = listOf("foo", "bar") + listOf("cheese", "wine") assertEquals(listOf("foo", "bar", "cheese", "wine"), list) } - test fun plusCollection() { - val a = listOf("foo", "bar") - val b = listOf("cheese", "wine") - val list: List = a + b - assertEquals(listOf("foo", "bar", "cheese", "wine"), list) - } - - test fun plusArray() { - val a = listOf("foo", "bar") - val b = arrayOf("cheese", "wine") - val list: List = a + b - assertEquals(listOf("foo", "bar", "cheese", "wine"), list) - - } test fun plusAssign() { // lets use a mutable variable of readonly list @@ -231,13 +222,15 @@ class CollectionTest { l += "foo" l += listOf("beer") l += arrayOf("cheese", "wine") - assertEquals(listOf("cheese", "foo", "beer", "cheese", "wine"), l) + l += sequenceOf("bar", "foo") + assertEquals(listOf("cheese", "foo", "beer", "cheese", "wine", "bar", "foo"), l) assertTrue(l !== lOriginal) val ml = arrayListOf("cheese") ml += "foo" ml += listOf("beer") ml += arrayOf("cheese", "wine") + ml += sequenceOf("bar", "foo") assertEquals(l, ml) } diff --git a/libraries/stdlib/test/collections/IterableTests.kt b/libraries/stdlib/test/collections/IterableTests.kt index a7cf970f667..aa237c98357 100644 --- a/libraries/stdlib/test/collections/IterableTests.kt +++ b/libraries/stdlib/test/collections/IterableTests.kt @@ -282,23 +282,20 @@ abstract class IterableTests>(val data: T, val empty: T) { assertEquals("FOO-BAR", result) } - Test - fun plusElement() { - val result = data + "zoo" + "g" + fun testPlus(doPlus: (Iterable) -> List) { + val result: List = doPlus(data) assertEquals(listOf("foo", "bar", "zoo", "g"), result) + assertFalse(result === data) } Test - fun plusCollection() { - val result = data + listOf("zoo", "g") - assertEquals(listOf("foo", "bar", "zoo", "g"), result) - } - + fun plusElement() = testPlus { it + "zoo" + "g" } Test - fun plusArray() { - val result = data + arrayOf("zoo", "g") - assertEquals(listOf("foo", "bar", "zoo", "g"), result) - } + fun plusCollection() = testPlus { it + listOf("zoo", "g") } + Test + fun plusArray() = testPlus { it + arrayOf("zoo", "g") } + Test + fun plusSequence() = testPlus { it + sequenceOf("zoo", "g") } Test fun plusAssign() { @@ -307,7 +304,8 @@ abstract class IterableTests>(val data: T, val empty: T) { result += "foo" result += listOf("beer") result += arrayOf("cheese", "wine") - assertEquals(listOf("foo", "bar", "foo", "beer", "cheese", "wine"), result) + result += sequenceOf("zoo", "g") + assertEquals(listOf("foo", "bar", "foo", "beer", "cheese", "wine", "zoo", "g"), result) } } diff --git a/libraries/stdlib/test/collections/SequenceTest.kt b/libraries/stdlib/test/collections/SequenceTest.kt index c8eb0bdfde0..87e8426c3ea 100644 --- a/libraries/stdlib/test/collections/SequenceTest.kt +++ b/libraries/stdlib/test/collections/SequenceTest.kt @@ -132,33 +132,28 @@ public class SequenceTest { assertEquals("144, 233, 377, 610, 987", fibonacci().filter { it > 100 }.takeWhile { it < 1000 }.joinToString()) } - test fun plusElement() { - val sequence = sequenceOf("foo", "bar") - val sequenceCheese: Sequence = sequence + "cheese" - assertEquals(listOf("foo", "bar", "cheese"), sequenceCheese.toList()) + + fun testPlus(doPlus: (Sequence) -> Sequence) { + val seq = sequenceOf("foo", "bar") + val seq2: Sequence = doPlus(seq) + assertEquals(listOf("foo", "bar"), seq.toList()) + assertEquals(listOf("foo", "bar", "cheese", "wine"), seq2.toList()) } - test fun plusCollection() { - val a = sequenceOf("foo", "bar") - val b = listOf("cheese", "wine") - val sequence: Sequence = a + b - assertEquals(listOf("foo", "bar", "cheese", "wine"), sequence.toList()) - } - test fun plusArray() { - val a = sequenceOf("foo", "bar") - val b = listOf("cheese", "wine") - val sequence: Sequence = a + b - assertEquals(listOf("foo", "bar", "cheese", "wine"), sequence.toList()) - } + test fun plusElement() = testPlus { it + "cheese" + "wine" } + test fun plusCollection() = testPlus { it + listOf("cheese", "wine") } + test fun plusArray() = testPlus { it + arrayOf("cheese", "wine") } + test fun plusSequence() = testPlus { it + sequenceOf("cheese", "wine") } test fun plusAssign() { // lets use a mutable variable - var ml = sequenceOf("a") - ml += "foo" - ml += listOf("beer") - ml += arrayOf("cheese", "wine") - assertEquals(listOf("a", "foo", "beer", "cheese", "wine"), ml.toList()) + var seq = sequenceOf("a") + seq += "foo" + seq += listOf("beer") + seq += arrayOf("cheese", "wine") + seq += sequenceOf("bar", "foo") + assertEquals(listOf("a", "foo", "beer", "cheese", "wine", "bar", "foo"), seq.toList()) } diff --git a/libraries/stdlib/test/collections/SetOperationsTest.kt b/libraries/stdlib/test/collections/SetOperationsTest.kt index 7698e0a8ca6..bda3524b6a7 100644 --- a/libraries/stdlib/test/collections/SetOperationsTest.kt +++ b/libraries/stdlib/test/collections/SetOperationsTest.kt @@ -33,33 +33,35 @@ class SetOperationsTest { assertTrue(listOf().intersect(listOf(1)).none()) } - test fun plusElement() { - val set = setOf("foo") - val result: Set = set + "bar" + "bar" - assertEquals(setOf("foo", "bar"), result) + fun testPlus(doPlus: (Set) -> Set) { + val set = setOf("foo", "bar") + val set2: Set = doPlus(set) + assertEquals(setOf("foo", "bar"), set) + assertEquals(setOf("foo", "bar", "cheese", "wine"), set2) } - test fun plusCollection() { - val set = setOf("foo") - val result: Set = set + listOf("bar", "bar") - assertEquals(setOf("foo", "bar"), result) - } - - test fun plusArray() { - val set = setOf("foo") - val result: Set = set + arrayOf("foo", "bar") - assertEquals(setOf("foo", "bar"), result) - } + test fun plusElement() = testPlus { it + "bar" + "cheese" + "wine" } + test fun plusCollection() = testPlus { it + listOf("bar", "cheese", "wine") } + test fun plusArray() = testPlus { it + arrayOf("bar", "cheese", "wine") } + test fun plusSequence() = testPlus { it + sequenceOf("bar", "cheese", "wine") } test fun plusAssign() { // lets use a mutable variable var set = setOf("a") val setOriginal = set set += "foo" - set += listOf("beer") - set += arrayOf("cheese", "wine") - assertEquals(setOf("a", "foo", "beer", "cheese", "wine"), set) + set += listOf("beer", "a") + set += arrayOf("cheese", "beer") + set += sequenceOf("bar", "foo") + assertEquals(setOf("a", "foo", "beer", "cheese", "bar"), set) assertTrue(set !== setOriginal) + + val mset = hashSetOf("a") + mset += "foo" + mset += listOf("beer", "a") + mset += arrayOf("cheese", "beer") + mset += sequenceOf("bar", "foo") + assertEquals(set, mset) } } \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt index 286ffe4958b..c312f36d1f0 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt @@ -137,10 +137,40 @@ fun generators(): List { templates add f("plus(sequence: Sequence)") { - only(Sequences) - doc { "Returns a sequence containing all elements of original sequence and then all elements of the given [sequence]." } - returns("Sequence") + only(Iterables, Sets, Sequences) + doc { "Returns a list containing all elements of the original collection and then all elements of the given [sequence]." } + returns("List") + returns("SELF", Sets, Sequences) body { + """ + val result = ArrayList() + result.addAll(this) + result.addAll(sequence) + return result + """ + } + body(Collections) { + """ + val result = ArrayList(this.size() + 10) + result.addAll(this) + result.addAll(sequence) + return result + """ + } + + // TODO: use immutable set builder when available + doc(Sets) { "Returns a set containing all elements both of the original set and the given [sequence]." } + body(Sets) { + """ + val result = LinkedHashSet(mapCapacity(this.size() * 2)) + result.addAll(this) + result.addAll(sequence) + return result + """ + } + + doc(Sequences) { "Returns a sequence containing all elements of original sequence and then all elements of the given [sequence]." } + body(Sequences) { """ return sequenceOf(this, sequence).flatten() """