diff --git a/libraries/stdlib/src/kotlin/collections/SequenceBuilder.kt b/libraries/stdlib/src/kotlin/collections/SequenceBuilder.kt index 9a20112da9e..63baa7db06a 100644 --- a/libraries/stdlib/src/kotlin/collections/SequenceBuilder.kt +++ b/libraries/stdlib/src/kotlin/collections/SequenceBuilder.kt @@ -76,7 +76,7 @@ private class YieldingIterator : SequenceBuilder(), Iterator, Continuat if (nextIterator!!.hasNext()) return true else nextIterator = null State_Done -> return false State_Ready -> return true - else -> throw unexpectedState() + else -> throw exceptionalState() } state = State_Failed @@ -86,25 +86,29 @@ private class YieldingIterator : SequenceBuilder(), Iterator, Continuat } } - override tailrec fun next(): T { + override fun next(): T { when (state) { - State_NotReady -> if (!hasNext()) throw NoSuchElementException() else return next() - State_ManyReady -> { - val iterator = nextIterator!! - return iterator.next() - } + State_NotReady -> return nextNotReady() + State_ManyReady -> return nextIterator!!.next() State_Ready -> { state = State_NotReady val result = nextValue as T nextValue = null return result } - State_Done -> throw NoSuchElementException() - else -> throw unexpectedState() + else -> throw exceptionalState() } } - private fun unexpectedState(): Throwable = IllegalStateException("Unexpected state of the iterator: $state") + private fun nextNotReady(): T { + if (!hasNext()) throw NoSuchElementException() else return next() + } + + private fun exceptionalState(): Throwable = when (state) { + State_Done -> NoSuchElementException() + State_Failed -> IllegalStateException("Iterator has failed.") + else -> IllegalStateException("Unexpected state of the iterator: $state") + } suspend override fun yield(value: T) { diff --git a/libraries/stdlib/test/collections/SequenceBuilderTest.kt b/libraries/stdlib/test/collections/SequenceBuilderTest.kt index e0f812b46ef..8bf31b422be 100644 --- a/libraries/stdlib/test/collections/SequenceBuilderTest.kt +++ b/libraries/stdlib/test/collections/SequenceBuilderTest.kt @@ -35,7 +35,7 @@ class SequenceBuilderTest { assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext()) - assertTrue(assertFails { iterator.next() } is NoSuchElementException) + assertFailsWith { iterator.next() } } @Test @@ -61,7 +61,7 @@ class SequenceBuilderTest { assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext()) - assertTrue(assertFails { iterator.next() } is NoSuchElementException) + assertFailsWith { iterator.next() } assertEquals(1, result.iterator().next()) } @@ -74,7 +74,7 @@ class SequenceBuilderTest { assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext()) - assertTrue(assertFails { iterator.next() } is NoSuchElementException) + assertFailsWith { iterator.next() } } @Test @@ -106,7 +106,7 @@ class SequenceBuilderTest { sharedVar = -1 assertFalse(iterator.hasNext()) - assertTrue(assertFails { iterator.next() } is NoSuchElementException) + assertFailsWith { iterator.next() } } @Test @@ -116,7 +116,7 @@ class SequenceBuilderTest { while (true) { when (sharedVar) { -1 -> return@buildSequence - -2 -> error("Invalid state: -2") + -2 -> throw UnsupportedOperationException("-2 is unsupported") else -> yield(sharedVar) } } @@ -128,7 +128,9 @@ class SequenceBuilderTest { assertEquals(1, iterator.next()) sharedVar = -2 - assertTrue(assertFails { iterator.hasNext() } is IllegalStateException) + assertFailsWith { iterator.hasNext() } + assertFailsWith { iterator.hasNext() } + assertFailsWith { iterator.next() } } @Test