diff --git a/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/closure.kt b/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/closure.kt index 22778211b1d..a5ee7589b8c 100644 --- a/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/closure.kt +++ b/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/closure.kt @@ -115,7 +115,7 @@ inline fun T.linearClosure(next: (T) -> T?): Set { while (enqueued != null) { if (enqueued != this && results.add(enqueued)) { enqueued = next(enqueued) - } + } else break } return results @@ -134,7 +134,7 @@ inline fun T.withLinearClosure(next: (T) -> T?): Set { while (enqueued != null) { if (results.add(enqueued)) { enqueued = next(enqueued) - } + } else break } return results diff --git a/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/ClosureTest.kt b/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/ClosureTest.kt index 6229f9be869..9d23dd2201c 100644 --- a/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/ClosureTest.kt +++ b/libraries/tools/kotlin-tooling-core/src/test/kotlin/org/jetbrains/kotlin/tooling/core/ClosureTest.kt @@ -288,6 +288,21 @@ class ClosureTest { ) } + @Test + fun `linearClosure - loop`() { + val a = Node("a") + val b = Node("b") + val c = Node("c") + + c.parent = b + b.parent = a + a.parent = c + + assertEquals( + listOf("b", "a"), c.linearClosure { it.parent }.map { it.value }, + ) + } + @Test fun `linearClosure on empty`() { assertSame( @@ -310,6 +325,21 @@ class ClosureTest { ) } + @Test + fun `withLinearClosure - loop`() { + val a = Node("a") + val b = Node("b") + val c = Node("c") + + c.parent = b + b.parent = a + a.parent = c + + assertEquals( + listOf("c", "b", "a"), c.withLinearClosure { it.parent }.map { it.value }, + ) + } + @Test fun `withLinearClosure on empty`() { assertEquals(