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
This commit is contained in:
Ilya Gorbunov
2018-09-07 07:15:21 +03:00
parent 9c812c6e2b
commit aac96c476a
9 changed files with 56 additions and 46 deletions
@@ -1658,7 +1658,7 @@ public fun <T> Sequence<T>.zipWithNext(): Sequence<Pair<T, T>> {
*/
@SinceKotlin("1.2")
public fun <T, R> Sequence<T>.zipWithNext(transform: (a: T, b: T) -> R): Sequence<R> {
return buildSequence result@ {
return sequence result@ {
val iterator = iterator()
if (!iterator.hasNext()) return@result
var current = iterator.next()
@@ -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 <T> buildSequence(builderAction: suspend SequenceBuilder<T>.() -> Unit): Sequence<T> = Sequence { buildIterator(builderAction) }
public fun <T> sequence(block: suspend SequenceScope<T>.() -> Unit): Sequence<T> = Sequence { iterator(block) }
@SinceKotlin("1.3")
@Deprecated("Use 'sequence { }' function instead.", ReplaceWith("sequence(builderAction)"), level = DeprecationLevel.ERROR)
@kotlin.internal.InlineOnly
public inline fun <T> buildSequence(noinline builderAction: suspend SequenceScope<T>.() -> Unit): Sequence<T> = Sequence { iterator(builderAction) }
/**
* Builds an [Iterator] lazily yielding values one by one.
@@ -30,24 +35,29 @@ public fun <T> buildSequence(builderAction: suspend SequenceBuilder<T>.() -> Uni
* @sample samples.collections.Iterables.Building.iterable
*/
@SinceKotlin("1.3")
public fun <T> buildIterator(builderAction: suspend SequenceBuilder<T>.() -> Unit): Iterator<T> {
public fun <T> iterator(block: suspend SequenceScope<T>.() -> Unit): Iterator<T> {
val iterator = SequenceBuilderIterator<T>()
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 <T> buildIterator(noinline builderAction: suspend SequenceScope<T>.() -> Unit): Iterator<T> = 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<in T> internal constructor() {
public abstract class SequenceScope<in T> internal constructor() {
/**
* Yields a value to the [Iterator] being built.
*
@@ -85,6 +95,9 @@ public abstract class SequenceBuilder<in T> internal constructor() {
public suspend fun yieldAll(sequence: Sequence<T>) = yieldAll(sequence.iterator())
}
@Deprecated("Use SequenceScope class instead.", ReplaceWith("SequenceScope<T>"), level = DeprecationLevel.ERROR)
public typealias SequenceBuilder<T> = SequenceScope<T>
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<T> : SequenceBuilder<T>(), Iterator<T>, Continuation<Unit> {
private class SequenceBuilderIterator<T> : SequenceScope<T>(), Iterator<T>, Continuation<Unit> {
private var state = State_NotReady
private var nextValue: T? = null
private var nextIterator: Iterator<T>? = null
@@ -26,7 +26,7 @@ class Iterables {
@Sample
fun iterable() {
val iterable = Iterable {
buildIterator {
iterator {
yield(42)
yieldAll(1..5 step 2)
}
@@ -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<Any>() {
override val size: Int = collection.size + 2
override fun iterator(): Iterator<Any> = buildIterator {
override fun iterator(): Iterator<Any> = iterator {
yield("first")
yieldAll(collection)
yield("last")
@@ -63,7 +63,7 @@ public inline fun <T> Sequence<T>?.orEmpty(): Sequence<T> = this ?: emptySequenc
* @sample samples.collections.Sequences.Usage.sequenceIfEmpty
*/
@SinceKotlin("1.3")
public fun <T> Sequence<T>.ifEmpty(defaultValue: () -> Sequence<T>): Sequence<T> = buildSequence {
public fun <T> Sequence<T>.ifEmpty(defaultValue: () -> Sequence<T>): Sequence<T> = sequence {
val iterator = this@ifEmpty.iterator()
if (iterator.hasNext()) {
yieldAll(iterator)
@@ -588,7 +588,7 @@ public fun <T> Sequence<T>.constrainOnce(): Sequence<T> {
* 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 <T : Any> generateSequence(nextFunction: () -> T?): Sequence<T> {
*
* 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 <T : Any> 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
*/
@@ -23,7 +23,7 @@ internal fun <T> Sequence<T>.windowedSequence(size: Int, step: Int, partialWindo
internal fun <T> windowedIterator(iterator: Iterator<T>, size: Int, step: Int, partialWindows: Boolean, reuseBuffer: Boolean): Iterator<List<T>> {
if (!iterator.hasNext()) return EmptyIterator
return buildIterator<List<T>> {
return iterator<List<T>> {
val gap = step - size
if (gap >= 0) {
var buffer = ArrayList<T>(size)
@@ -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<Int> {}
val result = sequence<Int> {}
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<Int> {
val result = sequence<Int> {
yieldAll(listOf())
}
assertEquals(listOf(), result.toList())
@@ -227,7 +227,7 @@ class SequenceBuilderTest {
@Test
fun testYieldAllCollectionManyEmpty() {
val result = buildSequence<Int> {
val result = sequence<Int> {
yieldAll(listOf())
yieldAll(listOf())
yieldAll(listOf())
@@ -238,7 +238,7 @@ class SequenceBuilderTest {
@Test
fun testYieldAllSideEffects() {
val effects = arrayListOf<Any>()
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 })
}
@@ -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;
@@ -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()