From 4d1057f7c6078752147a4b65f9b02c8486a0be21 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 27 May 2020 18:37:23 +0300 Subject: [PATCH] Remove dependency to Kotlin compiler in build tools just because of DFS (cherry picked from commit 6d9a9e743de6323c0073e09e53c14674ac726f7e) --- build-tools/build.gradle.kts | 5 - .../kotlin/org/jetbrains/kotlin/utils/DFS.kt | 121 ++++++++++++++++++ 2 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 build-tools/src/main/kotlin/org/jetbrains/kotlin/utils/DFS.kt diff --git a/build-tools/build.gradle.kts b/build-tools/build.gradle.kts index 33aa932732a..0bb0cd44196 100644 --- a/build-tools/build.gradle.kts +++ b/build-tools/build.gradle.kts @@ -43,13 +43,9 @@ repositories { maven("https://dl.bintray.com/kotlin/kotlin-dev") } -val kotlinCompilerJar by configurations.creating - dependencies { compileOnly(gradleApi()) - kotlinCompilerJar("org.jetbrains.kotlin:kotlin-compiler:${kotlinVersion}@jar") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion") @@ -104,7 +100,6 @@ compileKotlin.apply { // Add Kotlin classes to a classpath for the Groovy compiler compileGroovy.apply { classpath += project.files(compileKotlin.destinationDir) - classpath += kotlinCompilerJar dependsOn(compileKotlin) } diff --git a/build-tools/src/main/kotlin/org/jetbrains/kotlin/utils/DFS.kt b/build-tools/src/main/kotlin/org/jetbrains/kotlin/utils/DFS.kt new file mode 100644 index 00000000000..87438995b56 --- /dev/null +++ b/build-tools/src/main/kotlin/org/jetbrains/kotlin/utils/DFS.kt @@ -0,0 +1,121 @@ +package org.jetbrains.kotlin.utils + +import java.util.* + +// Copied from Kotlin org.jetbrains.kotlin.utils.DFS class +@Suppress("MemberVisibilityCanBePrivate", "MemberVisibilityCanBePrivate", "unused") +object DFS { + fun dfs(nodes: Collection, neighbors: Neighbors, visited: Visited, handler: NodeHandler): R { + for (node in nodes) { + doDfs(node, neighbors, visited, handler) + } + return handler.result() + } + + fun dfs( + nodes: Collection, + neighbors: Neighbors, + handler: NodeHandler + ): R { + return dfs(nodes, neighbors, VisitedWithSet(), handler) + } + + fun ifAny( + nodes: Collection, + neighbors: Neighbors, + predicate: Function1 + ): Boolean { + val result = BooleanArray(1) + return dfs(nodes, neighbors, object : AbstractNodeHandler() { + override fun beforeChildren(current: N): Boolean { + if (predicate.invoke(current)) { + result[0] = true + } + return !result[0] + } + + override fun result(): Boolean { + return result[0] + } + })!! + } + + fun dfsFromNode(node: N, neighbors: Neighbors, visited: Visited, handler: NodeHandler): R { + doDfs(node, neighbors, visited, handler) + return handler.result() + } + + fun dfsFromNode( + node: N, + neighbors: Neighbors, + visited: Visited + ) { + dfsFromNode(node, neighbors, visited, object : AbstractNodeHandler() { + override fun result(): Void? { + return null + } + }) + } + + fun topologicalOrder(nodes: Iterable, neighbors: Neighbors, visited: Visited): List { + val handler = TopologicalOrder() + for (node in nodes) { + doDfs(node, neighbors, visited, handler) + } + return handler.result() + } + + fun topologicalOrder(nodes: Iterable, neighbors: Neighbors): List { + return topologicalOrder(nodes, neighbors, VisitedWithSet()) + } + + fun doDfs(current: N, neighbors: Neighbors, visited: Visited, handler: NodeHandler) { + if (!visited.checkAndMarkVisited(current)) return + if (!handler.beforeChildren(current)) return + for (neighbor in neighbors.getNeighbors(current)) { + doDfs(neighbor, neighbors, visited, handler) + } + handler.afterChildren(current) + } + + interface NodeHandler { + fun beforeChildren(current: N): Boolean + fun afterChildren(current: N) + fun result(): R + } + + interface Neighbors { + fun getNeighbors(current: N): Iterable + } + + interface Visited { + fun checkAndMarkVisited(current: N): Boolean + } + + abstract class AbstractNodeHandler : NodeHandler { + override fun beforeChildren(current: N): Boolean { + return true + } + + override fun afterChildren(current: N) {} + } + + class VisitedWithSet @JvmOverloads constructor(private val visited: MutableSet = HashSet()) : Visited { + override fun checkAndMarkVisited(current: N): Boolean { + return visited.add(current) + } + } + + abstract class CollectingNodeHandler> protected constructor(protected val result: C) : AbstractNodeHandler() { + override fun result(): C { + return result + } + } + + abstract class NodeHandlerWithListResult protected constructor() : CollectingNodeHandler>(LinkedList()) + class TopologicalOrder : NodeHandlerWithListResult() { + override fun afterChildren(current: N) { + result.addFirst(current) + } + } +} \ No newline at end of file