From a8a861e1ce5be5dd39fa594701c6b2e88fcb0290 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Thu, 6 Oct 2022 18:26:09 +0200 Subject: [PATCH] [Gradle][MPP] KotlinTargetHierarchyBuilder: implement w/ include & exclude predicates ^KT-53570 Verification Pending --- .../gradle/dsl/KotlinTargetHierarchyDsl.kt | 11 +- .../plugin/KotlinTargetHierarchyBuilder.kt | 71 +++++-- .../gradle/plugin/KotlinTargetsContainer.kt | 2 +- .../targetHierarchy/KotlinTargetHierarchy.kt | 2 +- .../applyKotlinTargetHierarchy.kt | 21 +- .../buildKotlinTargetHierarchy.kt | 198 +++++++++++++++--- .../naturalKotlinTargetHierarchy.kt | 50 +++-- .../KotlinTargetHierarchyBuilderTest.kt | 39 ++++ .../KotlinTargetHierarchyDescriptorTest.kt | 4 +- .../gradle/KotlinTargetHierarchyDslTest.kt | 4 +- 10 files changed, 321 insertions(+), 81 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyBuilderTest.kt diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl.kt index 6291a8d1cc8..4b88ccfa7fb 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl.kt @@ -52,7 +52,7 @@ interface KotlinTargetHierarchyDsl { * +----------------------+--------------------+-----------------------+ * | | | | * - * apple linux windows androidNative + * apple linux mingw androidNative * * | * +-----------+------------+------------+ @@ -67,11 +67,10 @@ interface KotlinTargetHierarchyDsl { * ```kotlin * kotlin { * targets.hierarchy.default { target -> - * if(target.isNative) { - * group("native") { // <- we can re-declare already existing groups and connect children to it! - * if(target.isLinux || target.isApple) { - * group("unixLike") - * } + * group("native") { // <- we can re-declare already existing groups and connect children to it! + * group("unixLike") { + * anyLinux() + * anyApple() * } * } * } diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder.kt index 3da6f75ef2f..43f5f3fbc64 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder.kt @@ -1,7 +1,4 @@ -/* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ +// DO NOT EDIT MANUALLY! Generated by org.jetbrains.kotlin.generators.gradle.dsl.MppKotlinTargetHierarchyBuilderCodegenKt package org.jetbrains.kotlin.gradle.plugin @@ -9,24 +6,54 @@ import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi interface KotlinTargetHierarchyBuilder { - val target: KotlinTarget - val compilation: KotlinCompilation<*> - - val isNative: Boolean - val isApple: Boolean - val isIos: Boolean - val isWatchos: Boolean - val isMacos: Boolean - val isTvos: Boolean - val isWindows: Boolean - val isLinux: Boolean - val isAndroidNative: Boolean - val isJvm: Boolean - val isAndroidJvm: Boolean - val isJsLegacy: Boolean - val isJsIr: Boolean - val isJs: Boolean - + /* Declaring groups */ fun common(build: KotlinTargetHierarchyBuilder.() -> Unit) = group("common", build) fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit = {}) + + /* low-level APIs */ + fun includeCompilation(predicate: (KotlinCompilation<*>) -> Boolean) + fun excludeCompilation(predicate: (KotlinCompilation<*>) -> Boolean) + + /* Convenient groups */ + fun anyNative() + fun anyApple() + fun anyIos() + fun anyWatchos() + fun anyMacos() + fun anyTvos() + fun anyMingw() + fun anyLinux() + fun anyAndroidNative() + fun anyJs() + + /* Actual targets */ + fun jvm() + fun android() + fun androidNativeX64() + fun androidNativeX86() + fun androidNativeArm32() + fun androidNativeArm64() + fun iosArm32() + fun iosArm64() + fun iosX64() + fun iosSimulatorArm64() + fun watchosArm32() + fun watchosArm64() + fun watchosX86() + fun watchosX64() + fun watchosSimulatorArm64() + fun watchosDeviceArm64() + fun tvosArm64() + fun tvosX64() + fun tvosSimulatorArm64() + fun linuxX64() + fun mingwX86() + fun mingwX64() + fun macosX64() + fun macosArm64() + fun linuxArm64() + fun linuxArm32Hfp() + fun linuxMips32() + fun linuxMipsel32() + fun wasm32() } diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetsContainer.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetsContainer.kt index 9ba2df28688..668ee77ec36 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetsContainer.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetsContainer.kt @@ -18,4 +18,4 @@ interface KotlinTargetsContainerWithPresets : KotlinTargetsContainer { interface KotlinSourceSetContainer { val sourceSets: NamedDomainObjectContainer -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/KotlinTargetHierarchy.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/KotlinTargetHierarchy.kt index e3834b08c38..931bf5731ac 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/KotlinTargetHierarchy.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/KotlinTargetHierarchy.kt @@ -35,4 +35,4 @@ internal data class KotlinTargetHierarchy( if (children.isEmpty()) return node.toString() return node.toString() + "\n" + children.joinToString("\n").prependIndent("----") } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt index 2b666e799e7..29af1b67d24 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt @@ -29,16 +29,27 @@ private fun applyKotlinTargetHierarchy( compilation: KotlinCompilation<*>, sourceSets: NamedDomainObjectContainer ): KotlinSourceSet? { - val sharedSourceSetName = hierarchy.node.sharedSourceSetName(compilation) ?: return null - val sharedSourceSet = sourceSets.maybeCreate(sharedSourceSetName) + val sharedSourceSet = createSharedSourceSetOrNull(sourceSets, hierarchy.node, compilation) - hierarchy.children + val childSourceSets = hierarchy.children .mapNotNull { childHierarchy -> applyKotlinTargetHierarchy(childHierarchy, compilation, sourceSets) } - .forEach { childSourceSet -> childSourceSet.dependsOn(sharedSourceSet) } - if (hierarchy.children.isEmpty()) { + if (sharedSourceSet == null) return null + + if (hierarchy.children.isNotEmpty()) { + childSourceSets.forEach { childSourceSet -> childSourceSet.dependsOn(sharedSourceSet) } + } else { compilation.defaultSourceSet.dependsOn(sharedSourceSet) } return sharedSourceSet } + +private fun createSharedSourceSetOrNull( + sourceSets: NamedDomainObjectContainer, + node: KotlinTargetHierarchy.Node, + compilation: KotlinCompilation<*>, +): KotlinSourceSet? { + val sharedSourceSetName = node.sharedSourceSetName(compilation) ?: return null + return sourceSets.maybeCreate(sharedSourceSetName) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/buildKotlinTargetHierarchy.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/buildKotlinTargetHierarchy.kt index c903450c526..04d7f9c639e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/buildKotlinTargetHierarchy.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/buildKotlinTargetHierarchy.kt @@ -6,22 +6,26 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy import org.gradle.api.InvalidUserCodeException -import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyBuilder +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget -import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget -import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.konan.target.Family +import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.tooling.core.closure + internal fun KotlinTargetHierarchyDescriptor.buildKotlinTargetHierarchy(compilation: KotlinCompilation<*>): KotlinTargetHierarchy { val context = KotlinTargetHierarchyBuilderImplContext(compilation) this(context.getOrCreateBuilder(KotlinTargetHierarchy.Node.Root)) return context.build(KotlinTargetHierarchy.Node.Root) } -private class KotlinTargetHierarchyBuilderImplContext(val compilation: KotlinCompilation<*>) { +private class KotlinTargetHierarchyBuilderImplContext(private val compilation: KotlinCompilation<*>) { private val builders = hashMapOf() private val builtValues = hashMapOf() @@ -48,7 +52,15 @@ private class KotlinTargetHierarchyBuilderImplContext(val compilation: KotlinCom val childrenNodes = builder.children.map { it.node } - builder.children.flatMap { child -> child.childrenClosure }.map { it.node }.toSet() - KotlinTargetHierarchy(node, childrenNodes.map(this::build).toSet()) + /* + Respect include & exclude predicates! + */ + val applicableChildrenNodes = childrenNodes.filter { node -> + val childrenBuilder = getOrCreateBuilder(node) + childrenBuilder.predicate?.invoke(compilation) ?: true + } + + KotlinTargetHierarchy(node, applicableChildrenNodes.map(this::build).toSet()) } } } @@ -58,11 +70,163 @@ private class KotlinTargetHierarchyBuilderImpl( val node: KotlinTargetHierarchy.Node, ) : KotlinTargetHierarchyBuilder { - override val compilation: KotlinCompilation<*> get() = context.compilation - override val target: KotlinTarget get() = compilation.target - val children = mutableSetOf() - val childrenClosure: Set get() = closure { it.children } + val childrenClosure get() = closure { it.children } + + var predicate: ((KotlinCompilation<*>) -> Boolean)? = null + + override fun includeCompilation(predicate: (KotlinCompilation<*>) -> Boolean) { + val previousPredicate = this.predicate + if (previousPredicate == null) { + this.predicate = predicate + return + } + + this.predicate = { previousPredicate(it) || predicate(it) } + } + + override fun excludeCompilation(predicate: (KotlinCompilation<*>) -> Boolean) { + val previousPredicate = this.predicate + if (previousPredicate == null) { + this.predicate = { !predicate(it) } + return + } + this.predicate = { previousPredicate(it) && !predicate(it) } + } + + private inline fun includeTarget(crossinline predicate: (KotlinTarget) -> Boolean) = includeCompilation { predicate(it.target) } + + override fun anyNative() = includeTarget { it is KotlinNativeTarget } + + override fun anyApple() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family.isAppleFamily } + + override fun anyIos() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family == Family.IOS } + + override fun anyWatchos() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family == Family.WATCHOS } + + override fun anyMacos() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family == Family.OSX } + + override fun anyTvos() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family == Family.TVOS } + + override fun anyMingw() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family == Family.MINGW } + + override fun anyLinux() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family == Family.LINUX } + + override fun anyAndroidNative() = includeTarget { it is KotlinNativeTarget && it.konanTarget.family == Family.ANDROID } + + override fun anyJs() = includeTarget { it is KotlinJsTargetDsl } + + override fun jvm() = includeTarget { it is KotlinJvmTarget } + + override fun android() = includeTarget { it is KotlinAndroidTarget } + + override fun androidNativeX64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.ANDROID_X64 + } + + override fun androidNativeX86() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.ANDROID_X86 + } + + override fun androidNativeArm32() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.ANDROID_X86 + } + + override fun androidNativeArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.ANDROID_ARM64 + } + + override fun iosArm32() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.IOS_ARM32 + } + + override fun iosArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.IOS_ARM64 + } + + override fun iosX64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.IOS_X64 + } + + override fun iosSimulatorArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.IOS_SIMULATOR_ARM64 + } + + override fun watchosArm32() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.WATCHOS_ARM32 + } + + override fun watchosArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.WATCHOS_ARM64 + } + + override fun watchosX86() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.WATCHOS_X86 + } + + override fun watchosX64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.WATCHOS_X64 + } + + override fun watchosSimulatorArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.WATCHOS_SIMULATOR_ARM64 + } + + override fun watchosDeviceArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.WATCHOS_DEVICE_ARM64 + } + + override fun tvosArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.TVOS_ARM64 + } + + override fun tvosX64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.TVOS_X64 + } + + override fun tvosSimulatorArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.TVOS_SIMULATOR_ARM64 + } + + override fun linuxX64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.LINUX_X64 + } + + override fun mingwX86() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.MINGW_X86 + } + + override fun mingwX64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.MINGW_X64 + } + + override fun macosX64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.MACOS_X64 + } + + override fun macosArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.MACOS_ARM64 + } + + override fun linuxArm64() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.LINUX_ARM64 + } + + override fun linuxArm32Hfp() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.LINUX_ARM32_HFP + } + + override fun linuxMips32() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.LINUX_MIPS32 + } + + override fun linuxMipsel32() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.LINUX_MIPSEL32 + } + + override fun wasm32() = includeTarget { + it is KotlinNativeTarget && it.konanTarget == KonanTarget.WASM32 + } override fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit) { val node = KotlinTargetHierarchy.Node.Group(name) @@ -72,27 +236,11 @@ private class KotlinTargetHierarchyBuilderImpl( checkCyclicHierarchy() } - override val isNative: Boolean get() = target is KotlinNativeTarget - override val isApple: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family.isAppleFamily } - override val isIos: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family == Family.IOS } - override val isWatchos: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family == Family.WATCHOS } - override val isMacos: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family == Family.OSX } - override val isTvos: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family == Family.TVOS } - override val isWindows: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family == Family.MINGW } - override val isLinux: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family == Family.LINUX } - override val isAndroidNative: Boolean get() = target.let { it is KotlinNativeTarget && it.konanTarget.family == Family.ANDROID } - override val isJvm: Boolean get() = target is KotlinJvmTarget - override val isAndroidJvm: Boolean get() = target is KotlinAndroidTarget - override val isJsLegacy: Boolean get() = target is KotlinJsTarget - override val isJsIr: Boolean get() = target is KotlinJsIrTarget - override val isJs: Boolean get() = isJsIr || isJsLegacy - override fun toString(): String { return "KotlinTargetHierarchyBuilder($node)" } } - /* Cycle Detection: Provide feedback for users when a KotlinTargetHierarchy cycle is declared */ private fun KotlinTargetHierarchyBuilderImpl.checkCyclicHierarchy(): Nothing? { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/naturalKotlinTargetHierarchy.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/naturalKotlinTargetHierarchy.kt index 7ced3014918..ac887f60105 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/naturalKotlinTargetHierarchy.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/naturalKotlinTargetHierarchy.kt @@ -10,26 +10,42 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.isMain import org.jetbrains.kotlin.gradle.plugin.mpp.isTest internal val naturalKotlinTargetHierarchy = KotlinTargetHierarchyDescriptor { - if (!compilation.isMain() && !compilation.isTest()) { - /* This hierarchy is only defined for default 'main' and 'test' compilations */ - return@KotlinTargetHierarchyDescriptor - } - common { - if (isNative) { - group("native") { - if (isApple) { - group("apple") { - if (isIos) group("ios") - if (isTvos) group("tvos") - if (isWatchos) group("watchos") - if (isMacos) group("macos") - } + group("native") { + anyNative() + /* natural hierarchy is only defined for main and test default compilations, by default */ + excludeCompilation { compilation -> !(compilation.isMain() || compilation.isTest()) } + + group("apple") { + anyApple() + + group("ios") { + anyIos() } - if (isLinux) group("linux") - if (isWindows) group("windows") - if (isAndroidNative) group("androidNative") + group("tvos") { + anyTvos() + } + + group("watchos") { + anyWatchos() + } + + group("macos") { + anyMacos() + } + } + + group("linux") { + anyLinux() + } + + group("mingw") { + anyMingw() + } + + group("androidNative") { + anyAndroidNative() } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyBuilderTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyBuilderTest.kt new file mode 100644 index 00000000000..67c55b2cdda --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyBuilderTest.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle + +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyBuilder +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsTargetPreset +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmWithJavaTargetPreset +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinWasmTargetPreset +import org.junit.Test +import kotlin.test.fail + +class KotlinTargetHierarchyBuilderTest { + + @Test + fun `test - interface offers functions for known presets`() { + val kotlinTargetHierarchyBuilderInterface = KotlinTargetHierarchyBuilder::class.java + + buildProjectWithMPP().multiplatformExtension.presets + + // JS targets are special and therefore are only handled manually using `anyJs()` + .filter { it !is KotlinJsTargetPreset } + .filter { it !is KotlinJsIrTargetPreset } + .filter { it !is KotlinWasmTargetPreset } + + // jvmWithJava is covered by the jvm() call + .filter { it !is KotlinJvmWithJavaTargetPreset } + .forEach { preset -> + if (kotlinTargetHierarchyBuilderInterface.declaredMethods.none { it.name == preset.name }) + fail("${kotlinTargetHierarchyBuilderInterface.name}: Missing ${preset.name}() function") + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDescriptorTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDescriptorTest.kt index 3e2218702b9..6ad97a48fcb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDescriptorTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDescriptorTest.kt @@ -27,8 +27,8 @@ class KotlinTargetHierarchyDescriptorTest { fun `test - simple descriptor`() { val descriptor = KotlinTargetHierarchyDescriptor { common { - if (target.name == "a") group("groupA") - if (target.name == "b") group("groupB") + group("groupA") { includeCompilation { it.target.name == "a" } } + group("groupB") { includeCompilation { it.target.name == "b" } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDslTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDslTest.kt index 770adc3561f..4531291cb51 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDslTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinTargetHierarchyDslTest.kt @@ -95,12 +95,12 @@ class KotlinTargetHierarchyDslTest { ) assertEquals( - stringSetOf("androidNativeMain", "appleMain", "linuxMain", "windowsMain"), + stringSetOf("androidNativeMain", "appleMain", "linuxMain", "mingwMain"), kotlin.dependingSourceSetNames("nativeMain") ) assertEquals( - stringSetOf("androidNativeTest", "appleTest", "linuxTest", "windowsTest"), + stringSetOf("androidNativeTest", "appleTest", "linuxTest", "mingwTest"), kotlin.dependingSourceSetNames("nativeTest") )