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") @SinceKotlin("1.2")
public fun <T, R> Sequence<T>.zipWithNext(transform: (a: T, b: T) -> R): Sequence<R> { public fun <T, R> Sequence<T>.zipWithNext(transform: (a: T, b: T) -> R): Sequence<R> {
return buildSequence result@ { return sequence result@ {
val iterator = iterator() val iterator = iterator()
if (!iterator.hasNext()) return@result if (!iterator.hasNext()) return@result
var current = iterator.next() var current = iterator.next()
@@ -4,7 +4,7 @@
*/ */
@file:kotlin.jvm.JvmMultifileClass @file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("SequenceBuilderKt") @file:kotlin.jvm.JvmName("SequencesKt")
package kotlin.sequences package kotlin.sequences
@@ -21,7 +21,12 @@ import kotlin.coroutines.intrinsics.*
* @sample samples.collections.Sequences.Building.buildFibonacciSequence * @sample samples.collections.Sequences.Building.buildFibonacciSequence
*/ */
@SinceKotlin("1.3") @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. * 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 * @sample samples.collections.Iterables.Building.iterable
*/ */
@SinceKotlin("1.3") @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>() val iterator = SequenceBuilderIterator<T>()
iterator.nextStep = builderAction.createCoroutineUnintercepted(receiver = iterator, completion = iterator) iterator.nextStep = block.createCoroutineUnintercepted(receiver = iterator, completion = iterator)
return 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 sequence
* @see buildIterator * @see iterator
* *
* @sample samples.collections.Sequences.Building.buildSequenceYieldAll * @sample samples.collections.Sequences.Building.buildSequenceYieldAll
* @sample samples.collections.Sequences.Building.buildFibonacciSequence * @sample samples.collections.Sequences.Building.buildFibonacciSequence
*/ */
@RestrictsSuspension @RestrictsSuspension
@SinceKotlin("1.3") @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. * 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()) 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 typealias State = Int
private const val State_NotReady: State = 0 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_Done: State = 4
private const val State_Failed: State = 5 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 state = State_NotReady
private var nextValue: T? = null private var nextValue: T? = null
private var nextIterator: Iterator<T>? = null private var nextIterator: Iterator<T>? = null
@@ -26,7 +26,7 @@ class Iterables {
@Sample @Sample
fun iterable() { fun iterable() {
val iterable = Iterable { val iterable = Iterable {
buildIterator { iterator {
yield(42) yield(42)
yieldAll(1..5 step 2) yieldAll(1..5 step 2)
} }
@@ -111,7 +111,7 @@ class Sequences {
@Sample @Sample
fun buildFibonacciSequence() { fun buildFibonacciSequence() {
fun fibonacci() = buildSequence { fun fibonacci() = sequence {
var terms = Pair(0, 1) var terms = Pair(0, 1)
// this sequence is infinite // this sequence is infinite
@@ -126,7 +126,7 @@ class Sequences {
@Sample @Sample
fun buildSequenceYieldAll() { fun buildSequenceYieldAll() {
val sequence = buildSequence { val sequence = sequence {
val start = 0 val start = 0
// yielding a single value // yielding a single value
yield(start) yield(start)
@@ -145,7 +145,7 @@ class Sequences {
val wrappedCollection = object : AbstractCollection<Any>() { val wrappedCollection = object : AbstractCollection<Any>() {
override val size: Int = collection.size + 2 override val size: Int = collection.size + 2
override fun iterator(): Iterator<Any> = buildIterator { override fun iterator(): Iterator<Any> = iterator {
yield("first") yield("first")
yieldAll(collection) yieldAll(collection)
yield("last") yield("last")
@@ -63,7 +63,7 @@ public inline fun <T> Sequence<T>?.orEmpty(): Sequence<T> = this ?: emptySequenc
* @sample samples.collections.Sequences.Usage.sequenceIfEmpty * @sample samples.collections.Sequences.Usage.sequenceIfEmpty
*/ */
@SinceKotlin("1.3") @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() val iterator = this@ifEmpty.iterator()
if (iterator.hasNext()) { if (iterator.hasNext()) {
yieldAll(iterator) yieldAll(iterator)
@@ -588,7 +588,7 @@ public fun <T> Sequence<T>.constrainOnce(): Sequence<T> {
* The returned sequence is constrained to be iterated only once. * The returned sequence is constrained to be iterated only once.
* *
* @see constrainOnce * @see constrainOnce
* @see kotlin.coroutines.experimental.buildSequence * @see kotlin.sequences.sequence
* *
* @sample samples.collections.Sequences.Building.generateSequence * @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]. * 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 * @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. * The sequence can be iterated multiple times.
* *
* @see kotlin.coroutines.experimental.buildSequence * @see kotlin.sequences.sequence
* *
* @sample samples.collections.Sequences.Building.generateSequenceWithLazySeed * @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>> { internal fun <T> windowedIterator(iterator: Iterator<T>, size: Int, step: Int, partialWindows: Boolean, reuseBuffer: Boolean): Iterator<List<T>> {
if (!iterator.hasNext()) return EmptyIterator if (!iterator.hasNext()) return EmptyIterator
return buildIterator<List<T>> { return iterator<List<T>> {
val gap = step - size val gap = step - size
if (gap >= 0) { if (gap >= 0) {
var buffer = ArrayList<T>(size) var buffer = ArrayList<T>(size)
@@ -10,7 +10,7 @@ import kotlin.test.*
class SequenceBuilderTest { class SequenceBuilderTest {
@Test @Test
fun testSimple() { fun testSimple() {
val result = buildSequence { val result = sequence {
for (i in 1..3) { for (i in 1..3) {
yield(2 * i) yield(2 * i)
} }
@@ -23,7 +23,7 @@ class SequenceBuilderTest {
@Test @Test
fun testCallHasNextSeveralTimes() { fun testCallHasNextSeveralTimes() {
val result = buildSequence { val result = sequence {
yield(1) yield(1)
} }
@@ -44,7 +44,7 @@ class SequenceBuilderTest {
@Test @Test
fun testManualIteration() { fun testManualIteration() {
val result = buildSequence { val result = sequence {
yield(1) yield(1)
yield(2) yield(2)
yield(3) yield(3)
@@ -72,7 +72,7 @@ class SequenceBuilderTest {
@Test @Test
fun testEmptySequence() { fun testEmptySequence() {
val result = buildSequence<Int> {} val result = sequence<Int> {}
val iterator = result.iterator() val iterator = result.iterator()
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
@@ -84,10 +84,10 @@ class SequenceBuilderTest {
@Test @Test
fun testLaziness() { fun testLaziness() {
var sharedVar = -2 var sharedVar = -2
val result = buildSequence { val result = sequence {
while (true) { while (true) {
when (sharedVar) { when (sharedVar) {
-1 -> return@buildSequence -1 -> return@sequence
-2 -> error("Invalid state: -2") -2 -> error("Invalid state: -2")
else -> yield(sharedVar) else -> yield(sharedVar)
} }
@@ -116,10 +116,10 @@ class SequenceBuilderTest {
@Test @Test
fun testExceptionInCoroutine() { fun testExceptionInCoroutine() {
var sharedVar = -2 var sharedVar = -2
val result = buildSequence { val result = sequence {
while (true) { while (true) {
when (sharedVar) { when (sharedVar) {
-1 -> return@buildSequence -1 -> return@sequence
-2 -> throw UnsupportedOperationException("-2 is unsupported") -2 -> throw UnsupportedOperationException("-2 is unsupported")
else -> yield(sharedVar) else -> yield(sharedVar)
} }
@@ -140,7 +140,7 @@ class SequenceBuilderTest {
@Test @Test
fun testParallelIteration() { fun testParallelIteration() {
var inc = 0 var inc = 0
val result = buildSequence { val result = sequence {
for (i in 1..3) { for (i in 1..3) {
inc++ inc++
yield(inc * i) yield(inc * i)
@@ -152,7 +152,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllIterator() { fun testYieldAllIterator() {
val result = buildSequence { val result = sequence {
yieldAll(listOf(1, 2, 3).iterator()) yieldAll(listOf(1, 2, 3).iterator())
} }
assertEquals(listOf(1, 2, 3), result.toList()) assertEquals(listOf(1, 2, 3), result.toList())
@@ -160,7 +160,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllSequence() { fun testYieldAllSequence() {
val result = buildSequence { val result = sequence {
yieldAll(sequenceOf(1, 2, 3)) yieldAll(sequenceOf(1, 2, 3))
} }
assertEquals(listOf(1, 2, 3), result.toList()) assertEquals(listOf(1, 2, 3), result.toList())
@@ -168,7 +168,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllCollection() { fun testYieldAllCollection() {
val result = buildSequence { val result = sequence {
yieldAll(listOf(1, 2, 3)) yieldAll(listOf(1, 2, 3))
} }
assertEquals(listOf(1, 2, 3), result.toList()) assertEquals(listOf(1, 2, 3), result.toList())
@@ -176,7 +176,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllCollectionMixedFirst() { fun testYieldAllCollectionMixedFirst() {
val result = buildSequence { val result = sequence {
yield(0) yield(0)
yieldAll(listOf(1, 2, 3)) yieldAll(listOf(1, 2, 3))
} }
@@ -185,7 +185,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllCollectionMixedLast() { fun testYieldAllCollectionMixedLast() {
val result = buildSequence { val result = sequence {
yieldAll(listOf(1, 2, 3)) yieldAll(listOf(1, 2, 3))
yield(4) yield(4)
} }
@@ -194,7 +194,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllCollectionMixedBoth() { fun testYieldAllCollectionMixedBoth() {
val result = buildSequence { val result = sequence {
yield(0) yield(0)
yieldAll(listOf(1, 2, 3)) yieldAll(listOf(1, 2, 3))
yield(4) yield(4)
@@ -204,7 +204,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllCollectionMixedLong() { fun testYieldAllCollectionMixedLong() {
val result = buildSequence { val result = sequence {
yield(0) yield(0)
yieldAll(listOf(1, 2, 3)) yieldAll(listOf(1, 2, 3))
yield(4) yield(4)
@@ -219,7 +219,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllCollectionOneEmpty() { fun testYieldAllCollectionOneEmpty() {
val result = buildSequence<Int> { val result = sequence<Int> {
yieldAll(listOf()) yieldAll(listOf())
} }
assertEquals(listOf(), result.toList()) assertEquals(listOf(), result.toList())
@@ -227,7 +227,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllCollectionManyEmpty() { fun testYieldAllCollectionManyEmpty() {
val result = buildSequence<Int> { val result = sequence<Int> {
yieldAll(listOf()) yieldAll(listOf())
yieldAll(listOf()) yieldAll(listOf())
yieldAll(listOf()) yieldAll(listOf())
@@ -238,7 +238,7 @@ class SequenceBuilderTest {
@Test @Test
fun testYieldAllSideEffects() { fun testYieldAllSideEffects() {
val effects = arrayListOf<Any>() val effects = arrayListOf<Any>()
val result = buildSequence { val result = sequence {
effects.add("a") effects.add("a")
yieldAll(listOf(1, 2)) yieldAll(listOf(1, 2))
effects.add("b") effects.add("b")
@@ -276,7 +276,7 @@ class SequenceBuilderTest {
@Test @Test
fun testInfiniteYieldAll() { fun testInfiniteYieldAll() {
val values = buildIterator { val values = iterator {
while (true) { while (true) {
yieldAll((1..5).map { it }) 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 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 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 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 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 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 final class kotlin/sequences/SequencesKt {
public static final fun all (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Z public static final fun all (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Z
public static final fun any (Lkotlin/sequences/Sequence;)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 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 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 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 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 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; 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 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 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 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 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;)Ljava/lang/Object;
public static final fun single (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)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) { body(Sequences) {
""" """
return buildSequence result@ { return sequence result@ {
val iterator = iterator() val iterator = iterator()
if (!iterator.hasNext()) return@result if (!iterator.hasNext()) return@result
var current = iterator.next() var current = iterator.next()