[Gradle] Implement CInteropCommonizerDependent factories as safe suspend functions
^KT-34662 Verification Pending
This commit is contained in:
committed by
Space Team
parent
9517667081
commit
b064493c7b
+5
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerDep
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.from
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
|
||||
import org.jetbrains.kotlin.gradle.utils.findAppliedAndroidPluginIdOrNull
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck
|
||||
|
||||
private class KotlinMultiplatformProjectConfigurationException(message: String) : Exception(message)
|
||||
@@ -77,7 +78,10 @@ internal fun Project.runDisabledCInteropCommonizationOnHmppProjectConfigurationH
|
||||
|
||||
val sharedCompilationsWithInterops = multiplatformExtension.targets.flatMap { it.compilations }
|
||||
.filterIsInstance<KotlinSharedNativeCompilation>()
|
||||
.mapNotNull { compilation -> compilation to (CInteropCommonizerDependent.from(compilation) ?: return@mapNotNull null) }
|
||||
.mapNotNull { compilation ->
|
||||
val cinteropDependent = future { CInteropCommonizerDependent.from(compilation) }.getOrThrow() ?: return@mapNotNull null
|
||||
compilation to cinteropDependent
|
||||
}
|
||||
.toMap()
|
||||
|
||||
val affectedCompilations = sharedCompilationsWithInterops.keys
|
||||
|
||||
+9
-5
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.extraProperties
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ArtifactMetadataProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||
import org.jetbrains.kotlin.gradle.utils.LazyResolvedConfiguration
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import org.jetbrains.kotlin.gradle.utils.getOrPut
|
||||
import java.util.*
|
||||
|
||||
@@ -143,7 +144,7 @@ internal class GranularMetadataTransformation(
|
||||
params.resolvedMetadataConfiguration
|
||||
.root
|
||||
.dependencies
|
||||
.filter { !it.isConstraint}
|
||||
.filter { !it.isConstraint }
|
||||
.filterIsInstance<ResolvedDependencyResult>()
|
||||
)
|
||||
}
|
||||
@@ -332,15 +333,18 @@ internal val ResolvedComponentResult.currentBuildProjectIdOrNull
|
||||
}
|
||||
}
|
||||
|
||||
private val Project.allProjectsData: Map<String, GranularMetadataTransformation.ProjectData> get() = rootProject
|
||||
.extraProperties
|
||||
.getOrPut("all${GranularMetadataTransformation.ProjectData::class.java.simpleName}") { collectAllProjectsData() }
|
||||
private val Project.allProjectsData: Map<String, GranularMetadataTransformation.ProjectData>
|
||||
get() = rootProject
|
||||
.extraProperties
|
||||
.getOrPut("all${GranularMetadataTransformation.ProjectData::class.java.simpleName}") {
|
||||
future { collectAllProjectsData() }.getOrThrow()
|
||||
}
|
||||
|
||||
private fun Project.collectAllProjectsData(): Map<String, GranularMetadataTransformation.ProjectData> {
|
||||
return rootProject.allprojects.associateBy { it.path }.mapValues { (path, subProject) ->
|
||||
GranularMetadataTransformation.ProjectData(
|
||||
path = path,
|
||||
sourceSetMetadataOutputsProvider = { subProject.collectSourceSetMetadataOutputs() },
|
||||
sourceSetMetadataOutputsProvider = future { subProject.collectSourceSetMetadataOutputs() }::getOrThrow,
|
||||
moduleIdProvider = { ModuleIds.idOfRootModule(subProject) }
|
||||
)
|
||||
}
|
||||
|
||||
+2
-2
@@ -48,7 +48,7 @@ private class ProjectMetadataProviderImpl(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Project.collectSourceSetMetadataOutputs(): Map<SourceSetName, SourceSetMetadataOutputs> {
|
||||
internal suspend fun Project.collectSourceSetMetadataOutputs(): Map<SourceSetName, SourceSetMetadataOutputs> {
|
||||
val multiplatformExtension = multiplatformExtensionOrNull ?: return emptyMap()
|
||||
|
||||
val sourceSetMetadata = multiplatformExtension.sourceSetsMetadataOutputs()
|
||||
@@ -82,7 +82,7 @@ private fun KotlinMultiplatformExtension.sourceSetsMetadataOutputs(): Map<Kotlin
|
||||
}.toMap()
|
||||
}
|
||||
|
||||
private fun KotlinMultiplatformExtension.cInteropMetadataOfSourceSets(
|
||||
private suspend fun KotlinMultiplatformExtension.cInteropMetadataOfSourceSets(
|
||||
sourceSets: Iterable<KotlinSourceSet>
|
||||
): Map<KotlinSourceSet, SourceSetMetadataOutputs.CInterop?> {
|
||||
val taskForCLI = project.commonizeCInteropTask ?: return emptyMap()
|
||||
|
||||
+5
-3
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.base64Hash
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.ensureMaxFileNameLength
|
||||
import org.jetbrains.kotlin.commonizer.identityString
|
||||
import org.jetbrains.kotlin.gradle.utils.changing
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import org.jetbrains.kotlin.gradle.utils.outputFilesProvider
|
||||
import java.io.File
|
||||
|
||||
@@ -20,7 +21,7 @@ internal abstract class AbstractCInteropCommonizerTask : DefaultTask() {
|
||||
@get:OutputDirectory
|
||||
abstract val outputDirectory: File
|
||||
|
||||
internal abstract fun findInteropsGroup(dependent: CInteropCommonizerDependent): CInteropCommonizerGroup?
|
||||
internal abstract suspend fun findInteropsGroup(dependent: CInteropCommonizerDependent): CInteropCommonizerGroup?
|
||||
}
|
||||
|
||||
internal fun AbstractCInteropCommonizerTask.outputDirectory(group: CInteropCommonizerGroup): File {
|
||||
@@ -35,14 +36,15 @@ internal fun AbstractCInteropCommonizerTask.outputDirectory(group: CInteropCommo
|
||||
|
||||
internal fun AbstractCInteropCommonizerTask.commonizedOutputLibraries(dependent: CInteropCommonizerDependent): FileCollection {
|
||||
return outputFilesProvider {
|
||||
val outputDirectory = commonizedOutputDirectory(dependent) ?: return@outputFilesProvider emptySet<File>()
|
||||
val outputDirectory = project.future { commonizedOutputDirectory(dependent) }.getOrThrow()
|
||||
?: return@outputFilesProvider emptySet<File>()
|
||||
project.providers.changing {
|
||||
outputDirectory.listFiles().orEmpty().toSet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun AbstractCInteropCommonizerTask.commonizedOutputDirectory(dependent: CInteropCommonizerDependent): File? {
|
||||
internal suspend fun AbstractCInteropCommonizerTask.commonizedOutputDirectory(dependent: CInteropCommonizerDependent): File? {
|
||||
val group = findInteropsGroup(dependent) ?: return null
|
||||
return CommonizerOutputFileLayout
|
||||
.resolveCommonizedDirectory(outputDirectory(group), dependent.target)
|
||||
|
||||
+5
-2
@@ -9,16 +9,19 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.bundling.Zip
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.launch
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerCompositeMetadataJarBundling.cinteropMetadataDirectoryPath
|
||||
|
||||
internal fun Project.includeCommonizedCInteropMetadata(
|
||||
metadataKlib: TaskProvider<out Zip>, compilation: KotlinSharedNativeCompilation
|
||||
) {
|
||||
metadataKlib.configure { jar -> includeCommonizedCInteropMetadata(jar, compilation) }
|
||||
metadataKlib.configure { jar ->
|
||||
launch { includeCommonizedCInteropMetadata(jar, compilation) }
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Project.includeCommonizedCInteropMetadata(metadataKlib: Zip, compilation: KotlinSharedNativeCompilation) {
|
||||
internal suspend fun Project.includeCommonizedCInteropMetadata(metadataKlib: Zip, compilation: KotlinSharedNativeCompilation) {
|
||||
val commonizerTask = commonizeCInteropTask?.get() ?: return
|
||||
val commonizerDependencyToken = CInteropCommonizerDependent.from(compilation) ?: return
|
||||
val outputDirectory = commonizerTask.commonizedOutputDirectory(commonizerDependencyToken) ?: return
|
||||
|
||||
+10
-6
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.future
|
||||
import java.io.File
|
||||
|
||||
internal fun Project.setupCInteropCommonizerDependencies() {
|
||||
@@ -33,7 +34,8 @@ private fun Project.setupCInteropCommonizerDependenciesForCompilation(compilatio
|
||||
val cinteropCommonizerTask = project.commonizeCInteropTask ?: return
|
||||
|
||||
compilation.compileDependencyFiles += filesProvider {
|
||||
val cinteropCommonizerDependent = CInteropCommonizerDependent.from(compilation) ?: return@filesProvider emptySet<File>()
|
||||
val cinteropCommonizerDependent = future { CInteropCommonizerDependent.from(compilation) }.getOrThrow()
|
||||
?: return@filesProvider emptySet<File>()
|
||||
cinteropCommonizerTask.get().commonizedOutputLibraries(cinteropCommonizerDependent)
|
||||
}
|
||||
}
|
||||
@@ -51,12 +53,14 @@ internal fun Project.cinteropCommonizerDependencies(sourceSet: DefaultKotlinSour
|
||||
val cinteropCommonizerTask = project.copyCommonizeCInteropForIdeTask ?: return project.files()
|
||||
|
||||
return filesProvider {
|
||||
val directlyDependent = CInteropCommonizerDependent.from(sourceSet)
|
||||
val associateDependent = CInteropCommonizerDependent.fromAssociateCompilations(sourceSet)
|
||||
future {
|
||||
val directlyDependent = CInteropCommonizerDependent.from(sourceSet)
|
||||
val associateDependent = CInteropCommonizerDependent.fromAssociateCompilations(sourceSet)
|
||||
|
||||
listOfNotNull(directlyDependent, associateDependent).map { cinteropCommonizerDependent ->
|
||||
cinteropCommonizerTask.get().commonizedOutputLibraries(cinteropCommonizerDependent)
|
||||
}
|
||||
listOfNotNull(directlyDependent, associateDependent).map { cinteropCommonizerDependent ->
|
||||
cinteropCommonizerTask.get().commonizedOutputLibraries(cinteropCommonizerDependent)
|
||||
}
|
||||
}.getOrThrow()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -72,24 +72,24 @@ internal fun CInteropCommonizerDependent.Factory.from(
|
||||
return CInteropCommonizerDependent(target, scopes, interops)
|
||||
}
|
||||
|
||||
internal fun CInteropCommonizerDependent.Factory.from(compilation: KotlinSharedNativeCompilation): CInteropCommonizerDependent? {
|
||||
internal suspend fun CInteropCommonizerDependent.Factory.from(compilation: KotlinSharedNativeCompilation): CInteropCommonizerDependent? {
|
||||
return from(
|
||||
compilation.commonizerTarget.getOrThrow() as? SharedCommonizerTarget ?: return null,
|
||||
compilation.commonizerTarget.await() as? SharedCommonizerTarget ?: return null,
|
||||
compilation.getImplicitlyDependingNativeCompilations()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun CInteropCommonizerDependent.Factory.from(sourceSet: KotlinSourceSet): CInteropCommonizerDependent? {
|
||||
internal suspend fun CInteropCommonizerDependent.Factory.from(sourceSet: KotlinSourceSet): CInteropCommonizerDependent? {
|
||||
return from(
|
||||
target = sourceSet.commonizerTarget.getOrThrow() as? SharedCommonizerTarget ?: return null,
|
||||
target = sourceSet.commonizerTarget.await() as? SharedCommonizerTarget ?: return null,
|
||||
compilations = sourceSet.internal.compilations
|
||||
.filterIsInstance<KotlinNativeCompilation>().toSet()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun CInteropCommonizerDependent.Factory.fromAssociateCompilations(sourceSet: KotlinSourceSet): CInteropCommonizerDependent? {
|
||||
internal suspend fun CInteropCommonizerDependent.Factory.fromAssociateCompilations(sourceSet: KotlinSourceSet): CInteropCommonizerDependent? {
|
||||
return from(
|
||||
target = sourceSet.commonizerTarget.getOrThrow() as? SharedCommonizerTarget ?: return null,
|
||||
target = sourceSet.commonizerTarget.await() as? SharedCommonizerTarget ?: return null,
|
||||
compilations = sourceSet.internal.compilations
|
||||
.filterIsInstance<KotlinNativeCompilation>()
|
||||
.flatMap { compilation -> compilation.associateWithClosure }
|
||||
|
||||
+21
-19
@@ -27,9 +27,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerTask.CInteropGist
|
||||
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
||||
import org.jetbrains.kotlin.gradle.utils.chainedFinalizeValueOnRead
|
||||
import org.jetbrains.kotlin.gradle.utils.listProperty
|
||||
import org.jetbrains.kotlin.gradle.utils.property
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
@@ -123,14 +121,14 @@ internal open class CInteropCommonizerTask
|
||||
* For Gradle Configuration Cache support the Group-to-Dependencies relation should be pre-cached.
|
||||
* It is used during execution phase.
|
||||
*/
|
||||
private val groupedCommonizerDependencies: Map<CInteropCommonizerGroup, List<CInteropCommonizerDependencies>> by lazy {
|
||||
val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@lazy emptyMap()
|
||||
private val groupedCommonizerDependencies: Future<Map<CInteropCommonizerGroup, List<CInteropCommonizerDependencies>>> = project.future {
|
||||
val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@future emptyMap()
|
||||
|
||||
val sourceSetsByTarget = multiplatformExtension.sourceSets.groupBy { sourceSet -> sourceSet.commonizerTarget.getOrThrow() }
|
||||
val sourceSetsByGroup = multiplatformExtension.sourceSets.groupBy { sourceSet ->
|
||||
CInteropCommonizerDependent.from(sourceSet)?.let { findInteropsGroup(it) }
|
||||
}
|
||||
getAllInteropsGroups().associateWith { group ->
|
||||
allInteropGroups.await().associateWith { group ->
|
||||
(group.targets + group.targets.allLeaves()).map { target ->
|
||||
val externalDependencyFiles: List<FileCollection> = when (target) {
|
||||
is LeafCommonizerTarget -> {
|
||||
@@ -165,7 +163,7 @@ internal open class CInteropCommonizerTask
|
||||
@get:Classpath
|
||||
protected val commonizerDependenciesClasspath: FileCollection
|
||||
get() = project.files(
|
||||
groupedCommonizerDependencies.values.flatten().map { it.dependencies }
|
||||
groupedCommonizerDependencies.getOrThrow().values.flatten().map { it.dependencies }
|
||||
)
|
||||
|
||||
@get:Nested
|
||||
@@ -174,7 +172,7 @@ internal open class CInteropCommonizerTask
|
||||
|
||||
@get:OutputDirectories
|
||||
val allOutputDirectories: Set<File>
|
||||
get() = getAllInteropsGroups().map { outputDirectory(it) }.toSet()
|
||||
get() = allInteropGroups.getOrThrow().map { outputDirectory(it) }.toSet()
|
||||
|
||||
fun from(vararg tasks: CInteropProcess) = from(
|
||||
tasks.toList()
|
||||
@@ -192,7 +190,7 @@ internal open class CInteropCommonizerTask
|
||||
|
||||
@TaskAction
|
||||
protected fun commonizeCInteropLibraries() {
|
||||
getAllInteropsGroups().forEach(::commonize)
|
||||
allInteropGroups.getOrThrow().forEach(::commonize)
|
||||
}
|
||||
|
||||
private fun commonize(group: CInteropCommonizerGroup) {
|
||||
@@ -217,7 +215,7 @@ internal open class CInteropCommonizerTask
|
||||
}
|
||||
|
||||
private fun getCInteropCommonizerGroupDependencies(group: CInteropCommonizerGroup): Set<CommonizerDependency> {
|
||||
val dependencies = groupedCommonizerDependencies[group]
|
||||
val dependencies = groupedCommonizerDependencies.getOrThrow()[group]
|
||||
?.flatMap { (target, dependencies) ->
|
||||
dependencies.files
|
||||
.filter { file -> file.exists() && (file.isDirectory || file.extension == "klib") }
|
||||
@@ -229,15 +227,15 @@ internal open class CInteropCommonizerTask
|
||||
return dependencies
|
||||
}
|
||||
|
||||
@Nested
|
||||
internal fun getAllInteropsGroups(): Set<CInteropCommonizerGroup> {
|
||||
val dependents = allDependents
|
||||
@get:Internal
|
||||
internal val allInteropGroups: Future<Set<CInteropCommonizerGroup>> = project.future {
|
||||
val dependents = allDependents.await()
|
||||
val allScopeSets = dependents.map { it.scopes }.toSet()
|
||||
val rootScopeSets = allScopeSets.filter { scopeSet ->
|
||||
allScopeSets.none { otherScopeSet -> otherScopeSet != scopeSet && otherScopeSet.containsAll(scopeSet) }
|
||||
}
|
||||
|
||||
return rootScopeSets.map { scopeSet ->
|
||||
rootScopeSets.map { scopeSet ->
|
||||
val dependentsForScopes = dependents.filter { dependent ->
|
||||
scopeSet.containsAll(dependent.scopes)
|
||||
}
|
||||
@@ -249,8 +247,12 @@ internal open class CInteropCommonizerTask
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
override fun findInteropsGroup(dependent: CInteropCommonizerDependent): CInteropCommonizerGroup? {
|
||||
val suitableGroups = getAllInteropsGroups().filter { group ->
|
||||
@get:Nested
|
||||
@Suppress("unused") // UP-TO-DATE check
|
||||
protected val allInteropGroupsOrThrow get() = allInteropGroups.getOrThrow()
|
||||
|
||||
override suspend fun findInteropsGroup(dependent: CInteropCommonizerDependent): CInteropCommonizerGroup? {
|
||||
val suitableGroups = allInteropGroups.await().filter { group ->
|
||||
group.interops.containsAll(dependent.interops) && group.targets.contains(dependent.target)
|
||||
}
|
||||
|
||||
@@ -261,8 +263,8 @@ internal open class CInteropCommonizerTask
|
||||
return suitableGroups.firstOrNull()
|
||||
}
|
||||
|
||||
private val allDependents: Set<CInteropCommonizerDependent> by lazy {
|
||||
val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@lazy emptySet()
|
||||
private val allDependents: Future<Set<CInteropCommonizerDependent>> = project.future {
|
||||
val multiplatformExtension = project.multiplatformExtensionOrNull ?: return@future emptySet()
|
||||
|
||||
val fromSharedNativeCompilations = multiplatformExtension
|
||||
.targets.flatMap { target -> target.compilations }
|
||||
@@ -278,7 +280,7 @@ internal open class CInteropCommonizerTask
|
||||
.mapNotNull { sourceSet -> CInteropCommonizerDependent.fromAssociateCompilations(sourceSet) }
|
||||
.toSet()
|
||||
|
||||
return@lazy (fromSharedNativeCompilations + fromSourceSets + fromSourceSetsAssociateCompilations)
|
||||
(fromSharedNativeCompilations + fromSourceSets + fromSourceSetsAssociateCompilations)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -26,14 +26,14 @@ internal open class CopyCommonizeCInteropForIdeTask : AbstractCInteropCommonizer
|
||||
override val outputDirectory: File = project.rootDir.resolve(".gradle/kotlin/commonizer")
|
||||
.resolve(project.path.removePrefix(":").replace(":", "/"))
|
||||
|
||||
override fun findInteropsGroup(dependent: CInteropCommonizerDependent): CInteropCommonizerGroup? {
|
||||
override suspend fun findInteropsGroup(dependent: CInteropCommonizerDependent): CInteropCommonizerGroup? {
|
||||
return commonizeCInteropTask.get().findInteropsGroup(dependent)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
protected fun copy() {
|
||||
outputDirectory.mkdirs()
|
||||
for (group in commonizeCInteropTask.get().getAllInteropsGroups()) {
|
||||
for (group in commonizeCInteropTask.get().allInteropGroups.getOrThrow()) {
|
||||
val source = commonizeCInteropTask.get().outputDirectory(group)
|
||||
if (!source.exists()) continue
|
||||
val target = outputDirectory(group)
|
||||
|
||||
+22
-34
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle
|
||||
import org.jetbrains.kotlin.tooling.core.ExtrasLazyProperty
|
||||
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
||||
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
|
||||
import java.io.Serializable
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
* See [KotlinPluginLifecycle]:
|
||||
@@ -62,45 +64,31 @@ internal inline fun <Receiver, reified T> lazyFuture(
|
||||
|
||||
internal fun <T> Project.future(block: suspend Project.() -> T): Future<T> = kotlinPluginLifecycle.future { block() }
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal fun <T> KotlinPluginLifecycle.future(block: suspend () -> T): Future<T> {
|
||||
val deferred = CompletableDeferred<T>()
|
||||
|
||||
launch {
|
||||
deferred.completeWith(runCatching { block() })
|
||||
}
|
||||
|
||||
return object : Future<T> {
|
||||
override suspend fun await(): T {
|
||||
return deferred.await()
|
||||
}
|
||||
|
||||
override fun getOrThrow(): T {
|
||||
return if (deferred.isCompleted) deferred.getCompleted() else throw IllegalLifecycleException(
|
||||
"Future was not completed yet. Stage: '${stage}'"
|
||||
)
|
||||
}
|
||||
return FutureImpl<T>(CompletableDeferred()).also { future ->
|
||||
launch { future.completeWith(runCatching { block() }) }
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal fun <T> CompletableFuture(): CompletableFuture<T> {
|
||||
val deferred = CompletableDeferred<T>()
|
||||
return FutureImpl()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private class FutureImpl<T>(private val deferred: CompletableDeferred<T> = CompletableDeferred()) : CompletableFuture<T>, Serializable {
|
||||
fun completeWith(result: Result<T>) = deferred.completeWith(result)
|
||||
|
||||
return object : CompletableFuture<T> {
|
||||
override fun complete(value: T) {
|
||||
deferred.complete(value)
|
||||
}
|
||||
|
||||
override suspend fun await(): T {
|
||||
return deferred.await()
|
||||
}
|
||||
|
||||
override fun getOrThrow(): T {
|
||||
return if (deferred.isCompleted) deferred.getCompleted() else throw IllegalLifecycleException(
|
||||
"Future was not completed yet"
|
||||
)
|
||||
}
|
||||
override fun complete(value: T) {
|
||||
deferred.complete(value)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun await(): T {
|
||||
return deferred.await()
|
||||
}
|
||||
|
||||
override fun getOrThrow(): T {
|
||||
return if (deferred.isCompleted) deferred.getCompleted() else throw IllegalLifecycleException(
|
||||
"Future was not completed yet"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-21
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerTask
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerGroup
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
||||
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||
import kotlin.test.*
|
||||
|
||||
@@ -30,7 +31,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `nativeMain linux macos`() {
|
||||
fun `nativeMain linux macos`() = project.runLifecycleAwareTest {
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName")
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName")
|
||||
|
||||
@@ -43,9 +44,8 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
linuxMain.dependsOn(nativeMain)
|
||||
macosMain.dependsOn(nativeMain)
|
||||
|
||||
project.evaluate()
|
||||
|
||||
val groups = task.getAllInteropsGroups()
|
||||
val groups = task.allInteropGroups.await()
|
||||
assertEquals(1, groups.size, "Expected only one InteropsGroup")
|
||||
|
||||
assertCInteropDependentEqualsForSourceSetAndCompilation(nativeMain)
|
||||
@@ -60,7 +60,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `nativeMain linux macos (no macos interop defined)`() {
|
||||
fun `nativeMain linux macos (no macos interop defined)`() = project.runLifecycleAwareTest {
|
||||
kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName")
|
||||
kotlin.macosX64("macos")
|
||||
|
||||
@@ -73,8 +73,6 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
linuxMain.dependsOn(nativeMain)
|
||||
macosMain.dependsOn(nativeMain)
|
||||
|
||||
project.evaluate()
|
||||
|
||||
assertNull(
|
||||
findCInteropCommonizerDependent(nativeMain),
|
||||
"Expected no CInteropCommonizerTarget from nativeMain, since one target has not defined any cinterop"
|
||||
@@ -87,7 +85,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `nativeMain iosMain linux macos iosX64 iosArm64`() {
|
||||
fun `nativeMain iosMain linux macos iosX64 iosArm64`() = project.runLifecycleAwareTest {
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val iosX64Interop = kotlin.iosX64("iosX64").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
@@ -108,10 +106,8 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
iosX64Main.dependsOn(iosMain)
|
||||
iosArm64Main.dependsOn(iosMain)
|
||||
|
||||
project.evaluate()
|
||||
|
||||
assertEquals(
|
||||
1, task.getAllInteropsGroups().size,
|
||||
1, task.allInteropGroups.await().size,
|
||||
"Expected exactly one InteropsGroup for task"
|
||||
)
|
||||
|
||||
@@ -144,7 +140,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
|
||||
private fun `nativeTest nativeMain linux macos`(
|
||||
nativeTestDependsOnNativeMain: Boolean
|
||||
) {
|
||||
) = project.runLifecycleAwareTest {
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
|
||||
@@ -169,10 +165,8 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
nativeTest.dependsOn(nativeMain)
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
|
||||
assertEquals(
|
||||
1, task.getAllInteropsGroups().size,
|
||||
1, task.allInteropGroups.await().size,
|
||||
"Expected exactly 1 'SharedInteropsGroup' for task"
|
||||
)
|
||||
|
||||
@@ -209,7 +203,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
|
||||
private fun `nativeTest nativeMain linux macos - test compilation defines custom cinterop`(
|
||||
nativeTestDependsOnNativeMain: Boolean
|
||||
) {
|
||||
) = project.runLifecycleAwareTest {
|
||||
val linuxInterop = kotlin.linuxX64("linux").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
val macosInterop = kotlin.macosX64("macos").compilations.getByName("main").cinterops.create("anyInteropName").identifier
|
||||
kotlin.linuxX64("linux").compilations.getByName("test").cinterops.create("anyOtherName").identifier
|
||||
@@ -235,10 +229,9 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
nativeTest.dependsOn(nativeMain)
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
|
||||
assertEquals(
|
||||
1, task.getAllInteropsGroups().size,
|
||||
1, task.allInteropGroups.await().size,
|
||||
"Expected exactly 1 'SharedInteropsGroup' for task"
|
||||
)
|
||||
|
||||
@@ -271,7 +264,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
`hierarchical project`(testSourceSetsDependOnMainSourceSets = false)
|
||||
}
|
||||
|
||||
private fun `hierarchical project`(testSourceSetsDependOnMainSourceSets: Boolean) {
|
||||
private fun `hierarchical project`(testSourceSetsDependOnMainSourceSets: Boolean) = project.runLifecycleAwareTest {
|
||||
/* Define targets */
|
||||
val linux = kotlin.linuxX64("linux")
|
||||
val macos = kotlin.macosX64("macos")
|
||||
@@ -368,14 +361,13 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
target.compilations.getByName("test").defaultSourceSet.dependsOn(nativeTest)
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
|
||||
assertCInteropDependentEqualsForSourceSetAndCompilation(nativeMain)
|
||||
assertCInteropDependentEqualsForSourceSetAndCompilation(unixMain)
|
||||
assertCInteropDependentEqualsForSourceSetAndCompilation(appleMain)
|
||||
assertCInteropDependentEqualsForSourceSetAndCompilation(iosMain)
|
||||
|
||||
val groups = task.getAllInteropsGroups()
|
||||
val groups = task.allInteropGroups.await()
|
||||
assertEquals(2, groups.size, "Expected exactly two interop groups: main and test")
|
||||
|
||||
val nativeCommonizerTarget = SharedCommonizerTarget(nativeTargets.map { it.konanTarget })
|
||||
@@ -462,7 +454,7 @@ class CInteropCommonizerTaskTest : MultiplatformExtensionTest() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertCInteropDependentEqualsForSourceSetAndCompilation(sourceSet: KotlinSourceSet) {
|
||||
private suspend fun assertCInteropDependentEqualsForSourceSetAndCompilation(sourceSet: KotlinSourceSet) {
|
||||
assertEquals(
|
||||
expectCInteropCommonizerDependent(sourceSet),
|
||||
expectCInteropCommonizerDependent(expectSharedNativeCompilation(sourceSet)),
|
||||
|
||||
+9
-7
@@ -15,11 +15,13 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerDependent
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.from
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.fail
|
||||
|
||||
|
||||
abstract class MultiplatformExtensionTest {
|
||||
@@ -39,29 +41,29 @@ abstract class MultiplatformExtensionTest {
|
||||
project.enableCInteropCommonization()
|
||||
}
|
||||
|
||||
internal fun expectCInteropCommonizerDependent(compilation: KotlinSharedNativeCompilation): CInteropCommonizerDependent {
|
||||
internal suspend fun expectCInteropCommonizerDependent(compilation: KotlinSharedNativeCompilation): CInteropCommonizerDependent {
|
||||
return assertNotNull(
|
||||
CInteropCommonizerDependent.from(compilation), "Can't find SharedInterops for ${compilation.name} compilation"
|
||||
)
|
||||
}
|
||||
|
||||
internal fun expectCInteropCommonizerDependent(sourceSet: KotlinSourceSet): CInteropCommonizerDependent {
|
||||
internal suspend fun expectCInteropCommonizerDependent(sourceSet: KotlinSourceSet): CInteropCommonizerDependent {
|
||||
return assertNotNull(
|
||||
CInteropCommonizerDependent.from(sourceSet), "Can't find SharedInterops for ${sourceSet.name} source set"
|
||||
)
|
||||
}
|
||||
|
||||
internal fun findCInteropCommonizerDependent(compilation: KotlinSharedNativeCompilation): CInteropCommonizerDependent? {
|
||||
internal suspend fun findCInteropCommonizerDependent(compilation: KotlinSharedNativeCompilation): CInteropCommonizerDependent? {
|
||||
return CInteropCommonizerDependent.from(compilation)
|
||||
}
|
||||
|
||||
internal fun findCInteropCommonizerDependent(sourceSet: KotlinSourceSet): CInteropCommonizerDependent? {
|
||||
internal suspend fun findCInteropCommonizerDependent(sourceSet: KotlinSourceSet): CInteropCommonizerDependent? {
|
||||
return CInteropCommonizerDependent.from(sourceSet)
|
||||
}
|
||||
|
||||
internal fun expectSharedNativeCompilation(sourceSet: KotlinSourceSet): KotlinSharedNativeCompilation {
|
||||
return kotlin.targets.flatMap { it.compilations }.filterIsInstance<KotlinSharedNativeCompilation>()
|
||||
.single { it.defaultSourceSet == sourceSet }
|
||||
internal suspend fun expectSharedNativeCompilation(sourceSet: KotlinSourceSet): KotlinSharedNativeCompilation {
|
||||
val compilation = project.findMetadataCompilation(sourceSet) ?: fail("Missing metadata compilation for $sourceSet")
|
||||
return assertIsInstance<KotlinSharedNativeCompilation>(compilation)
|
||||
}
|
||||
|
||||
internal fun KotlinNativeTarget.mainCinteropIdentifier(name: String): CInteropIdentifier {
|
||||
|
||||
Reference in New Issue
Block a user