From aac96c476a10241d23f2a7fb5ea3ac4dbf3ef55c Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 7 Sep 2018 07:15:21 +0300 Subject: [PATCH] Rename sequence and iterator builder functions and their scope class This introduces new functions instead of the existing sequence builders: - `sequence` instead of `buildSequence` - `iterator` instead of `buildIterator` - `SequenceScope` instead of `SequenceBuilder` The old functions were deprecated with error and made inline-only, and `SequenceBuilder` has been made a deprecated typealias to `SequenceScope`. Move sequence builders to `SequencesKt` facade class. Replace sequence builder usages in stdlib and samples. #KT-26678 --- .../stdlib/common/src/generated/_Sequences.kt | 2 +- .../src/kotlin/sequences/SequenceBuilder.kt | 31 +++++++++----- .../test/samples/collections/iterables.kt | 2 +- .../test/samples/collections/sequences.kt | 6 +-- .../src/kotlin/collections/Sequences.kt | 8 ++-- .../src/kotlin/collections/SlidingWindow.kt | 2 +- .../test/coroutines/SequenceBuilderTest.kt | 40 +++++++++---------- .../kotlin-stdlib-runtime-merged.txt | 9 ++--- .../src/templates/Generators.kt | 2 +- 9 files changed, 56 insertions(+), 46 deletions(-) diff --git a/libraries/stdlib/common/src/generated/_Sequences.kt b/libraries/stdlib/common/src/generated/_Sequences.kt index 4e29a4ec0f0..61350f39de0 100644 --- a/libraries/stdlib/common/src/generated/_Sequences.kt +++ b/libraries/stdlib/common/src/generated/_Sequences.kt @@ -1658,7 +1658,7 @@ public fun Sequence.zipWithNext(): Sequence> { */ @SinceKotlin("1.2") public fun Sequence.zipWithNext(transform: (a: T, b: T) -> R): Sequence { - return buildSequence result@ { + return sequence result@ { val iterator = iterator() if (!iterator.hasNext()) return@result var current = iterator.next() diff --git a/libraries/stdlib/coroutines/src/kotlin/sequences/SequenceBuilder.kt b/libraries/stdlib/coroutines/src/kotlin/sequences/SequenceBuilder.kt index 095a8bdc3a2..0822820408f 100644 --- a/libraries/stdlib/coroutines/src/kotlin/sequences/SequenceBuilder.kt +++ b/libraries/stdlib/coroutines/src/kotlin/sequences/SequenceBuilder.kt @@ -4,7 +4,7 @@ */ @file:kotlin.jvm.JvmMultifileClass -@file:kotlin.jvm.JvmName("SequenceBuilderKt") +@file:kotlin.jvm.JvmName("SequencesKt") package kotlin.sequences @@ -21,7 +21,12 @@ import kotlin.coroutines.intrinsics.* * @sample samples.collections.Sequences.Building.buildFibonacciSequence */ @SinceKotlin("1.3") -public fun buildSequence(builderAction: suspend SequenceBuilder.() -> Unit): Sequence = Sequence { buildIterator(builderAction) } +public fun sequence(block: suspend SequenceScope.() -> Unit): Sequence = Sequence { iterator(block) } + +@SinceKotlin("1.3") +@Deprecated("Use 'sequence { }' function instead.", ReplaceWith("sequence(builderAction)"), level = DeprecationLevel.ERROR) +@kotlin.internal.InlineOnly +public inline fun buildSequence(noinline builderAction: suspend SequenceScope.() -> Unit): Sequence = Sequence { iterator(builderAction) } /** * Builds an [Iterator] lazily yielding values one by one. @@ -30,24 +35,29 @@ public fun buildSequence(builderAction: suspend SequenceBuilder.() -> Uni * @sample samples.collections.Iterables.Building.iterable */ @SinceKotlin("1.3") -public fun buildIterator(builderAction: suspend SequenceBuilder.() -> Unit): Iterator { +public fun iterator(block: suspend SequenceScope.() -> Unit): Iterator { val iterator = SequenceBuilderIterator() - iterator.nextStep = builderAction.createCoroutineUnintercepted(receiver = iterator, completion = iterator) + iterator.nextStep = block.createCoroutineUnintercepted(receiver = iterator, completion = iterator) return iterator } +@SinceKotlin("1.3") +@Deprecated("Use 'iterator { }' function instead.", ReplaceWith("iterator(builderAction)"), level = DeprecationLevel.ERROR) +@kotlin.internal.InlineOnly +public inline fun buildIterator(noinline builderAction: suspend SequenceScope.() -> Unit): Iterator = iterator(builderAction) + /** - * Builder for a [Sequence] or an [Iterator], provides [yield] and [yieldAll] suspension functions. + * The scope for yielding values of a [Sequence] or an [Iterator], provides [yield] and [yieldAll] suspension functions. * - * @see buildSequence - * @see buildIterator + * @see sequence + * @see iterator * * @sample samples.collections.Sequences.Building.buildSequenceYieldAll * @sample samples.collections.Sequences.Building.buildFibonacciSequence */ @RestrictsSuspension @SinceKotlin("1.3") -public abstract class SequenceBuilder internal constructor() { +public abstract class SequenceScope internal constructor() { /** * Yields a value to the [Iterator] being built. * @@ -85,6 +95,9 @@ public abstract class SequenceBuilder internal constructor() { public suspend fun yieldAll(sequence: Sequence) = yieldAll(sequence.iterator()) } +@Deprecated("Use SequenceScope class instead.", ReplaceWith("SequenceScope"), level = DeprecationLevel.ERROR) +public typealias SequenceBuilder = SequenceScope + private typealias State = Int private const val State_NotReady: State = 0 @@ -94,7 +107,7 @@ private const val State_Ready: State = 3 private const val State_Done: State = 4 private const val State_Failed: State = 5 -private class SequenceBuilderIterator : SequenceBuilder(), Iterator, Continuation { +private class SequenceBuilderIterator : SequenceScope(), Iterator, Continuation { private var state = State_NotReady private var nextValue: T? = null private var nextIterator: Iterator? = null diff --git a/libraries/stdlib/samples/test/samples/collections/iterables.kt b/libraries/stdlib/samples/test/samples/collections/iterables.kt index 0861cff59dc..e1e308964dc 100644 --- a/libraries/stdlib/samples/test/samples/collections/iterables.kt +++ b/libraries/stdlib/samples/test/samples/collections/iterables.kt @@ -26,7 +26,7 @@ class Iterables { @Sample fun iterable() { val iterable = Iterable { - buildIterator { + iterator { yield(42) yieldAll(1..5 step 2) } diff --git a/libraries/stdlib/samples/test/samples/collections/sequences.kt b/libraries/stdlib/samples/test/samples/collections/sequences.kt index 76dbd38ba3b..5618648a22e 100644 --- a/libraries/stdlib/samples/test/samples/collections/sequences.kt +++ b/libraries/stdlib/samples/test/samples/collections/sequences.kt @@ -111,7 +111,7 @@ class Sequences { @Sample fun buildFibonacciSequence() { - fun fibonacci() = buildSequence { + fun fibonacci() = sequence { var terms = Pair(0, 1) // this sequence is infinite @@ -126,7 +126,7 @@ class Sequences { @Sample fun buildSequenceYieldAll() { - val sequence = buildSequence { + val sequence = sequence { val start = 0 // yielding a single value yield(start) @@ -145,7 +145,7 @@ class Sequences { val wrappedCollection = object : AbstractCollection() { override val size: Int = collection.size + 2 - override fun iterator(): Iterator = buildIterator { + override fun iterator(): Iterator = iterator { yield("first") yieldAll(collection) yield("last") diff --git a/libraries/stdlib/src/kotlin/collections/Sequences.kt b/libraries/stdlib/src/kotlin/collections/Sequences.kt index 1e9fcee5024..0e4a05636ef 100644 --- a/libraries/stdlib/src/kotlin/collections/Sequences.kt +++ b/libraries/stdlib/src/kotlin/collections/Sequences.kt @@ -63,7 +63,7 @@ public inline fun Sequence?.orEmpty(): Sequence = this ?: emptySequenc * @sample samples.collections.Sequences.Usage.sequenceIfEmpty */ @SinceKotlin("1.3") -public fun Sequence.ifEmpty(defaultValue: () -> Sequence): Sequence = buildSequence { +public fun Sequence.ifEmpty(defaultValue: () -> Sequence): Sequence = sequence { val iterator = this@ifEmpty.iterator() if (iterator.hasNext()) { yieldAll(iterator) @@ -588,7 +588,7 @@ public fun Sequence.constrainOnce(): Sequence { * The returned sequence is constrained to be iterated only once. * * @see constrainOnce - * @see kotlin.coroutines.experimental.buildSequence + * @see kotlin.sequences.sequence * * @sample samples.collections.Sequences.Building.generateSequence */ @@ -605,7 +605,7 @@ public fun generateSequence(nextFunction: () -> T?): Sequence { * * The sequence can be iterated multiple times, each time starting with [seed]. * - * @see kotlin.coroutines.experimental.buildSequence + * @see kotlin.sequences.sequence * * @sample samples.collections.Sequences.Building.generateSequenceWithSeed */ @@ -625,7 +625,7 @@ public fun generateSequence(seed: T?, nextFunction: (T) -> T?): Sequen * * The sequence can be iterated multiple times. * - * @see kotlin.coroutines.experimental.buildSequence + * @see kotlin.sequences.sequence * * @sample samples.collections.Sequences.Building.generateSequenceWithLazySeed */ diff --git a/libraries/stdlib/src/kotlin/collections/SlidingWindow.kt b/libraries/stdlib/src/kotlin/collections/SlidingWindow.kt index a52b587e190..16cb65b751e 100644 --- a/libraries/stdlib/src/kotlin/collections/SlidingWindow.kt +++ b/libraries/stdlib/src/kotlin/collections/SlidingWindow.kt @@ -23,7 +23,7 @@ internal fun Sequence.windowedSequence(size: Int, step: Int, partialWindo internal fun windowedIterator(iterator: Iterator, size: Int, step: Int, partialWindows: Boolean, reuseBuffer: Boolean): Iterator> { if (!iterator.hasNext()) return EmptyIterator - return buildIterator> { + return iterator> { val gap = step - size if (gap >= 0) { var buffer = ArrayList(size) diff --git a/libraries/stdlib/test/coroutines/SequenceBuilderTest.kt b/libraries/stdlib/test/coroutines/SequenceBuilderTest.kt index 3ee321b8eed..57333999f47 100644 --- a/libraries/stdlib/test/coroutines/SequenceBuilderTest.kt +++ b/libraries/stdlib/test/coroutines/SequenceBuilderTest.kt @@ -10,7 +10,7 @@ import kotlin.test.* class SequenceBuilderTest { @Test fun testSimple() { - val result = buildSequence { + val result = sequence { for (i in 1..3) { yield(2 * i) } @@ -23,7 +23,7 @@ class SequenceBuilderTest { @Test fun testCallHasNextSeveralTimes() { - val result = buildSequence { + val result = sequence { yield(1) } @@ -44,7 +44,7 @@ class SequenceBuilderTest { @Test fun testManualIteration() { - val result = buildSequence { + val result = sequence { yield(1) yield(2) yield(3) @@ -72,7 +72,7 @@ class SequenceBuilderTest { @Test fun testEmptySequence() { - val result = buildSequence {} + val result = sequence {} val iterator = result.iterator() assertFalse(iterator.hasNext()) @@ -84,10 +84,10 @@ class SequenceBuilderTest { @Test fun testLaziness() { var sharedVar = -2 - val result = buildSequence { + val result = sequence { while (true) { when (sharedVar) { - -1 -> return@buildSequence + -1 -> return@sequence -2 -> error("Invalid state: -2") else -> yield(sharedVar) } @@ -116,10 +116,10 @@ class SequenceBuilderTest { @Test fun testExceptionInCoroutine() { var sharedVar = -2 - val result = buildSequence { + val result = sequence { while (true) { when (sharedVar) { - -1 -> return@buildSequence + -1 -> return@sequence -2 -> throw UnsupportedOperationException("-2 is unsupported") else -> yield(sharedVar) } @@ -140,7 +140,7 @@ class SequenceBuilderTest { @Test fun testParallelIteration() { var inc = 0 - val result = buildSequence { + val result = sequence { for (i in 1..3) { inc++ yield(inc * i) @@ -152,7 +152,7 @@ class SequenceBuilderTest { @Test fun testYieldAllIterator() { - val result = buildSequence { + val result = sequence { yieldAll(listOf(1, 2, 3).iterator()) } assertEquals(listOf(1, 2, 3), result.toList()) @@ -160,7 +160,7 @@ class SequenceBuilderTest { @Test fun testYieldAllSequence() { - val result = buildSequence { + val result = sequence { yieldAll(sequenceOf(1, 2, 3)) } assertEquals(listOf(1, 2, 3), result.toList()) @@ -168,7 +168,7 @@ class SequenceBuilderTest { @Test fun testYieldAllCollection() { - val result = buildSequence { + val result = sequence { yieldAll(listOf(1, 2, 3)) } assertEquals(listOf(1, 2, 3), result.toList()) @@ -176,7 +176,7 @@ class SequenceBuilderTest { @Test fun testYieldAllCollectionMixedFirst() { - val result = buildSequence { + val result = sequence { yield(0) yieldAll(listOf(1, 2, 3)) } @@ -185,7 +185,7 @@ class SequenceBuilderTest { @Test fun testYieldAllCollectionMixedLast() { - val result = buildSequence { + val result = sequence { yieldAll(listOf(1, 2, 3)) yield(4) } @@ -194,7 +194,7 @@ class SequenceBuilderTest { @Test fun testYieldAllCollectionMixedBoth() { - val result = buildSequence { + val result = sequence { yield(0) yieldAll(listOf(1, 2, 3)) yield(4) @@ -204,7 +204,7 @@ class SequenceBuilderTest { @Test fun testYieldAllCollectionMixedLong() { - val result = buildSequence { + val result = sequence { yield(0) yieldAll(listOf(1, 2, 3)) yield(4) @@ -219,7 +219,7 @@ class SequenceBuilderTest { @Test fun testYieldAllCollectionOneEmpty() { - val result = buildSequence { + val result = sequence { yieldAll(listOf()) } assertEquals(listOf(), result.toList()) @@ -227,7 +227,7 @@ class SequenceBuilderTest { @Test fun testYieldAllCollectionManyEmpty() { - val result = buildSequence { + val result = sequence { yieldAll(listOf()) yieldAll(listOf()) yieldAll(listOf()) @@ -238,7 +238,7 @@ class SequenceBuilderTest { @Test fun testYieldAllSideEffects() { val effects = arrayListOf() - val result = buildSequence { + val result = sequence { effects.add("a") yieldAll(listOf(1, 2)) effects.add("b") @@ -276,7 +276,7 @@ class SequenceBuilderTest { @Test fun testInfiniteYieldAll() { - val values = buildIterator { + val values = iterator { while (true) { yieldAll((1..5).map { it }) } diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index bd4ed8f1737..8de6a2ad715 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -4448,18 +4448,13 @@ public abstract interface class kotlin/sequences/Sequence { public abstract fun iterator ()Ljava/util/Iterator; } -public abstract class kotlin/sequences/SequenceBuilder { +public abstract class kotlin/sequences/SequenceScope { public abstract fun yield (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun yieldAll (Ljava/lang/Iterable;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun yieldAll (Ljava/util/Iterator;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun yieldAll (Lkotlin/sequences/Sequence;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public final class kotlin/sequences/SequenceBuilderKt { - public static final fun buildIterator (Lkotlin/jvm/functions/Function2;)Ljava/util/Iterator; - public static final fun buildSequence (Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; -} - public final class kotlin/sequences/SequencesKt { public static final fun all (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Z public static final fun any (Lkotlin/sequences/Sequence;)Z @@ -4528,6 +4523,7 @@ public final class kotlin/sequences/SequencesKt { public static final fun indexOf (Lkotlin/sequences/Sequence;Ljava/lang/Object;)I public static final fun indexOfFirst (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)I public static final fun indexOfLast (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)I + public static final fun iterator (Lkotlin/jvm/functions/Function2;)Ljava/util/Iterator; public static final fun joinTo (Lkotlin/sequences/Sequence;Ljava/lang/Appendable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/Appendable; public static synthetic fun joinTo$default (Lkotlin/sequences/Sequence;Ljava/lang/Appendable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/Appendable; public static final fun joinToString (Lkotlin/sequences/Sequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/String; @@ -4570,6 +4566,7 @@ public final class kotlin/sequences/SequencesKt { public static final fun reduce (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static final fun reduceIndexed (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object; public static final fun requireNoNulls (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; + public static final fun sequence (Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; public static final fun sequenceOf ([Ljava/lang/Object;)Lkotlin/sequences/Sequence; public static final fun single (Lkotlin/sequences/Sequence;)Ljava/lang/Object; public static final fun single (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt index 3c81f681ce8..35dadcc786a 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt @@ -944,7 +944,7 @@ object Generators : TemplateGroupBase() { } body(Sequences) { """ - return buildSequence result@ { + return sequence result@ { val iterator = iterator() if (!iterator.hasNext()) return@result var current = iterator.next()