package org.jetbrains.dokka.model interface WithChildren { val children: List } inline fun WithChildren<*>.firstChildOfTypeOrNull(): T? = children.filterIsInstance().firstOrNull() inline fun WithChildren<*>.firstChildOfTypeOrNull(predicate: (T) -> Boolean): T? = children.filterIsInstance().firstOrNull(predicate) inline fun WithChildren<*>.firstChildOfType(): T = children.filterIsInstance().first() inline fun WithChildren<*>.firstChildOfType(predicate: (T) -> Boolean): T = children.filterIsInstance().first(predicate) inline fun WithChildren>.firstMemberOfType(): T where T : WithChildren<*> { return withDescendants().filterIsInstance().first() } inline fun WithChildren>.firstMemberOfTypeOrNull(): T? where T : WithChildren<*> { return withDescendants().filterIsInstance().firstOrNull() } fun T.withDescendants(): Sequence where T : WithChildren { return sequence { yield(this@withDescendants) children.forEach { child -> yieldAll(child.withDescendants()) } } } @JvmName("withDescendantsProjection") fun WithChildren<*>.withDescendants(): Sequence { return sequence { yield(this@withDescendants) children.forEach { child -> if (child is WithChildren<*>) { yieldAll(child.withDescendants()) } } } } @JvmName("withDescendantsAny") fun WithChildren.withDescendants(): Sequence { return sequence { yield(this@withDescendants) children.forEach { child -> if (child is WithChildren<*>) { yieldAll(child.withDescendants().filterNotNull()) } } } } fun T.dfs(predicate: (T) -> Boolean): T? where T : WithChildren = if (predicate(this)) { this } else { children.asSequence().mapNotNull { it.dfs(predicate) }.firstOrNull() }