aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/model/WithChildren.kt
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/kotlin/model/WithChildren.kt')
-rw-r--r--core/src/main/kotlin/model/WithChildren.kt64
1 files changed, 64 insertions, 0 deletions
diff --git a/core/src/main/kotlin/model/WithChildren.kt b/core/src/main/kotlin/model/WithChildren.kt
new file mode 100644
index 00000000..589bcd2a
--- /dev/null
+++ b/core/src/main/kotlin/model/WithChildren.kt
@@ -0,0 +1,64 @@
+package org.jetbrains.dokka.model
+
+interface WithChildren<out T> {
+ val children: List<T>
+}
+
+inline fun <reified T> WithChildren<*>.firstChildOfTypeOrNull(): T? =
+ children.filterIsInstance<T>().firstOrNull()
+
+inline fun <reified T> WithChildren<*>.firstChildOfTypeOrNull(predicate: (T) -> Boolean): T? =
+ children.filterIsInstance<T>().firstOrNull(predicate)
+
+inline fun <reified T> WithChildren<*>.firstChildOfType(): T =
+ children.filterIsInstance<T>().first()
+
+inline fun <reified T> WithChildren<*>.firstChildOfType(predicate: (T) -> Boolean): T =
+ children.filterIsInstance<T>().first(predicate)
+
+inline fun <reified T> WithChildren<WithChildren<*>>.firstMemberOfType(): T where T : WithChildren<*> {
+ return withDescendants().filterIsInstance<T>().first()
+}
+
+inline fun <reified T> WithChildren<WithChildren<*>>.firstMemberOfTypeOrNull(): T? where T : WithChildren<*> {
+ return withDescendants().filterIsInstance<T>().firstOrNull()
+}
+
+fun <T> T.withDescendants(): Sequence<T> where T : WithChildren<T> {
+ return sequence {
+ yield(this@withDescendants)
+ children.forEach { child ->
+ yieldAll(child.withDescendants())
+ }
+ }
+}
+
+@JvmName("withDescendantsProjection")
+fun WithChildren<*>.withDescendants(): Sequence<Any?> {
+ return sequence {
+ yield(this@withDescendants)
+ children.forEach { child ->
+ if (child is WithChildren<*>) {
+ yieldAll(child.withDescendants())
+ }
+ }
+ }
+}
+
+@JvmName("withDescendantsAny")
+fun WithChildren<Any>.withDescendants(): Sequence<Any> {
+ return sequence {
+ yield(this@withDescendants)
+ children.forEach { child ->
+ if (child is WithChildren<*>) {
+ yieldAll(child.withDescendants().filterNotNull())
+ }
+ }
+ }
+}
+
+fun <T> T.dfs(predicate: (T) -> Boolean): T? where T : WithChildren<T> = if (predicate(this)) {
+ this
+} else {
+ children.asSequence().mapNotNull { it.dfs(predicate) }.firstOrNull()
+}