[Misc] Introduce lazyClosure

This commit is contained in:
Dmitry Savvinov
2019-06-05 20:17:03 +03:00
parent 54cdd3bfef
commit 61ec5ed5dd
@@ -144,6 +144,27 @@ fun <T> Collection<T>.closure(f: (T) -> Collection<T>): Collection<T> {
return result
}
fun <T> Collection<T>.lazyClosure(f: (T) -> Collection<T>): Sequence<T> = sequence {
if (size == 0) return@sequence
var sizeBeforeIteration = 0
yieldAll(this@lazyClosure)
var yieldedCount = size
var elementsToCheck = this@lazyClosure
while (yieldedCount > sizeBeforeIteration) {
val toAdd = hashSetOf<T>()
elementsToCheck.forEach {
val neighbours = f(it)
yieldAll(neighbours)
yieldedCount += neighbours.size
toAdd.addAll(neighbours)
}
elementsToCheck = toAdd
sizeBeforeIteration = yieldedCount
}
}
fun boundClosure(types: Collection<KotlinType>): Collection<KotlinType> =
types.closure { type -> TypeUtils.getTypeParameterDescriptorOrNull(type)?.upperBounds ?: emptySet() }