From 82b08a813b8ade38d9384a12aba7db4b77331d60 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Fri, 10 Nov 2023 14:13:16 +0100 Subject: [PATCH] [Native] Fix scripts for computing dependencies in platform DEF files Now, the scripts are able to compute and record full dependencies (i.e. direct + transitive) to DEF files. ^KT-61098 --- .../native/interop/gen/defFileDependencies.kt | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/defFileDependencies.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/defFileDependencies.kt index 4ee2ac9996e..81c2a20b416 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/defFileDependencies.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/defFileDependencies.kt @@ -9,8 +9,8 @@ import org.jetbrains.kotlin.native.interop.gen.jvm.prepareTool import org.jetbrains.kotlin.native.interop.indexer.NativeLibraryHeaders import org.jetbrains.kotlin.native.interop.indexer.getHeaderPaths import org.jetbrains.kotlin.native.interop.tool.CInteropArguments +import org.jetbrains.kotlin.utils.mapToSetOrEmpty import java.io.File -import java.util.stream.Collectors import kotlin.streams.toList fun defFileDependencies(args: Array, runFromDaemon: Boolean) { @@ -59,11 +59,14 @@ private fun makeDependencyAssignerForTarget(target: String, defFiles: List } private fun defFileDependencies(dependencyAssigner: DependencyAssigner) { + val dependenciesExpander = DependenciesExpander() + while (!dependencyAssigner.isDone()) { - val (file, depends) = dependencyAssigner.getReady().entries.sortedBy { it.key }.first() - dependencyAssigner.markDone(file) - patchDepends(file, depends.sorted()) - println("${file.name} done.") + val (defFile, directDependencies) = dependencyAssigner.getReady().entries.minByOrNull { it.key }!! + val expandedDependencies = dependenciesExpander.expand(defFile, directDependencies) + dependencyAssigner.markDone(defFile) + patchDepends(defFile, expandedDependencies.sorted()) + println("${defFile.name} done.") } } @@ -134,10 +137,10 @@ private class SingleTargetDependencyAssigner( override fun getReady(): Map> { val result = mutableMapOf>() - defFiles@for ((defFile, headers) in pendingDefFilesToHeaders) { + defFiles@ for ((defFile, headers) in pendingDefFilesToHeaders) { val depends = mutableSetOf() - headers@for (header in (headers.ownHeaders + headers.importedHeaders)) { + headers@ for (header in (headers.ownHeaders + headers.importedHeaders)) { val dependency = processedHeadersToDefFiles[header] ?: if (header in headers.ownHeaders) continue@headers else continue@defFiles @@ -168,4 +171,27 @@ private class SingleTargetDependencyAssigner( processedHeadersToDefFiles.putIfAbsent(it, file) } } -} \ No newline at end of file +} + +private class DependenciesExpander { + private class Dependency(val defFile: File, val directDependencies: Set) { + val name: String = defFile.nameWithoutExtension + + val allDependencies: Set by lazy { + buildSet { + directDependencies.forEach { directDependency -> + this += directDependency.name + addAll(directDependency.allDependencies) + } + } + } + } + + private val cache = mutableMapOf() + + fun expand(defFile: File, directDepends: Set): Set { + val dependency = Dependency(defFile, directDepends.mapToSetOrEmpty { cache.getValue(it) }) + check(cache.put(dependency.name, dependency) == null) + return dependency.allDependencies + } +}