[Gradle] Stabilise Kotlin Hierarchy Template DSL

- Remove 'Target' name from hierarchy components as in
    - KotlinTargetHierarchyBuilder -> KotlinHierarchyBuilder
    - KotlinTargetHierarchyDsl -> KotlinHierarchyDsl

- Rename KotlinTargetHierarchyDescriptor -> KotlinHierarchyTemplate
    To convey a better intuition about the 'template' vs 'layout' separation:
    A 'template' is used to 'layout' the actual 'hierarchy' on a given project.

- Move entities from .mpp.targetHierarchy to .hierarchy package
    As the .targetHierarchy package was using the 'target' term as well

- Rename SourceSetTree to KotlinSourceSetTree

- Rename SourceSetTreeClassifier to KotlinSourceSetTreeClassifier
    (Support external target APIs by introducing a V2 api version)

^KT-58676 In Progress
This commit is contained in:
Sebastian Sellmair
2023-06-19 16:11:07 +02:00
committed by Space Team
parent cb087b7def
commit b2dd83515c
82 changed files with 1230 additions and 819 deletions
@@ -242,6 +242,12 @@ public final class org/jetbrains/kotlin/gradle/dsl/KotlinCompile$DefaultImpls {
public static fun kotlinOptions (Lorg/jetbrains/kotlin/gradle/dsl/KotlinCompile;Lorg/gradle/api/Action;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/dsl/KotlinHierarchyDsl {
public abstract fun applyHierarchyTemplate (Lkotlin/jvm/functions/Function1;)V
public abstract fun applyHierarchyTemplate (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate;)V
public abstract fun applyHierarchyTemplate (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate;Lkotlin/jvm/functions/Function1;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/dsl/KotlinJsCompilerOptions : org/jetbrains/kotlin/gradle/dsl/KotlinCommonCompilerOptions {
public abstract fun getFriendModulesDisabled ()Lorg/gradle/api/provider/Property;
public abstract fun getMain ()Lorg/gradle/api/provider/Property;
@@ -519,17 +525,6 @@ public abstract interface class org/jetbrains/kotlin/gradle/dsl/KotlinNativeXCFr
public abstract fun targets ([Lorg/jetbrains/kotlin/konan/target/KonanTarget;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl {
public abstract fun apply (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyDescriptor;Lkotlin/jvm/functions/Function1;)V
public abstract fun custom (Lkotlin/jvm/functions/Function1;)V
public abstract fun default (Lkotlin/jvm/functions/Function1;)V
}
public final class org/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl$DefaultImpls {
public static synthetic fun apply$default (Lorg/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl;Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyDescriptor;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static synthetic fun default$default (Lorg/jetbrains/kotlin/gradle/dsl/KotlinTargetHierarchyDsl;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/dsl/KotlinTopLevelExtensionConfig {
public abstract fun explicitApi ()V
public abstract fun explicitApiWarning ()V
@@ -902,6 +897,87 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinExecuti
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin {
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder {
public abstract fun common (Lkotlin/jvm/functions/Function1;)V
public abstract fun excludeCompilations (Lkotlin/jvm/functions/Function1;)V
public abstract fun filterCompilations (Lkotlin/jvm/functions/Function1;)V
public abstract fun group (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public abstract fun withAndroid ()V
public abstract fun withAndroidNative ()V
public abstract fun withAndroidNativeArm32 ()V
public abstract fun withAndroidNativeArm64 ()V
public abstract fun withAndroidNativeX64 ()V
public abstract fun withAndroidNativeX86 ()V
public abstract fun withAndroidTarget ()V
public abstract fun withApple ()V
public abstract fun withCompilations (Lkotlin/jvm/functions/Function1;)V
public abstract fun withIos ()V
public abstract fun withIosArm32 ()V
public abstract fun withIosArm64 ()V
public abstract fun withIosSimulatorArm64 ()V
public abstract fun withIosX64 ()V
public abstract fun withJs ()V
public abstract fun withJvm ()V
public abstract fun withLinux ()V
public abstract fun withLinuxArm32Hfp ()V
public abstract fun withLinuxArm64 ()V
public abstract fun withLinuxMips32 ()V
public abstract fun withLinuxMipsel32 ()V
public abstract fun withLinuxX64 ()V
public abstract fun withMacos ()V
public abstract fun withMacosArm64 ()V
public abstract fun withMacosX64 ()V
public abstract fun withMingw ()V
public abstract fun withMingwX64 ()V
public abstract fun withMingwX86 ()V
public abstract fun withNative ()V
public abstract fun withTvos ()V
public abstract fun withTvosArm64 ()V
public abstract fun withTvosSimulatorArm64 ()V
public abstract fun withTvosX64 ()V
public abstract fun withWasm ()V
public abstract fun withWasm32 ()V
public abstract fun withWatchos ()V
public abstract fun withWatchosArm32 ()V
public abstract fun withWatchosArm64 ()V
public abstract fun withWatchosDeviceArm64 ()V
public abstract fun withWatchosSimulatorArm64 ()V
public abstract fun withWatchosX64 ()V
public abstract fun withWatchosX86 ()V
public abstract fun withoutCompilations (Lkotlin/jvm/functions/Function1;)V
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder$DefaultImpls {
public static fun common (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder;Lkotlin/jvm/functions/Function1;)V
public static fun filterCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun group$default (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static fun withoutCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder;Lkotlin/jvm/functions/Function1;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder$Root : org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder {
public abstract fun excludeSourceSetTree ([Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;)V
public abstract fun sourceSetTrees ([Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;)V
public abstract fun withSourceSetTree ([Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;)V
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder$Root$DefaultImpls {
public static fun common (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder$Root;Lkotlin/jvm/functions/Function1;)V
public static fun filterCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder$Root;Lkotlin/jvm/functions/Function1;)V
public static fun withoutCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyBuilder$Root;Lkotlin/jvm/functions/Function1;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate {
public static final field Templates Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate$Templates;
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate$Templates {
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplateKt {
public static final fun KotlinHierarchyTemplate (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate;
public static final fun extend (Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/KotlinHierarchyTemplate;
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinJsCompilerType : java/lang/Enum {
public static final field BOTH Lorg/jetbrains/kotlin/gradle/plugin/KotlinJsCompilerType;
public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/KotlinJsCompilerType$Companion;
@@ -1017,6 +1093,23 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinSourceS
public abstract fun getSourceSets ()Lorg/gradle/api/NamedDomainObjectContainer;
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree {
public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree$Companion;
public abstract fun getName ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree$Companion {
public final fun getInstrumentedTest ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
public final fun getIntegrationTest ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
public final fun getMain ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
public final fun getTest ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
public final fun getUnitTest ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTreeKt {
public static final fun KotlinSourceSetTree (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinTarget : org/gradle/api/Named, org/gradle/api/attributes/HasAttributes, org/jetbrains/kotlin/gradle/plugin/HasProject, org/jetbrains/kotlin/tooling/core/HasMutableExtras {
public abstract fun attributes (Lkotlin/jvm/functions/Function1;)V
public abstract fun attributes (Lorg/gradle/api/Action;)V
@@ -1063,11 +1156,11 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinTargetE
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy {
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree {
public final class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree : org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree {
public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree$Companion;
public fun <init> (Ljava/lang/String;)V
public fun equals (Ljava/lang/Object;)Z
public final fun getName ()Ljava/lang/String;
public fun getName ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
@@ -1080,84 +1173,6 @@ public final class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$Sour
public final fun getUnitTest ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree;
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder {
public abstract fun common (Lkotlin/jvm/functions/Function1;)V
public abstract fun excludeCompilations (Lkotlin/jvm/functions/Function1;)V
public abstract fun filterCompilations (Lkotlin/jvm/functions/Function1;)V
public abstract fun group (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public abstract fun withAndroid ()V
public abstract fun withAndroidNative ()V
public abstract fun withAndroidNativeArm32 ()V
public abstract fun withAndroidNativeArm64 ()V
public abstract fun withAndroidNativeX64 ()V
public abstract fun withAndroidNativeX86 ()V
public abstract fun withAndroidTarget ()V
public abstract fun withApple ()V
public abstract fun withCompilations (Lkotlin/jvm/functions/Function1;)V
public abstract fun withIos ()V
public abstract fun withIosArm32 ()V
public abstract fun withIosArm64 ()V
public abstract fun withIosSimulatorArm64 ()V
public abstract fun withIosX64 ()V
public abstract fun withJs ()V
public abstract fun withJvm ()V
public abstract fun withLinux ()V
public abstract fun withLinuxArm32Hfp ()V
public abstract fun withLinuxArm64 ()V
public abstract fun withLinuxMips32 ()V
public abstract fun withLinuxMipsel32 ()V
public abstract fun withLinuxX64 ()V
public abstract fun withMacos ()V
public abstract fun withMacosArm64 ()V
public abstract fun withMacosX64 ()V
public abstract fun withMingw ()V
public abstract fun withMingwX64 ()V
public abstract fun withMingwX86 ()V
public abstract fun withNative ()V
public abstract fun withTvos ()V
public abstract fun withTvosArm64 ()V
public abstract fun withTvosSimulatorArm64 ()V
public abstract fun withTvosX64 ()V
public abstract fun withWasm ()V
public abstract fun withWasm32 ()V
public abstract fun withWatchos ()V
public abstract fun withWatchosArm32 ()V
public abstract fun withWatchosArm64 ()V
public abstract fun withWatchosDeviceArm64 ()V
public abstract fun withWatchosSimulatorArm64 ()V
public abstract fun withWatchosX64 ()V
public abstract fun withWatchosX86 ()V
public abstract fun withoutCompilations (Lkotlin/jvm/functions/Function1;)V
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder$DefaultImpls {
public static fun common (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder;Lkotlin/jvm/functions/Function1;)V
public static fun filterCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun group$default (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static fun withoutCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder;Lkotlin/jvm/functions/Function1;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder$Root : org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder {
public abstract fun excludeSourceSetTree ([Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree;)V
public abstract fun sourceSetTrees ([Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree;)V
public abstract fun withSourceSetTree ([Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree;)V
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder$Root$DefaultImpls {
public static fun common (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder$Root;Lkotlin/jvm/functions/Function1;)V
public static fun filterCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder$Root;Lkotlin/jvm/functions/Function1;)V
public static fun withoutCompilations (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder$Root;Lkotlin/jvm/functions/Function1;)V
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyDescriptor {
public abstract fun describe (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyBuilder$Root;)V
public abstract fun extend (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyDescriptor;
}
public final class org/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyDescriptorKt {
public static final fun KotlinTargetHierarchyDescriptor (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchyDescriptor;
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/KotlinTargetPreset : org/gradle/api/Named {
public abstract fun createTarget (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/plugin/KotlinTarget;
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.dsl
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyBuilder
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
interface KotlinHierarchyDsl {
fun applyHierarchyTemplate(template: KotlinHierarchyTemplate)
@ExperimentalKotlinGradlePluginApi
fun applyHierarchyTemplate(template: KotlinHierarchyTemplate, extension: KotlinHierarchyBuilder.Root.() -> Unit)
@ExperimentalKotlinGradlePluginApi
fun applyHierarchyTemplate(template: KotlinHierarchyBuilder.Root.() -> Unit)
}
@@ -1,171 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.gradle.dsl
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyBuilder
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
@ExperimentalKotlinGradlePluginApi
interface KotlinTargetHierarchyDsl {
fun apply(
hierarchyDescriptor: KotlinTargetHierarchyDescriptor,
describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)? = null
)
/**
* Set's up a 'natural'/'default' hierarchy withing [KotlinTarget]'s in the project.
*
* #### Example 1
*
* ```kotlin
* kotlin {
* targetHierarchy.default() // <- position of this call is not relevant!
*
* iosX64()
* iosArm64()
* linuxX64()
* linuxArm64()
* }
* ```
*
* Will create the following SourceSets:
* `[iosMain, iosTest, appleMain, appleTest, linuxMain, linuxTest, nativeMain, nativeTest]
*
*
* Hierarchy:
* ```
* common
* |
* +-----------------+-------------------+
* | |
*
* native ...
*
* |
* |
* |
* +----------------------+--------------------+-----------------------+
* | | | |
*
* apple linux mingw androidNative
*
* |
* +-----------+------------+------------+
* | | | |
*
* macos ios tvos watchos
* ```
*
* #### Example 2: Adding custom groups
* Let's imagine we would additionally like to share code between linux and apple (unixLike)
*
* ```kotlin
* kotlin {
* targetHierarchy.default { target ->
* group("native") { // <- we can re-declare already existing groups and connect children to it!
* group("unixLike") {
* withLinux()
* withApple()
* }
* }
* }
* }
* ```
*
* @param describeExtension: Additional groups can be described to extend the 'default'/'natural' hierarchy:
* @see KotlinTargetHierarchyDescriptor.extend
*/
fun default(describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)? = null)
/**
* Allows to create a fully custom hierarchy (no defaults applied)
* Note: Using the custom hierarchy will also require to set the edges to 'commonMain' and 'commonTest' SourceSets by
* using the `common` group.
*
* #### Example 1:
* Sharing code between iOS and a jvmTarget:
* ```kotlin
* targetHierarchy.custom {
* common {
* withJvm()
* group("ios") {
* withIos()
* }
* }
* }
* ```
*
* Will create two [SourceSetTree] using the 'common' and 'ios' groups, applied on the "test" and "main" compilations:
* When the following targets are specified:
* - jvm()
* - iosX64()
* - iosArm64()
* ```
* "main" "test"
* commonMain commonTest
* | |
* | |
* +----------+----------+ +----------+----------+
* | | | |
* iosMain jvmMain iosTest jvmTest
* | |
* +----+-----+ +----+-----+
* | | | |
* iosX64Main iosArm64Main iosX64Test iosArm64Test
* ```
*
* #### Example 2: Creating a 'diamond structure'
* ```kotlin
* targetHierarchy.custom {
* common {
* group("ios") {
* withIos()
* }
*
* group("frontend") {
* withJvm()
* group("ios") // <- ! We can again reference the 'ios' group
* }
*
* group("apple") {
* withMacos()
* group("ios") // <- ! We can again reference the 'ios' group
* }
* }
* }
* ```
*
* In this case, the _group_ "ios" can be created with 'group("ios")' and later referenced with the same construction to build
* the tree. Applying the descriptor from the example to the following targets:
* - iosX64()
* - iosArm64()
* - macosX64()
* - jvm()
*
* will create the following 'main' SourceSetTree:
*
* ```
* commonMain
* |
* +------------+----------+
* | |
* frontendMain appleMain
* | |
* +---------+------------+-----------+----------+
* | | |
* jvmMain iosMain macosX64Main
* |
* |
* +----+----+
* | |
* iosX64Main iosArm64Main
* ```
*/
fun custom(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit)
}
@@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Action
import org.gradle.api.Named
import org.gradle.api.Project
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.file.FileCollection
@@ -17,7 +16,6 @@ import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptionsDeprecated
import org.jetbrains.kotlin.gradle.dsl.KotlinCompileDeprecated
import org.jetbrains.kotlin.gradle.dsl.KotlinTargetHierarchyDsl
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
@@ -1,5 +1,3 @@
// DO NOT EDIT MANUALLY! Generated by org.jetbrains.kotlin.generators.gradle.dsl.MppKotlinTargetHierarchyBuilderCodegenKt
package org.jetbrains.kotlin.gradle.plugin
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
@@ -7,18 +5,18 @@ import org.jetbrains.kotlin.konan.target.DEPRECATED_TARGET_MESSAGE
@KotlinTargetsDsl
@ExperimentalKotlinGradlePluginApi
interface KotlinTargetHierarchyBuilder {
interface KotlinHierarchyBuilder {
@KotlinTargetsDsl
@ExperimentalKotlinGradlePluginApi
interface Root : KotlinTargetHierarchyBuilder {
interface Root : KotlinHierarchyBuilder {
/**
* Defines the trees that the described hierarchy is applied to.
* ### Example 1: Only apply a hierarchy for the "main" and "test" [KotlinTargetHierarchy.SourceSetTree]
* ### Example 1: Only apply a hierarchy for the "main" and "test" [KotlinSourceSetTree]
*
* ```kotlin
* targetHierarchy.custom {
* sourceSetTrees(SourceSetTree.main, SourceSetTree.test)
* applyHierarchyTemplate {
* sourceSetTrees(KotlinSourceSetTree.main, KotlinSourceSetTree.test)
* common {
* withJvm()
* group("ios") {
@@ -45,7 +43,7 @@ interface KotlinTargetHierarchyBuilder {
* ### Example 2:
* Using a different hierarchy for "main" and "test"
*```kotlin
* targetHierarchy.custom {
* applyHierarchyTemplate {
* sourceSetTrees(SourceSetTree.main) // ! <- only applied to the "main" tree
* common {
* withJvm()
@@ -55,7 +53,7 @@ interface KotlinTargetHierarchyBuilder {
* }
* }
*
* targetHierarchy.custom {
* applyHierarchyTemplate {
* sourceSetTrees(SourceSetTree.test) // ! <- only applied to the "test" tree
* common {
* withJvm()
@@ -78,19 +76,19 @@ interface KotlinTargetHierarchyBuilder {
* iosX64Main iosArm64Main
* ```
*/
fun sourceSetTrees(vararg tree: KotlinTargetHierarchy.SourceSetTree)
fun sourceSetTrees(vararg tree: KotlinSourceSetTree)
/**
* Will add the given [tree]s into for this descriptor.
* @see sourceSetTrees
*/
fun withSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree)
fun withSourceSetTree(vararg tree: KotlinSourceSetTree)
/**
* Will remove the given [tree]s from this descriptor
* @see sourceSetTrees
*/
fun excludeSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree)
fun excludeSourceSetTree(vararg tree: KotlinSourceSetTree)
}
/* Declaring groups */
@@ -112,8 +110,8 @@ interface KotlinTargetHierarchyBuilder {
* depend on the usual 'commonMain'
*
*/
fun common(build: KotlinTargetHierarchyBuilder.() -> Unit) = group("common", build)
fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit = {})
fun common(build: KotlinHierarchyBuilder.() -> Unit) = group("common", build)
fun group(name: String, build: KotlinHierarchyBuilder.() -> Unit = {})
/* low-level APIs */
fun withCompilations(predicate: (KotlinCompilation<*>) -> Boolean)
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.plugin
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
sealed interface KotlinHierarchyTemplate {
companion object Templates
}
/*
EXPERIMENTAL API
*/
@ExperimentalKotlinGradlePluginApi
fun KotlinHierarchyTemplate(
describe: KotlinHierarchyBuilder.Root.() -> Unit
): KotlinHierarchyTemplate {
return KotlinHierarchyTemplateImpl(describe)
}
@ExperimentalKotlinGradlePluginApi
fun KotlinHierarchyTemplate.extend(describe: KotlinHierarchyBuilder.Root.() -> Unit): KotlinHierarchyTemplate {
return KotlinHierarchyTemplate {
this@extend.internal.layout(this)
describe()
}
}
/*
INTERNAL API
*/
@InternalKotlinGradlePluginApi
@OptIn(ExperimentalKotlinGradlePluginApi::class)
fun KotlinHierarchyBuilder.Root.applyHierarchyTemplate(template: KotlinHierarchyTemplate) {
template.internal.layout(this)
}
internal val KotlinHierarchyTemplate.internal
get() = when (this) {
is InternalKotlinHierarchyTemplate -> this
}
@OptIn(ExperimentalKotlinGradlePluginApi::class)
internal interface InternalKotlinHierarchyTemplate : KotlinHierarchyTemplate {
fun layout(builder: KotlinHierarchyBuilder.Root)
}
@OptIn(ExperimentalKotlinGradlePluginApi::class)
internal class KotlinHierarchyTemplateImpl(
private val describe: KotlinHierarchyBuilder.Root.() -> Unit
) : InternalKotlinHierarchyTemplate {
override fun layout(builder: KotlinHierarchyBuilder.Root) {
describe(builder)
}
}
@@ -0,0 +1,231 @@
/*
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.plugin
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree.Companion.instrumentedTest
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree.Companion.integrationTest
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree.Companion.main
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree.Companion.test
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree.Companion.unitTest
import org.jetbrains.kotlin.tooling.core.Interner
/**
* When applying any [KotlinHierarchyTemplate] (e.g. by calling `applyDefaultHierarchyTemplate()`), the descriptor will
* be applied on individual compilations, creating multiple trees of shared SourceSets.
*
* The name of given shared source set within the target hierarchy will be built by
* `lowerCamelCase(nameOfGroup, nameOfSourceSetTree)`
* So for the 'common' group within the 'main' tree the shared SourceSet name will be 'commonMain'
*
* The most default case will create two well known SourceSetTrees:
* - The `main` tree with `commonMain` as its root SourceSet
* - The `test` tree with `commonTest` as its root SourceSet
*
* e.g.
* ```kotlin
* kotlin {
* applyDefaultHierarchyTemplate()
* jvm()
* iosX64()
* iosArm64()
* }
* ```
*
* will create two SourceSetTrees: "main" and "test"
* ```
* "main" "test"
*
* commonMain commonTest
* | |
* | |
* +----------+----------+ +----------+----------+
* | | | |
* ... jvmMain ... jvmTest
* | |
* | |
* iosMain iosTest
* | |
* +----+-----+ +----+-----+
* | | | |
* iosX64Main iosArm64Main iosX64Test iosArm64Test
* ```
*
*
* Usually, the name of the compilation correlates to the name of the SourceSetTree:
* As seen in the previous example, the "main" tree under the "commonMain" root contains all 'main' compilations of the projects
* targets. The "test" tree under the "commonTest" root contains all 'test' compilations of the projects targets.
*
* There are some exceptions, where the name of the compilations cannot be chosen by the user directly (Android)
* In this case, the name of the SourceSet can be configured outside the target hierarchy DSL.
*/
sealed interface KotlinSourceSetTree {
val name: String
companion object {
/**
* The 'main' SourceSetTree. Typically, with 'commonMain' as the root SourceSet
*/
val main: KotlinSourceSetTree = KotlinSourceSetTreeImpl("main")
/**
* The 'test' SourceSetTree. Typically, with 'commonTest' as the root SourceSet
*/
val test: KotlinSourceSetTree = KotlinSourceSetTreeImpl("test")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonUnitTest' as the root SourceSet
* e.g. relevant for organising Android unitTest compilations/SourceSets
*/
val unitTest: KotlinSourceSetTree = KotlinSourceSetTreeImpl("unitTest")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonInstrumentedTest' as the root SourceSet
* e.g. relevant for organising Android instrumented compilations/SourceSets
*/
val instrumentedTest: KotlinSourceSetTree = KotlinSourceSetTreeImpl("instrumentedTest")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonIntegrationTest' as root SourceSEt
*/
val integrationTest: KotlinSourceSetTree = KotlinSourceSetTreeImpl("integrationTest")
}
}
fun KotlinSourceSetTree(name: String): KotlinSourceSetTree {
return when (name) {
main.name -> main
test.name -> test
unitTest.name -> unitTest
instrumentedTest.name -> instrumentedTest
integrationTest.name -> integrationTest
else -> KotlinSourceSetTreeImpl(name)
}
}
/*
Implementation
*/
private class KotlinSourceSetTreeImpl(override val name: String) : KotlinSourceSetTree {
override fun toString(): String = name
override fun equals(other: Any?): Boolean {
if (other !is KotlinSourceSetTree) return false
return this.name == other.name
}
override fun hashCode(): Int {
return name.hashCode()
}
}
/*
Deprecated APIs
*/
@Deprecated("Use KotlinSourceSetTree instead")
interface KotlinTargetHierarchy {
/**
* When applying any [KotlinTargetHierarchyDescriptor] (e.g. by calling `applyDefaultHierarchyTemplate()`), the descriptor will
* be applied on individual compilations, creating multiple trees of shared SourceSets.
*
* The name of given shared source set within the target hierarchy will be built by
* `lowerCamelCase(nameOfGroup, nameOfSourceSetTree)`
* So for the 'common' group within the 'main' tree the shared SourceSet name will be 'commonMain'
*
* The most default case will create two well known SourceSetTrees:
* - The `main` tree with `commonMain` as its root SourceSet
* - The `test` tree with `commonTest` as its root SourceSet
*
* e.g.
* ```kotlin
* kotlin {
* applyDefaultHierarchyTemplate()
* jvm()
* iosX64()
* iosArm64()
* }
* ```
*
* will create two SourceSetTrees: "main" and "test"
* ```
* "main" "test"
*
* commonMain commonTest
* | |
* | |
* +----------+----------+ +----------+----------+
* | | | |
* ... jvmMain ... jvmTest
* | |
* | |
* iosMain iosTest
* | |
* +----+-----+ +----+-----+
* | | | |
* iosX64Main iosArm64Main iosX64Test iosArm64Test
* ```
*
*
* Usually, the name of the compilation correlates to the name of the SourceSetTree:
* As seen in the previous example, the "main" tree under the "commonMain" root contains all 'main' compilations of the projects
* targets. The "test" tree under the "commonTest" root contains all 'test' compilations of the projects targets.
*
* There are some exceptions, where the name of the compilations cannot be chosen by the user directly (Android)
* In this case, the name of the SourceSet can be configured outside the target hierarchy DSL.
*/
@Deprecated("Use KotlinSourceSetTree instead", replaceWith = ReplaceWith("KotlinSourceSetTree"))
class SourceSetTree(override val name: String) : KotlinSourceSetTree {
override fun toString(): String = name
override fun equals(other: Any?): Boolean {
if (other !is KotlinSourceSetTree) return false
return this.name == other.name
}
override fun hashCode(): Int {
return name.hashCode()
}
@Suppress("DEPRECATION")
companion object {
/**
* The 'main' SourceSetTree. Typically, with 'commonMain' as the root SourceSet
*/
val main = SourceSetTree("main")
/**
* The 'test' SourceSetTree. Typically, with 'commonTest' as the root SourceSet
*/
val test = SourceSetTree("test")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonUnitTest' as the root SourceSet
* e.g. relevant for organising Android unitTest compilations/SourceSets
*/
val unitTest = SourceSetTree("unitTest")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonInstrumentedTest' as the root SourceSet
* e.g. relevant for organising Android instrumented compilations/SourceSets
*/
val instrumentedTest = SourceSetTree("instrumentedTest")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonIntegrationTest' as root SourceSEt
*/
val integrationTest = SourceSetTree("integrationTest")
}
}
}
@@ -1,102 +0,0 @@
/*
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.plugin
interface KotlinTargetHierarchy {
/**
* When applying any [KotlinTargetHierarchyDescriptor] (e.g. by calling `targetHierarchy.default()`), the descriptor will
* be applied on individual compilations, creating multiple trees of shared SourceSets.
*
* The name of given shared source set within the target hierarchy will be built by
* `lowerCamelCase(nameOfGroup, nameOfSourceSetTree)`
* So for the 'common' group within the 'main' tree the shared SourceSet name will be 'commonMain'
*
* The most default case will create two well known SourceSetTrees:
* - The `main` tree with `commonMain` as its root SourceSet
* - The `test` tree with `commonTest` as its root SourceSet
*
* e.g.
* ```kotlin
* kotlin {
* targetHierarchy.default()
* jvm()
* iosX64()
* iosArm64()
* }
* ```
*
* will create two SourceSetTrees: "main" and "test"
* ```
* "main" "test"
*
* commonMain commonTest
* | |
* | |
* +----------+----------+ +----------+----------+
* | | | |
* ... jvmMain ... jvmTest
* | |
* | |
* iosMain iosTest
* | |
* +----+-----+ +----+-----+
* | | | |
* iosX64Main iosArm64Main iosX64Test iosArm64Test
* ```
*
*
* Usually, the name of the compilation correlates to the name of the SourceSetTree:
* As seen in the previous example, the "main" tree under the "commonMain" root contains all 'main' compilations of the projects
* targets. The "test" tree under the "commonTest" root contains all 'test' compilations of the projects targets.
*
* There are some exceptions, where the name of the compilations cannot be chosen by the user directly (Android)
* In this case, the name of the SourceSet can be configured outside the target hierarchy DSL.
*/
class SourceSetTree(val name: String) {
override fun toString(): String = name
override fun equals(other: Any?): Boolean {
if (other !is SourceSetTree) return false
return this.name == other.name
}
override fun hashCode(): Int {
return name.hashCode()
}
companion object {
/**
* The 'main' SourceSetTree. Typically, with 'commonMain' as the root SourceSet
*/
val main = SourceSetTree("main")
/**
* The 'test' SourceSetTree. Typically, with 'commonTest' as the root SourceSet
*/
val test = SourceSetTree("test")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonUnitTest' as the root SourceSet
* e.g. relevant for organising Android unitTest compilations/SourceSets
*/
val unitTest = SourceSetTree("unitTest")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonInstrumentedTest' as the root SourceSet
* e.g. relevant for organising Android instrumented compilations/SourceSets
*/
val instrumentedTest = SourceSetTree("instrumentedTest")
/**
* Special pre-defined SourceSetTree: Can be used to introduce a new tree with 'commonIntegrationTest' as root SourceSEt
*/
val integrationTest = SourceSetTree("integrationTest")
}
}
}
@@ -1,37 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.gradle.plugin
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
@ExperimentalKotlinGradlePluginApi
interface KotlinTargetHierarchyDescriptor {
fun describe(builder: KotlinTargetHierarchyBuilder.Root)
fun extend(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit): KotlinTargetHierarchyDescriptor
}
@ExperimentalKotlinGradlePluginApi
fun KotlinTargetHierarchyDescriptor(
describe: KotlinTargetHierarchyBuilder.Root.() -> Unit
): KotlinTargetHierarchyDescriptor {
return KotlinTargetHierarchyDescriptorImpl(describe)
}
@ExperimentalKotlinGradlePluginApi
private class KotlinTargetHierarchyDescriptorImpl(
private val describe: KotlinTargetHierarchyBuilder.Root.() -> Unit
) : KotlinTargetHierarchyDescriptor {
override fun extend(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit): KotlinTargetHierarchyDescriptor {
val sourceDescribe = this.describe
return KotlinTargetHierarchyDescriptor {
sourceDescribe()
describe()
}
}
override fun describe(builder: KotlinTargetHierarchyBuilder.Root) = builder.describe()
}
@@ -16,7 +16,7 @@ kotlin {
linuxArm64()
linuxX64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies {
implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT")
@@ -20,7 +20,7 @@ kotlin {
linuxX64()
linuxArm64()
targetHierarchy.custom {
applyHierarchyTemplate {
group("nativeCommon") {
withNative()
}
@@ -10,7 +10,7 @@ kotlin {
macosX64()
macosArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
targets.withType<KotlinNativeTarget>().all {
compilations.getByName("main").cinterops.create("libapp") {
@@ -9,7 +9,7 @@ kotlin {
macosX64()
macosArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
/* first cinterop commonizer group */
listOf(macosX64(), macosArm64()).forEach { target ->
@@ -1,6 +1,7 @@
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
plugins {
kotlin("multiplatform")
@@ -8,7 +9,7 @@ plugins {
kotlin {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
targetHierarchy.default {
applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common {
group("concurrent") {
withJvm()
@@ -12,7 +12,7 @@ repositories {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
linuxArm64()
@@ -21,7 +21,7 @@ fun KotlinNativeTarget.cinterop(name: String = "a") {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
@@ -20,7 +20,7 @@ fun KotlinNativeTarget.cinterop(name: String = "a") {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
@@ -14,7 +14,7 @@ repositories {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
linuxX64()
macosX64()
macosArm64()
@@ -10,7 +10,7 @@ repositories {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
@@ -20,7 +20,7 @@ kotlin {
jvm()
linuxX64()
linuxArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
}
dependencies {
@@ -19,7 +19,7 @@ kotlin {
jvm()
linuxX64()
linuxArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies {
api(project(":p1"))
@@ -12,6 +12,6 @@ kotlin {
linuxX64()
linuxArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
}
@@ -16,7 +16,7 @@ repositories {
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm {}
linuxX64 {}
linuxArm64 {}
@@ -5,7 +5,7 @@ plugins {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
linuxArm64()
@@ -10,7 +10,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT"
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
linuxArm64()
@@ -5,7 +5,7 @@ plugins {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
iosX64()
iosArm64()
@@ -10,7 +10,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT"
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
iosX64()
iosArm64()
@@ -5,7 +5,7 @@ plugins {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
linuxArm64()
@@ -12,7 +12,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT"
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
linuxArm64()
@@ -5,7 +5,7 @@ plugins {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
linuxArm64()
@@ -10,7 +10,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT"
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
linuxArm64()
@@ -11,7 +11,7 @@ kotlin {
jvm()
linuxX64()
linuxArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies {
implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT")
@@ -12,7 +12,7 @@ kotlin {
jvm()
linuxX64()
linuxArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies {
implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT")
@@ -21,7 +21,7 @@ kotlin {
jvm()
linuxX64()
linuxArm64()
targetHierarchy.default()
applyDefaultHierarchyTemplate()
}
group = "org.jetbrains.sample"
@@ -8,7 +8,7 @@ repositories {
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
@@ -7,7 +7,7 @@ group = "test"
version = "1.0"
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
@@ -11,7 +11,7 @@ repositories {
}
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
jvm()
linuxX64()
@@ -1,3 +1,44 @@
public abstract interface class org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier {
}
public final class org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Default : org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier {
public static final field INSTANCE Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Default;
public fun toString ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Name : org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier {
public fun <init> (Ljava/lang/String;)V
public final fun component1 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;)Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Name;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Name;Ljava/lang/String;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Name;
public fun equals (Ljava/lang/Object;)Z
public final fun getName ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$None : org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier {
public static final field INSTANCE Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$None;
public fun toString ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Property : org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier {
public fun <init> (Lorg/gradle/api/provider/Property;)V
public final fun getProperty ()Lorg/gradle/api/provider/Property;
public fun toString ()Ljava/lang/String;
}
public final class org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Value : org/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier {
public fun <init> (Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;)V
public final fun component1 ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
public final fun copy (Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;)Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Value;
public static synthetic fun copy$default (Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Value;Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;ILjava/lang/Object;)Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier$Value;
public fun equals (Ljava/lang/Object;)Z
public final fun getTree ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSetTree;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/ide/IdeAdditionalArtifactResolver {
public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeAdditionalArtifactResolver$Companion;
public abstract fun resolve (Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSet;Ljava/util/Set;)V
@@ -234,6 +275,7 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/external/
public abstract fun getDefaultSourceSet ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSet;
public abstract fun getFriendArtifactResolver ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$FriendArtifactResolver;
public abstract fun getSourceSetTreeClassifier ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier;
public abstract fun getSourceSetTreeClassifierV2 ()Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier;
}
public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$CompilationAssociator {
@@ -258,6 +300,7 @@ public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotli
public final fun getDefaultSourceSet ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSet;
public final fun getFriendArtifactResolver ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$FriendArtifactResolver;
public final fun getSourceSetTreeClassifier ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier;
public final fun getSourceSetTreeClassifierV2 ()Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier;
public final fun setCompilationAssociator (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$CompilationAssociator;)V
public final fun setCompilationFactory (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$CompilationFactory;)V
public final fun setCompilationName (Ljava/lang/String;)V
@@ -266,6 +309,7 @@ public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotli
public final fun setDefaultSourceSet (Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSet;)V
public final fun setFriendArtifactResolver (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$FriendArtifactResolver;)V
public final fun setSourceSetTreeClassifier (Lorg/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier;)V
public final fun setSourceSetTreeClassifierV2 (Lorg/jetbrains/kotlin/gradle/plugin/hierarchy/KotlinSourceSetTreeClassifier;)V
}
public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptorKt {
@@ -10,8 +10,9 @@ import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinHierarchyDslImpl
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyDslImpl
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import javax.inject.Inject
abstract class KotlinMultiplatformExtension(project: Project) :
@@ -19,7 +20,8 @@ abstract class KotlinMultiplatformExtension(project: Project) :
KotlinTargetContainerWithPresetFunctions,
KotlinTargetContainerWithJsPresetFunctions,
KotlinTargetContainerWithWasmPresetFunctions,
KotlinTargetContainerWithNativeShortcuts {
KotlinTargetContainerWithNativeShortcuts,
KotlinHierarchyDsl {
override val presets: NamedDomainObjectCollection<KotlinTargetPreset<*>> = project.container(KotlinTargetPreset::class.java)
final override val targets: NamedDomainObjectCollection<KotlinTarget> = project.container(KotlinTarget::class.java)
@@ -45,12 +47,189 @@ abstract class KotlinMultiplatformExtension(project: Project) :
configure(presetExtension)
}
internal val internalKotlinTargetHierarchy by lazy {
KotlinTargetHierarchyDslImpl(targets, sourceSets)
internal val hierarchy by lazy { KotlinHierarchyDslImpl(targets, sourceSets) }
/**
* Set's up a 'natural'/'default' hierarchy withing [KotlinTarget]'s in the project.
*
* #### Example
*
* ```kotlin
* kotlin {
* applyDefaultHierarchyTemplate() // <- position of this call is not relevant!
*
* iosX64()
* iosArm64()
* linuxX64()
* linuxArm64()
* }
* ```
*
* Will create the following SourceSets:
* `[iosMain, iosTest, appleMain, appleTest, linuxMain, linuxTest, nativeMain, nativeTest]
*
*
* Hierarchy:
* ```
* common
* |
* +-----------------+-------------------+
* | |
*
* native ...
*
* |
* |
* |
* +----------------------+--------------------+-----------------------+
* | | | |
*
* apple linux mingw androidNative
*
* |
* +-----------+------------+------------+
* | | | |
*
* macos ios tvos watchos
* ```
*
* @see KotlinHierarchyTemplate.extend
*/
fun applyDefaultHierarchyTemplate() = applyHierarchyTemplate(KotlinHierarchyTemplate.default)
/**
* Will apply the given [template] to the project.
*
* ### Example: Manually apply the default hierarchy (see [applyDefaultHierarchyTemplate])
* ```kotlin
* kotlin {
* applyHierarchyTemplate(KotlinHierarchyTemplate.default)
* iosX64()
* iosArm64()
* iosSimulatorArm64()
* linuxX64()
* // ...
* }
* ```
*/
@ExperimentalKotlinGradlePluginApi
override fun applyHierarchyTemplate(template: KotlinHierarchyTemplate) {
hierarchy.applyHierarchyTemplate(template)
}
/**
* Similar to [applyDefaultHierarchyTemplate], but allows to extend the provided template
*
* #### Example 2: Adding custom groups (Experimental)
* Let's imagine we would additionally like to share code between linux and apple (unixLike)
*
* ```kotlin
* kotlin {
* applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
* group("native") { // <- we can re-declare already existing groups and connect children to it!
* group("unixLike") {
* withLinux()
* withApple()
* }
* }
* }
* }
* ```
*/
@ExperimentalKotlinGradlePluginApi
val targetHierarchy: KotlinTargetHierarchyDsl get() = internalKotlinTargetHierarchy
override fun applyHierarchyTemplate(template: KotlinHierarchyTemplate, extension: KotlinHierarchyBuilder.Root.() -> Unit) {
hierarchy.applyHierarchyTemplate(template, extension)
}
/**
* Allows to create a fully custom hierarchy (no defaults applied)
* Note: Using the custom hierarchy will also require to set the edges to 'commonMain' and 'commonTest' SourceSets by
* using the `common` group.
*
* #### Example 1:
* Sharing code between iOS and a jvmTarget:
* ```kotlin
* applyHierarchyTemplate {
* common {
* withJvm()
* group("ios") {
* withIos()
* }
* }
* }
* ```
*
* Will create two [KotlinSourceSetTree] using the 'common' and 'ios' groups, applied on the "test" and "main" compilations:
* When the following targets are specified:
* - jvm()
* - iosX64()
* - iosArm64()
* ```
* "main" "test"
* commonMain commonTest
* | |
* | |
* +----------+----------+ +----------+----------+
* | | | |
* iosMain jvmMain iosTest jvmTest
* | |
* +----+-----+ +----+-----+
* | | | |
* iosX64Main iosArm64Main iosX64Test iosArm64Test
* ```
*
* #### Example 2: Creating a 'diamond structure'
* ```kotlin
* applyHierarchyTemplate {
* common {
* group("ios") {
* withIos()
* }
*
* group("frontend") {
* withJvm()
* group("ios") // <- ! We can again reference the 'ios' group
* }
*
* group("apple") {
* withMacos()
* group("ios") // <- ! We can again reference the 'ios' group
* }
* }
* }
* ```
*
* In this case, the _group_ "ios" can be created with 'group("ios")' and later referenced with the same construction to build
* the tree. Applying the descriptor from the example to the following targets:
* - iosX64()
* - iosArm64()
* - macosX64()
* - jvm()
*
* will create the following 'main' KotlinSourceSetTree:
*
* ```
* commonMain
* |
* +------------+----------+
* | |
* frontendMain appleMain
* | |
* +---------+------------+-----------+----------+
* | | |
* jvmMain iosMain macosX64Main
* |
* |
* +----+----+
* | |
* iosX64Main iosArm64Main
* ```
*/
@ExperimentalKotlinGradlePluginApi
override fun applyHierarchyTemplate(template: KotlinHierarchyBuilder.Root.() -> Unit) {
hierarchy.applyHierarchyTemplate(template)
}
@Suppress("unused") // DSL
val testableTargets: NamedDomainObjectCollection<KotlinTargetWithTests<*, *>>
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.KotlinSourceSetDependsOnDefaultCompilationSourceSet
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.KotlinSourceSetTreeDependsOnMismatch
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.hierarchy.orNull
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.orNull
import org.jetbrains.kotlin.gradle.plugin.sources.awaitPlatformCompilations
import org.jetbrains.kotlin.gradle.plugin.sources.internal
@@ -22,14 +22,14 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
val sourceSets = this.multiplatformExtension?.awaitSourceSets() ?: return
// A "good" source set is part of only single Source Set Tree
val goodSourceSets = mutableMapOf<KotlinSourceSet, SourceSetTree?>()
val goodSourceSets = mutableMapOf<KotlinSourceSet, KotlinSourceSetTree?>()
// A "bad" source set is part of >=2 Source Set Trees
val badSourceSets = mutableMapOf<KotlinSourceSet, Set<SourceSetTree?>>()
val badSourceSets = mutableMapOf<KotlinSourceSet, Set<KotlinSourceSetTree?>>()
// A "leaf" source set is a source set with known Source Set Tree by default
val leafSourceSets = multiplatformExtension
.awaitTargets()
.filter { it !is KotlinMetadataTarget }
.flatMap { target -> target.compilations.map { it.defaultSourceSet to SourceSetTree.orNull(it) } }
.flatMap { target -> target.compilations.map { it.defaultSourceSet to KotlinSourceSetTree.orNull(it) } }
.toMap()
val reverseSourceSetDependencies = mutableMapOf<KotlinSourceSet, MutableSet<KotlinSourceSet>>()
@@ -40,7 +40,7 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
sourceSet.dependsOn.forEach { it.addReverseDependencyTo(sourceSet) }
val platformCompilations = sourceSet.internal.awaitPlatformCompilations()
val distinctSourceSetTrees = platformCompilations.map { SourceSetTree.orNull(it) }.toSet()
val distinctSourceSetTrees = platformCompilations.map { KotlinSourceSetTree.orNull(it) }.toSet()
val totalDistinctSourceSetTrees = distinctSourceSetTrees.size
@@ -124,7 +124,7 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
private fun KotlinGradleProjectCheckerContext.reportSingleSourceSetWithDifferentSourceSetTree(
collector: KotlinToolingDiagnosticsCollector,
badSourceSet: KotlinSourceSet,
dependentsBySourceSetTree: Map<SourceSetTree?, List<KotlinSourceSet>>
dependentsBySourceSetTree: Map<KotlinSourceSetTree?, List<KotlinSourceSet>>
): Boolean {
val singleDependee = dependentsBySourceSetTree
.values
@@ -139,7 +139,7 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
private fun KotlinGradleProjectCheckerContext.reportAllIncorrectSourceSetEdges(
collector: KotlinToolingDiagnosticsCollector,
badSourceSet: KotlinSourceSet,
dependentsBySourceSetTree: Map<SourceSetTree?, List<KotlinSourceSet>>,
dependentsBySourceSetTree: Map<KotlinSourceSetTree?, List<KotlinSourceSet>>,
) {
val dependentsGroup = dependentsBySourceSetTree
.mapKeys { it.key?.name ?: "null" }
@@ -1,21 +1,21 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
package org.jetbrains.kotlin.gradle.plugin.hierarchy
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.tooling.core.withClosure
internal data class KotlinTargetHierarchyTree(
val node: Node, val children: Set<KotlinTargetHierarchyTree> = emptySet()
internal data class KotlinHierarchy(
val node: Node, val children: Set<KotlinHierarchy> = emptySet(),
) {
val childrenClosure: Set<KotlinTargetHierarchyTree> =
children.withClosure<KotlinTargetHierarchyTree> { it.children }
val childrenClosure: Set<KotlinHierarchy> =
children.withClosure<KotlinHierarchy> { it.children }
sealed class Node {
abstract suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String?
@@ -26,7 +26,7 @@ internal data class KotlinTargetHierarchyTree(
data class Group(val name: String) : Node() {
override suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String? {
val sourceSetTree = KotlinTargetHierarchy.SourceSetTree.orNull(compilation)?.name ?: return null
val sourceSetTree = KotlinSourceSetTree.orNull(compilation)?.name ?: return null
return lowerCamelCaseName(name, sourceSetTree)
}
}
@@ -1,38 +1,37 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
package org.jetbrains.kotlin.gradle.plugin.hierarchy
import org.gradle.api.InvalidUserCodeException
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.konan.target.DEPRECATED_TARGET_MESSAGE
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.tooling.core.closure
internal suspend fun KotlinTargetHierarchyDescriptor.buildKotlinTargetHierarchy(compilation: KotlinCompilation<*>): KotlinTargetHierarchyTree? {
val context = KotlinTargetHierarchyBuilderImplContext(compilation)
describe(context.root)
return context.build(KotlinTargetHierarchyTree.Node.Root)
internal suspend fun KotlinHierarchyTemplate.buildHierarchy(compilation: KotlinCompilation<*>): KotlinHierarchy? {
val context = KotlinHierarchyBuilderImplContext(compilation)
context.root.applyHierarchyTemplate(this)
return context.build(KotlinHierarchy.Node.Root)
}
private class KotlinTargetHierarchyBuilderImplContext(private val compilation: KotlinCompilation<*>) {
val root by lazy { KotlinTargetHierarchyBuilderRootImpl(getOrCreateBuilder(KotlinTargetHierarchyTree.Node.Root)) }
private class KotlinHierarchyBuilderImplContext(private val compilation: KotlinCompilation<*>) {
val root by lazy { KotlinHierarchyBuilderRootImpl(getOrCreateBuilder(KotlinHierarchy.Node.Root)) }
private val builders = hashMapOf<KotlinTargetHierarchyTree.Node, KotlinTargetHierarchyBuilderImpl>()
private val builtValues = hashMapOf<KotlinTargetHierarchyTree.Node, KotlinTargetHierarchyTree?>()
private val builders = hashMapOf<KotlinHierarchy.Node, KotlinHierarchyBuilderImpl>()
private val builtValues = hashMapOf<KotlinHierarchy.Node, KotlinHierarchy?>()
fun getOrCreateBuilder(node: KotlinTargetHierarchyTree.Node): KotlinTargetHierarchyBuilderImpl = builders.getOrPut(node) {
KotlinTargetHierarchyBuilderImpl(this, node)
fun getOrCreateBuilder(node: KotlinHierarchy.Node): KotlinHierarchyBuilderImpl = builders.getOrPut(node) {
KotlinHierarchyBuilderImpl(this, node)
}
suspend fun build(node: KotlinTargetHierarchyTree.Node): KotlinTargetHierarchyTree? {
suspend fun build(node: KotlinHierarchy.Node): KotlinHierarchy? {
return builtValues.getOrPut(node) {
val builder = getOrCreateBuilder(node)
if (!builder.contains(compilation)) return@getOrPut null
@@ -50,25 +49,25 @@ private class KotlinTargetHierarchyBuilderImplContext(private val compilation: K
*/
val children = builder.children.mapNotNull { child -> build(child.node) }
val directChildren = children.toSet() - children.flatMap { child -> child.childrenClosure }.toSet()
KotlinTargetHierarchyTree(node, directChildren)
KotlinHierarchy(node, directChildren)
}
}
}
private class KotlinTargetHierarchyBuilderRootImpl(
private val builder: KotlinTargetHierarchyBuilderImpl,
) : KotlinTargetHierarchyBuilder.Root, KotlinTargetHierarchyBuilder by builder {
private class KotlinHierarchyBuilderRootImpl(
private val builder: KotlinHierarchyBuilderImpl,
) : KotlinHierarchyBuilder.Root, KotlinHierarchyBuilder by builder {
override fun sourceSetTrees(vararg tree: KotlinTargetHierarchy.SourceSetTree) {
override fun sourceSetTrees(vararg tree: KotlinSourceSetTree) {
builder.sourceSetTrees = tree.toHashSet()
}
override fun withSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree) {
override fun withSourceSetTree(vararg tree: KotlinSourceSetTree) {
builder.sourceSetTrees = builder.sourceSetTrees.orEmpty().plus(tree)
}
override fun excludeSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree) {
override fun excludeSourceSetTree(vararg tree:KotlinSourceSetTree) {
val modules = tree.toHashSet()
if (modules.isEmpty()) return
builder.sourceSetTrees = builder.sourceSetTrees.orEmpty() - modules
@@ -76,15 +75,15 @@ private class KotlinTargetHierarchyBuilderRootImpl(
}
private class KotlinTargetHierarchyBuilderImpl(
val context: KotlinTargetHierarchyBuilderImplContext,
val node: KotlinTargetHierarchyTree.Node,
) : KotlinTargetHierarchyBuilder {
private class KotlinHierarchyBuilderImpl(
val context: KotlinHierarchyBuilderImplContext,
val node: KotlinHierarchy.Node,
) : KotlinHierarchyBuilder {
val children = mutableSetOf<KotlinTargetHierarchyBuilderImpl>()
val children = mutableSetOf<KotlinHierarchyBuilderImpl>()
val childrenClosure get() = closure { it.children }
var sourceSetTrees: Set<KotlinTargetHierarchy.SourceSetTree>? = null
var sourceSetTrees: Set<KotlinSourceSetTree>? = null
private var includePredicate: ((KotlinCompilation<*>) -> Boolean) = { false }
private var excludePredicate: ((KotlinCompilation<*>) -> Boolean) = { false }
@@ -105,7 +104,7 @@ private class KotlinTargetHierarchyBuilderImpl(
suspend fun contains(compilation: KotlinCompilation<*>): Boolean {
sourceSetTrees?.let { sourceSetTrees ->
val sourceSetTree = KotlinTargetHierarchy.SourceSetTree.orNull(compilation) ?: return false
val sourceSetTree = KotlinSourceSetTree.orNull(compilation) ?: return false
if (sourceSetTree !in sourceSetTrees) return false
}
@@ -121,8 +120,8 @@ private class KotlinTargetHierarchyBuilderImpl(
private inline fun withTargets(crossinline predicate: (KotlinTarget) -> Boolean) = withCompilations { predicate(it.target) }
override fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit) {
val node = KotlinTargetHierarchyTree.Node.Group(name)
override fun group(name: String, build: KotlinHierarchyBuilder.() -> Unit) {
val node = KotlinHierarchy.Node.Group(name)
val child = context.getOrCreateBuilder(node).also(build)
children.add(child)
checkCyclicHierarchy()
@@ -281,20 +280,20 @@ private class KotlinTargetHierarchyBuilderImpl(
}
override fun toString(): String {
return "KotlinTargetHierarchyBuilder($node)"
return "KotlinHierarchyBuilder($node)"
}
}
/* Cycle Detection: Provide feedback for users when a KotlinTargetHierarchy cycle is declared */
/* Cycle Detection: Provide feedback for users when a KotlinHierarchy cycle is declared */
private fun KotlinTargetHierarchyBuilderImpl.checkCyclicHierarchy(): Nothing? {
private fun KotlinHierarchyBuilderImpl.checkCyclicHierarchy(): Nothing? {
val stack = mutableListOf(node)
val visited = hashSetOf<KotlinTargetHierarchyBuilderImpl>()
val visited = hashSetOf<KotlinHierarchyBuilderImpl>()
fun checkChild(child: KotlinTargetHierarchyBuilderImpl) {
fun checkChild(child: KotlinHierarchyBuilderImpl) {
if (!visited.add(child)) return
stack += child.node
if (this == child) throw CyclicKotlinTargetHierarchyException(stack)
if (this == child) throw CyclicKotlinHierarchyException(stack)
child.children.forEach { next -> checkChild(next) }
stack -= child.node
}
@@ -303,6 +302,6 @@ private fun KotlinTargetHierarchyBuilderImpl.checkCyclicHierarchy(): Nothing? {
return null
}
internal class CyclicKotlinTargetHierarchyException(val cycle: List<KotlinTargetHierarchyTree.Node>) : InvalidUserCodeException(
"KotlinTargetHierarchy cycle detected: ${cycle.joinToString(" -> ")}"
internal class CyclicKotlinHierarchyException(val cycle: List<KotlinHierarchy.Node>) : InvalidUserCodeException(
"KotlinHierarchy cycle detected: ${cycle.joinToString(" -> ")}"
)
@@ -0,0 +1,79 @@
/*
* Copyright 2010-2023 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("DuplicatedCode")
package org.jetbrains.kotlin.gradle.plugin.hierarchy
import org.gradle.api.DomainObjectCollection
import org.gradle.api.NamedDomainObjectContainer
import org.jetbrains.kotlin.gradle.dsl.KotlinHierarchyDsl
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.FinaliseRefinesEdges
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
internal class KotlinHierarchyDslImpl(
private val targets: DomainObjectCollection<KotlinTarget>,
private val sourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
) : KotlinHierarchyDsl {
private val appliedTemplatesImpl = mutableSetOf<KotlinHierarchyTemplate>()
val appliedTemplates get() = appliedTemplatesImpl.toSet()
override fun applyHierarchyTemplate(template: KotlinHierarchyTemplate) {
if (!appliedTemplatesImpl.add(template)) return
applyHierarchyTemplateToAllCompilations(template)
}
override fun applyHierarchyTemplate(template: KotlinHierarchyBuilder.Root.() -> Unit) {
applyHierarchyTemplate(KotlinHierarchyTemplate(template))
}
override fun applyHierarchyTemplate(template: KotlinHierarchyTemplate, extension: KotlinHierarchyBuilder.Root.() -> Unit) {
applyHierarchyTemplate(template.extend(extension))
}
/* Implementation */
private fun applyHierarchyTemplateToAllCompilations(template: KotlinHierarchyTemplate) {
targets.matching { target -> target.platformType != KotlinPlatformType.common }.all { target ->
target.compilations.all { compilation ->
target.project.kotlinPluginLifecycle.launch {
withRestrictedStages(KotlinPluginLifecycle.Stage.upTo(FinaliseRefinesEdges)) {
val hierarchy = template.buildHierarchy(compilation) ?: return@withRestrictedStages
applyKotlinHierarchy(hierarchy, compilation)
}
}
}
}
}
private suspend fun applyKotlinHierarchy(hierarchy: KotlinHierarchy, compilation: KotlinCompilation<*>): KotlinSourceSet? {
val sharedSourceSet = createSharedSourceSetOrNull(hierarchy.node, compilation)
val childSourceSets =
hierarchy.children.mapNotNull { childHierarchy -> applyKotlinHierarchy(childHierarchy, compilation) }
if (sharedSourceSet == null) return null
if (hierarchy.children.isNotEmpty()) {
childSourceSets.forEach { childSourceSet -> childSourceSet.dependsOn(sharedSourceSet) }
} else {
compilation.internal.kotlinSourceSets.forAll { compilationSourceSet ->
compilationSourceSet.dependsOn(sharedSourceSet)
}
}
return sharedSourceSet
}
private suspend fun createSharedSourceSetOrNull(
node: KotlinHierarchy.Node, compilation: KotlinCompilation<*>,
): KotlinSourceSet? {
val sharedSourceSetName = node.sharedSourceSetName(compilation) ?: return null
return sourceSets.maybeCreate(sharedSourceSetName)
}
}
@@ -0,0 +1,133 @@
/*
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.plugin.hierarchy
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilationFactory
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
/**
* Classifier providing the corresponding [KotlinSourceSetTree] associated with any given [KotlinCompilation]
*
* ### Example: Overwriting 'test' compilations [KotlinSourceSetTreeClassifier]:
* Consider the following setup:
* ```kotlin
* kotlin {
* val testCompilation = jvm().compilations.getByName("test")
* }
* ```
*
* In this example, we know that the 'jvm/test' compilation will have a 'jvmTest' SourceSet which
* will depend on 'commonTest' and therefore is part of the 'test' [KotlinSourceSetTree].
*
* When another [KotlinSourceSetTreeClassifier] is specified, this behaviour is changed.
* Using the External Kotlin Target API:
* ```kotlin
* myTarget.createCompilation {
* compilationName = "test"
* sourceSetTreeClassifier = SourceSetTreeClassifier.Name("unitTest")
* }
* ```
*
* This will create a compilation called 'test' which however will be considered part of the 'unitTest' SourceSetTree.
* The SourceSet of this 'jvm/test' compilation will still be called 'jvmTest' but since its part of the 'unitTest [KotlinSourceSetTree],
* there will not be a dependsOn edge to 'commonTest', but (if present) 'commonUnitTest'
*/
@ExternalKotlinTargetApi
sealed interface KotlinSourceSetTreeClassifier {
/**
* Default Classifier: The name of the compilation will be used to infer the [KotlinSourceSetTree]:
* 'main' compilations will be part of [KotlinSourceSetTree.main]
* 'test' compilations will be part of [KotlinSourceSetTree.test]
* ...
*/
@ExternalKotlinTargetApi
object Default : KotlinSourceSetTreeClassifier {
override fun toString(): String = "Default"
}
/**
* Indicates that the given compilations is not part of any 'named' [KotlinSourceSetTree].
* No [KotlinHierarchyTemplate] will be applied nor default dependsOn edges shall be set.
*/
@ExternalKotlinTargetApi
object None : KotlinSourceSetTreeClassifier {
override fun toString(): String = "None"
}
/**
* Predefined [KotlinSourceSetTree] using the [tree] specified.
*/
@ExternalKotlinTargetApi
data class Value(val tree: KotlinSourceSetTree) : KotlinSourceSetTreeClassifier
/**
* Predefined [KotlinSourceSetTree] using the [name] specified
*/
@ExternalKotlinTargetApi
data class Name(val name: String) : KotlinSourceSetTreeClassifier
/**
* Wrapper around [org.gradle.api.provider.Property] of a given [KotlinSourceSetTree] in order to
* make the [KotlinSourceSetTree] configurable.
*/
@ExternalKotlinTargetApi
class Property(val property: org.gradle.api.provider.Property<KotlinSourceSetTree>) : KotlinSourceSetTreeClassifier {
override fun toString(): String {
return property.toString()
}
}
}
/**
* To support old API (moved from .mpp.targetHierarchy to .hierarchy package)
*/
@Suppress("DEPRECATION")
internal class SourceSetTreeClassifierWrapper(
val classifier: org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.SourceSetTreeClassifier,
) : KotlinSourceSetTreeClassifier {
override fun toString(): String {
return classifier.toString()
}
}
internal suspend fun KotlinSourceSetTreeClassifier.classify(compilation: KotlinCompilation<*>): KotlinSourceSetTree? {
return when (this) {
is KotlinSourceSetTreeClassifier.Default -> KotlinSourceSetTree(compilation.name)
is KotlinSourceSetTreeClassifier.Property -> property.awaitFinalValue()
is KotlinSourceSetTreeClassifier.Value -> tree
is KotlinSourceSetTreeClassifier.Name -> KotlinSourceSetTree(name)
is KotlinSourceSetTreeClassifier.None -> null
is SourceSetTreeClassifierWrapper -> classifier.classify(compilation)
}
}
/**
* Returns the classifier configured for a given compilation.
* This is writable, as Android requires overwriting of this default behaviour.
*
* - The KGP maintained target will set the classifier within the [KotlinJvmAndroidCompilationFactory]
* - The external Android target will set this classifier within the 'createCompilation'
*
* It is therefore safe to access this value as soon as a compilation is provided
*/
internal var KotlinCompilation<*>.sourceSetTreeClassifier: KotlinSourceSetTreeClassifier by extrasLazyProperty {
KotlinSourceSetTreeClassifier.Default
}
/**
* Returns the [KotlinSourceSetTree] of a given [KotlinCompilation]:
* Uses the [sourceSetTreeClassifier] under the hood.
* See [KotlinSourceSetTreeClassifier]
*/
internal suspend fun KotlinSourceSetTree.Companion.orNull(compilation: KotlinCompilation<*>) =
compilation.sourceSetTreeClassifier.classify(compilation)
@@ -0,0 +1,105 @@
/*
* Copyright 2010-2023 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.
*/
package org.jetbrains.kotlin.gradle.plugin.hierarchy
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate.Templates
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
/**
* Set's up a 'natural'/'default' hierarchy within [KotlinTarget]'s, inside the project.
*
* #### Example 1
*
* ```kotlin
* kotlin {
* applyDefaultHierarchyTemplate() // <- position of this call is not relevant!
*
* iosX64()
* iosArm64()
* linuxX64()
* linuxArm64()
* }
* ```
*
* Will create the following SourceSets:
* `[iosMain, iosTest, appleMain, appleTest, linuxMain, linuxTest, nativeMain, nativeTest]
*
*
* Hierarchy:
* ```
* common
* |
* +-----------------+-------------------+
* | |
*
* native ...
*
* |
* |
* |
* +----------------------+--------------------+-----------------------+
* | | | |
*
* apple linux mingw androidNative
*
* |
* +-----------+------------+------------+
* | | | |
*
* macos ios tvos watchos
* ```
*/
val Templates.default get() = defaultKotlinHierarchyTemplate
private val defaultKotlinHierarchyTemplate = KotlinHierarchyTemplate {
/* natural hierarchy is only applied to default 'main'/'test' compilations (by default) */
withSourceSetTree(KotlinSourceSetTree.main, KotlinSourceSetTree.test)
common {
/* All compilations shall be added to the common group by default */
withCompilations { true }
group("native") {
withNative()
group("apple") {
withApple()
group("ios") {
withIos()
}
group("tvos") {
withTvos()
}
group("watchos") {
withWatchos()
}
group("macos") {
withMacos()
}
}
group("linux") {
withLinux()
}
group("mingw") {
withMingw()
}
group("androidNative") {
withAndroidNative()
}
}
}
}
@@ -19,14 +19,13 @@ import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.plugin.hierarchy.orNull
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport
import org.jetbrains.kotlin.gradle.plugin.ide.locateOrRegisterIdeResolveDependenciesTask
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin.Companion.sourceSetFreeCompilerArgsPropertyName
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.addBuildListenerForXcode
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.runDeprecationDiagnostics
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.orNull
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
import org.jetbrains.kotlin.gradle.plugin.sources.awaitPlatformCompilations
import org.jetbrains.kotlin.gradle.plugin.sources.checkSourceSetVisibilityRequirements
@@ -181,9 +180,10 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseRefinesEdges) {
/* Only setup default refines edges when no KotlinTargetHierarchy was applied */
if (project.multiplatformExtension.internalKotlinTargetHierarchy.appliedDescriptors.isNotEmpty()) return@launchInStage
if (project.multiplatformExtension.hierarchy.appliedTemplates.isNotEmpty()) return@launchInStage
target.compilations.forEach { compilation ->
val sourceSetTree = SourceSetTree.orNull(compilation) ?: return@forEach
val sourceSetTree = KotlinSourceSetTree.orNull(compilation) ?: return@forEach
val commonSourceSet = sourceSets.findByName(lowerCamelCaseName("common", sourceSetTree.name)) ?: return@forEach
compilation.defaultSourceSet.dependsOn(commonSourceSet)
}
@@ -330,7 +330,7 @@ internal fun Project.setupGeneralKotlinExtensionParameters() {
val isMainSourceSet = sourceSet
.internal
.awaitPlatformCompilations()
.any { SourceSetTree.orNull(it) == SourceSetTree.main }
.any { KotlinSourceSetTree.orNull(it) == KotlinSourceSetTree.main }
languageSettings.explicitApi = project.providers.provider {
val explicitApiFlag = project.kotlinExtension.explicitApiModeAsCompilerArg()
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.mpp.DecoratedKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.*
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.SourceSetTreeClassifier
@@ -55,7 +56,12 @@ interface ExternalKotlinCompilationDescriptor<T : DecoratedExternalKotlinCompila
val compilationFactory: CompilationFactory<T>
val friendArtifactResolver: FriendArtifactResolver<T>?
val compilationAssociator: CompilationAssociator<T>?
@Suppress("DEPRECATION")
@Deprecated("Use .sourceSetTreeClassifierV2 instead")
val sourceSetTreeClassifier: SourceSetTreeClassifier
val sourceSetTreeClassifierV2: KotlinSourceSetTreeClassifier?
val configure: ((T) -> Unit)?
}
@@ -73,6 +79,7 @@ fun <T : DecoratedExternalKotlinCompilation> ExternalKotlinCompilationDescriptor
friendArtifactResolver = friendArtifactResolver,
compilationAssociator = compilationAssociator,
sourceSetTreeClassifier = sourceSetTreeClassifier,
sourceSetTreeClassifierV2 = sourceSetTreeClassifierV2,
configure = this.configure
)
}
@@ -87,7 +94,12 @@ class ExternalKotlinCompilationDescriptorBuilder<T : DecoratedExternalKotlinComp
var compilationFactory: CompilationFactory<T> by Delegates.notNull()
var friendArtifactResolver: FriendArtifactResolver<T>? = null
var compilationAssociator: CompilationAssociator<T>? = null
@Suppress("DEPRECATION")
@Deprecated("Use sourceSetTreeClassifierV2 instead")
var sourceSetTreeClassifier: SourceSetTreeClassifier = SourceSetTreeClassifier.Default
var sourceSetTreeClassifierV2: KotlinSourceSetTreeClassifier? = null
internal var configure: ((T) -> Unit)? = null
@@ -106,6 +118,9 @@ private data class ExternalKotlinCompilationDescriptorImpl<T : DecoratedExternal
override val compilationFactory: CompilationFactory<T>,
override val friendArtifactResolver: FriendArtifactResolver<T>?,
override val compilationAssociator: CompilationAssociator<T>?,
@Deprecated("Use .sourceSetTreeClassifierV2 instead")
@Suppress("DEPRECATION")
override val sourceSetTreeClassifier: SourceSetTreeClassifier,
override val sourceSetTreeClassifierV2: KotlinSourceSetTreeClassifier?,
override val configure: ((T) -> Unit)?,
) : ExternalKotlinCompilationDescriptor<T>
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.external
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.hierarchy.SourceSetTreeClassifierWrapper
import org.jetbrains.kotlin.gradle.plugin.hierarchy.sourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationAssociator
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationAssociator
@@ -14,7 +16,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationS
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.*
import org.jetbrains.kotlin.gradle.plugin.mpp.decoratedInstance
import org.jetbrains.kotlin.gradle.plugin.mpp.external.DecoratedExternalKotlinCompilation.Delegate
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.sourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
/**
@@ -70,7 +71,10 @@ fun <T : DecoratedExternalKotlinCompilation> DecoratedExternalKotlinTarget.creat
val compilationImpl = compilationImplFactory.create(this, descriptor.compilationName)
val decoratedCompilation = descriptor.compilationFactory.create(Delegate(compilationImpl))
decoratedCompilation.sourceSetTreeClassifier = descriptor.sourceSetTreeClassifier
decoratedCompilation.sourceSetTreeClassifier = descriptor.sourceSetTreeClassifierV2
?: @Suppress("DEPRECATION") SourceSetTreeClassifierWrapper(descriptor.sourceSetTreeClassifier)
descriptor.configure?.invoke(decoratedCompilation)
this.delegate.compilations.add(decoratedCompilation)
@@ -1,44 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
import org.gradle.api.DomainObjectCollection
import org.gradle.api.NamedDomainObjectContainer
import org.jetbrains.kotlin.gradle.dsl.KotlinTargetHierarchyDsl
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyBuilder
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
internal class KotlinTargetHierarchyDslImpl(
private val targets: DomainObjectCollection<KotlinTarget>,
private val sourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
) : KotlinTargetHierarchyDsl {
private val _appliedDescriptors = mutableListOf<KotlinTargetHierarchyDescriptor>()
val appliedDescriptors: List<KotlinTargetHierarchyDescriptor> get() = _appliedDescriptors
override fun apply(
hierarchyDescriptor: KotlinTargetHierarchyDescriptor,
describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)?,
) {
val descriptor = hierarchyDescriptor.extendIfNotNull(describeExtension)
_appliedDescriptors.add(descriptor)
applyKotlinTargetHierarchy(descriptor, targets, sourceSets)
}
override fun default(describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)?) {
apply(defaultKotlinTargetHierarchy, describeExtension)
}
override fun custom(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit) {
apply(KotlinTargetHierarchyDescriptor(describe))
}
}
private fun KotlinTargetHierarchyDescriptor.extendIfNotNull(describe: (KotlinTargetHierarchyBuilder.Root.() -> Unit)?) =
if (describe == null) this else extend(describe)
@@ -3,15 +3,17 @@
* 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("DEPRECATION")
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilationFactory
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
/**
* Classifier providing the corresponding [SourceSetTree] associated with any given [KotlinCompilation]
@@ -41,6 +43,10 @@ import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
* there will not be a dependsOn edge to 'commonTest', but (if present) 'commonUnitTest'
*/
@ExternalKotlinTargetApi
@Deprecated(
"Use org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier instead",
ReplaceWith("org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier"),
)
sealed class SourceSetTreeClassifier {
/**
@@ -80,13 +86,13 @@ sealed class SourceSetTreeClassifier {
* make the [SourceSetTree] configurable.
*/
@ExternalKotlinTargetApi
class Property(val property: org.gradle.api.provider.Property<SourceSetTree>) : SourceSetTreeClassifier() {
class Property(val property: org.gradle.api.provider.Property<KotlinSourceSetTree>) : SourceSetTreeClassifier() {
override fun toString(): String {
return property.toString()
}
}
internal suspend fun classify(compilation: KotlinCompilation<*>): SourceSetTree? {
internal suspend fun classify(compilation: KotlinCompilation<*>): KotlinSourceSetTree? {
return when (this) {
is Default -> SourceSetTree(compilation.name)
is Property -> property.awaitFinalValue()
@@ -96,25 +102,3 @@ sealed class SourceSetTreeClassifier {
}
}
}
/**
* Returns the classifier configured for a given compilation.
* This is writable, as Android requires overwriting of this default behaviour.
*
* - The KGP maintained target will set the classifier within the [KotlinJvmAndroidCompilationFactory]
* - The external Android target will set this classifier within the 'createCompilation'
*
* It is therefore safe to access this value as soon as a compilation is provided
*/
internal var KotlinCompilation<*>.sourceSetTreeClassifier: SourceSetTreeClassifier by extrasLazyProperty {
SourceSetTreeClassifier.Default
}
/**
* Returns the [SourceSetTree] of a given [KotlinCompilation]:
* Uses the [sourceSetTreeClassifier] under the hood.
* See [SourceSetTreeClassifier]
*/
internal suspend fun SourceSetTree.Companion.orNull(compilation: KotlinCompilation<*>) =
compilation.sourceSetTreeClassifier.classify(compilation)
@@ -1,64 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
import org.gradle.api.DomainObjectCollection
import org.gradle.api.NamedDomainObjectContainer
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.Companion.upTo
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
internal fun applyKotlinTargetHierarchy(
hierarchyDescriptor: KotlinTargetHierarchyDescriptor,
targets: DomainObjectCollection<KotlinTarget>,
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>
) {
targets
.matching { target -> target.platformType != KotlinPlatformType.common }
.all { target ->
target.compilations.all forCompilation@{ compilation ->
target.project.kotlinPluginLifecycle.launch {
withRestrictedStages(upTo(Stage.FinaliseRefinesEdges)) {
val hierarchy = hierarchyDescriptor.buildKotlinTargetHierarchy(compilation) ?: return@withRestrictedStages
applyKotlinTargetHierarchy(hierarchy, compilation, sourceSets)
}
}
}
}
}
private suspend fun applyKotlinTargetHierarchy(
hierarchy: KotlinTargetHierarchyTree,
compilation: KotlinCompilation<*>,
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>
): KotlinSourceSet? {
val sharedSourceSet = createSharedSourceSetOrNull(sourceSets, hierarchy.node, compilation)
val childSourceSets = hierarchy.children
.mapNotNull { childHierarchy -> applyKotlinTargetHierarchy(childHierarchy, compilation, sourceSets) }
if (sharedSourceSet == null) return null
if (hierarchy.children.isNotEmpty()) {
childSourceSets.forEach { childSourceSet -> childSourceSet.dependsOn(sharedSourceSet) }
} else {
compilation.internal.kotlinSourceSets.forAll { compilationSourceSet ->
compilationSourceSet.dependsOn(sharedSourceSet)
}
}
return sharedSourceSet
}
private suspend fun createSharedSourceSetOrNull(
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
node: KotlinTargetHierarchyTree.Node,
compilation: KotlinCompilation<*>,
): KotlinSourceSet? {
val sharedSourceSetName = node.sharedSourceSetName(compilation) ?: return null
return sourceSets.maybeCreate(sharedSourceSetName)
}
@@ -1,55 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
internal val defaultKotlinTargetHierarchy = KotlinTargetHierarchyDescriptor {
/* natural hierarchy is only applied to default 'main'/'test' compilations (by default) */
withSourceSetTree(SourceSetTree.main, SourceSetTree.test)
common {
/* All compilations shall be added to the common group by default */
withCompilations { true }
group("native") {
withNative()
group("apple") {
withApple()
group("ios") {
withIos()
}
group("tvos") {
withTvos()
}
group("watchos") {
withWatchos()
}
group("macos") {
withMacos()
}
}
group("linux") {
withLinux()
}
group("mingw") {
withMingw()
}
group("androidNative") {
withAndroidNative()
}
}
}
}
@@ -0,0 +1,5 @@
### Deprecation
This package is fully deprecated and scheduled for removal with Kotlin 2.0.
Most concepts were moved by renaming of 'KotlinTargetHierarchy' to 'KotlinHierarchy'
(dropping the 'Target' in the name).
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.android.variantType
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
internal object MultiplatformLayoutV2DependsOnConfigurator : KotlinAndroidSourceSetConfigurator {
@Suppress("DEPRECATION")
override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: AndroidSourceSet) {
val androidBaseSourceSetName = AndroidBaseSourceSetName.byName(androidSourceSet.name) ?: return
setDefaultDependsOn(target, kotlinSourceSet, androidBaseSourceSetName.variantType)
@@ -32,8 +33,8 @@ internal object MultiplatformLayoutV2DependsOnConfigurator : KotlinAndroidSource
private fun setDefaultDependsOn(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, variantType: AndroidVariantType) {
target.project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseRefinesEdges) {
/* Only setup default if not KotlinTargetHierarchy was applied */
if (target.project.multiplatformExtensionOrNull?.internalKotlinTargetHierarchy?.appliedDescriptors.orEmpty().isNotEmpty()) {
/* Only setup default if no hierarchy template was applied */
if (target.project.multiplatformExtensionOrNull?.hierarchy?.appliedTemplates.orEmpty().isNotEmpty()) {
return@launchInStage
}
@@ -39,7 +39,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
@ExperimentalKotlinGradlePluginApi
val mainVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply {
sourceSetTree.convention(SourceSetTree.main)
sourceSetTree.convention(KotlinSourceSetTree.main)
}
@ExperimentalKotlinGradlePluginApi
@@ -54,7 +54,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
@ExperimentalKotlinGradlePluginApi
val unitTestVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply {
sourceSetTree.convention(SourceSetTree.test)
sourceSetTree.convention(KotlinSourceSetTree.test)
}
@ExperimentalKotlinGradlePluginApi
@@ -69,7 +69,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
@ExperimentalKotlinGradlePluginApi
val instrumentedTestVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply {
sourceSetTree.convention(SourceSetTree.instrumentedTest)
sourceSetTree.convention(KotlinSourceSetTree.instrumentedTest)
}
@ExperimentalKotlinGradlePluginApi
@@ -9,6 +9,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.utils.property
@@ -30,9 +31,9 @@ interface KotlinAndroidTargetVariantDsl {
* Will ensure that all android instrumented tests (androidInstrumentedTest, androidInstrumentedTestDebug, ...)
* will be placed into the 'test' SourceSet tree (with 'commonTest' as root)
*/
val sourceSetTree: Property<SourceSetTree>
val sourceSetTree: Property<KotlinSourceSetTree>
}
internal class KotlinAndroidTargetVariantDslImpl(objects: ObjectFactory) : KotlinAndroidTargetVariantDsl {
override val sourceSetTree: Property<SourceSetTree> = objects.property()
override val sourceSetTree: Property<KotlinSourceSetTree> = objects.property()
}
@@ -7,14 +7,14 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import com.android.build.gradle.api.BaseVariant
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier.Property
import org.jetbrains.kotlin.gradle.plugin.hierarchy.sourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinAndroidCompilationAssociator
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.AndroidCompilationSourceSetsContainerFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinJvmCompilerOptionsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.SourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.SourceSetTreeClassifier.Property
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.sourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType
import org.jetbrains.kotlin.gradle.plugin.sources.android.type
@@ -49,7 +49,7 @@ class KotlinJvmAndroidCompilationFactory internal constructor(
AndroidVariantType.Main -> Property(target.mainVariant.sourceSetTree)
AndroidVariantType.UnitTest -> Property(target.unitTestVariant.sourceSetTree)
AndroidVariantType.InstrumentedTest -> Property(target.instrumentedTestVariant.sourceSetTree)
AndroidVariantType.Unknown -> SourceSetTreeClassifier.None
AndroidVariantType.Unknown -> KotlinSourceSetTreeClassifier.None
}
}
}
@@ -41,7 +41,8 @@ class ResolvableMetadataConfigurationTest {
kotlin.jvm()
kotlin.linuxArm64()
kotlin.linuxX64()
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
val commonMain = kotlin.sourceSets.getByName("commonMain")
val nativeMain = kotlin.sourceSets.getByName("nativeMain")
@@ -34,7 +34,7 @@ class IdeBinaryDependencyResolverTest {
}
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm()
kotlin.linuxX64()
@@ -98,7 +98,7 @@ class IdeBinaryDependencyResolverTest {
/* Setup android target and add MVIKotlin dependency */
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.androidTarget()
val commonMain = kotlin.sourceSets.getByName("commonMain")
commonMain.dependencies {
@@ -20,7 +20,7 @@ class IdeDependsOnDependencyResolverTest {
fun `test - sample 0 - default dependsOn to commonMain and commonTest`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm()
val commonMain = kotlin.sourceSets.getByName("commonMain")
@@ -42,7 +42,7 @@ class IdeDependsOnDependencyResolverTest {
fun `test - sample 1 - custom dependsOn edge`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm()
val commonMain = kotlin.sourceSets.getByName("commonMain")
val customMain = kotlin.sourceSets.create("customMain")
@@ -37,7 +37,7 @@ class IdeJvmAndAndroidDependencyResolutionTest {
if (enableDefaultStdlib) repositories.mavenLocal()
repositories.mavenCentralCacheRedirector()
project.multiplatformExtension.targetHierarchy.custom {
project.multiplatformExtension.applyHierarchyTemplate {
common {
group("jvmAndAndroid") {
withJvm()
@@ -25,7 +25,7 @@ class IdeNativePlatformDependencyResolverTest {
fun `test - posix on linux`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64()
project.evaluate()
@@ -50,7 +50,7 @@ class IdeNativePlatformDependencyResolverTest {
Assume.assumeTrue("Macos host required for this test", HostManager.hostIsMac)
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.macosArm64()
project.evaluate()
@@ -36,7 +36,7 @@ class IdeOriginalMetadataDependencyResolverTest {
kotlin.linuxX64()
kotlin.linuxArm64()
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
project.evaluate()
@@ -64,7 +64,7 @@ class IdeOriginalMetadataDependencyResolverTest {
kotlin.jvm()
kotlin.linuxX64()
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
val commonMain = kotlin.sourceSets.getByName("commonMain")
@@ -27,7 +27,7 @@ class IdeSourceDependencyResolutionTest {
applyMultiplatformPlugin()
multiplatformExtension.apply {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
linuxX64()
linuxArm64()
jvm()
@@ -39,7 +39,7 @@ class IdeSourceDependencyResolutionTest {
applyMultiplatformPlugin()
multiplatformExtension.apply {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
linuxX64()
linuxArm64()
jvm()
@@ -142,7 +142,7 @@ class IdeSourceDependencyResolutionTest {
androidLibrary { compileSdk = 33 }
multiplatformExtension.apply {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
linuxX64()
linuxArm64()
jvm()
@@ -349,7 +349,7 @@ class IdeSourceSetConstraintTest {
val project = buildMppProject()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm()
kotlin.js(KotlinJsCompilerType.IR)
@@ -38,7 +38,7 @@ class IdeSourcesAndDocumentationResolutionTest {
}
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm()
kotlin.linuxX64()
kotlin.linuxArm64()
@@ -31,7 +31,7 @@ class IdeTransformedMetadataDependencyResolverTest {
}
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm()
kotlin.linuxX64()
@@ -10,7 +10,9 @@ package org.jetbrains.kotlin.gradle.regressionTests
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.kotlin.dsl.repositories
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.util.*
import org.junit.Test
@@ -33,7 +35,7 @@ class KT55929MetadataConfigurationsTest {
kotlin.linuxX64()
kotlin.linuxArm64()
kotlin.targetHierarchy.default {
kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common {
group("jvmAndLinux") {
withCompilations { it.platformType == KotlinPlatformType.jvm }
@@ -127,7 +129,7 @@ class KT55929MetadataConfigurationsTest {
}
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64()
kotlin.linuxArm64()
@@ -144,7 +146,7 @@ class KT55929MetadataConfigurationsTest {
id is ModuleComponentIdentifier && id.module == "kotlin-stdlib-common"
}
if(stdlibCommonFound) {
if (stdlibCommonFound) {
fail("Unexpectedly resolved stdlib-common for 'linuxX64Main'")
}
}
@@ -22,7 +22,7 @@ class KT57023CompileTaskDescriptionsTest {
kotlin.linuxArm64()
kotlin.jvm()
kotlin.js(KotlinJsCompilerType.IR)
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
project.evaluate()
@@ -8,8 +8,10 @@
package org.jetbrains.kotlin.gradle.regressionTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
@@ -23,7 +25,7 @@ class KotlinCompileTaskSourcesTest {
fun `test - sources - shared native compile - KT-54995`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64()
kotlin.linuxArm64()
@@ -63,7 +65,7 @@ class KotlinCompileTaskSourcesTest {
fun `test - sources - linux and jvm`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default {
kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common {
group("jvmAndLinux") {
withLinux()
@@ -21,7 +21,7 @@ class KotlinNativeCompileRefinesPathsTest {
fun `test - shared linux - refinesPaths`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64()
kotlin.linuxArm64()
@@ -87,7 +87,7 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
@Test
fun `test task disabled for non shared-native source sets`() {
project.enableCInteropCommonization(true)
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxArm64()
kotlin.linuxX64()
kotlin.jvm()
@@ -131,7 +131,7 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
) {
enableCInteropCommonization(true)
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
linuxX64()
linuxArm64()
}
@@ -10,13 +10,13 @@ package org.jetbrains.kotlin.gradle.unitTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.hierarchy.orNull
import org.jetbrains.kotlin.gradle.plugin.launchInStage
import org.jetbrains.kotlin.gradle.plugin.mpp.external.*
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.CompilationFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.TargetFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.SourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.orNull
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
import org.jetbrains.kotlin.gradle.utils.property
@@ -49,7 +49,7 @@ class ExternalKotlinTargetApiTests {
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
val compilation = target.createCompilation<FakeCompilation> { defaults() }
assertEquals(SourceSetTree("fake"), SourceSetTree.orNull(compilation))
assertEquals(KotlinSourceSetTree("fake"), KotlinSourceSetTree.orNull(compilation))
}
@Test
@@ -57,36 +57,36 @@ class ExternalKotlinTargetApiTests {
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
val compilation = target.createCompilation<FakeCompilation> {
defaults()
sourceSetTreeClassifier = SourceSetTreeClassifier.Name("mySourceSetTree")
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Name("mySourceSetTree")
}
assertEquals(SourceSetTree("mySourceSetTree"), SourceSetTree.orNull(compilation))
assertEquals(KotlinSourceSetTree("mySourceSetTree"), KotlinSourceSetTree.orNull(compilation))
}
@Test
fun `test - sourceSetClassifier - custom property`() = buildProjectWithMPP().runLifecycleAwareTest {
val myProperty = project.objects.property<SourceSetTree>()
val nullProperty = project.objects.property<SourceSetTree>()
val myProperty = project.objects.property<KotlinSourceSetTree>()
val nullProperty = project.objects.property<KotlinSourceSetTree>()
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
val mainCompilation = target.createCompilation<FakeCompilation> {
defaults()
sourceSetTreeClassifier = SourceSetTreeClassifier.Property(myProperty)
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Property(myProperty)
}
val auxCompilation = target.createCompilation<FakeCompilation>() {
compilationName = "aux"
compilationFactory = CompilationFactory(::FakeCompilation)
defaultSourceSet = kotlin.sourceSets.create("aux")
sourceSetTreeClassifier = SourceSetTreeClassifier.Property(nullProperty)
sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Property(nullProperty)
}
launchInStage(KotlinPluginLifecycle.Stage.FinaliseDsl) {
myProperty.set(SourceSetTree.main)
myProperty.set(KotlinSourceSetTree.main)
}
assertEquals(SourceSetTree.main, SourceSetTree.orNull(mainCompilation))
assertNull(SourceSetTree.orNull(auxCompilation))
assertEquals(KotlinSourceSetTree.main, KotlinSourceSetTree.orNull(mainCompilation))
assertNull(KotlinSourceSetTree.orNull(auxCompilation))
}
}
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue
import org.jetbrains.kotlin.gradle.plugin.currentKotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTargetVariantDslImpl
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import org.jetbrains.kotlin.gradle.util.*
import org.junit.Test
import kotlin.test.assertEquals
@@ -34,8 +35,8 @@ class KotlinAndroidTargetHierarchyDsl {
@Test
fun `test - module - can be set in users afterEvaluate`() = buildProjectWithMPP().runLifecycleAwareTest {
val dsl = KotlinAndroidTargetVariantDslImpl(project.objects)
afterEvaluate { dsl.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("x")) }
dsl.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("-set-before-after-evaluate-"))
afterEvaluate { dsl.sourceSetTree.set(KotlinSourceSetTree("x")) }
dsl.sourceSetTree.set(KotlinSourceSetTree("-set-before-after-evaluate-"))
assertEquals("x", dsl.sourceSetTree.awaitFinalValue()?.name)
assertEquals(KotlinPluginLifecycle.Stage.AfterFinaliseDsl, currentKotlinPluginLifecycle().stage)
}
@@ -51,8 +52,8 @@ class KotlinAndroidTargetHierarchyDsl {
val kotlin = project.multiplatformExtension
project.runLifecycleAwareTest {
kotlin.androidTarget {
unitTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree.test)
instrumentedTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree.test)
unitTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)
instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)
}
AfterFinaliseRefinesEdges.await()
@@ -73,13 +74,13 @@ class KotlinAndroidTargetHierarchyDsl {
val kotlin = project.multiplatformExtension
project.runLifecycleAwareTest {
kotlin.androidTarget {
unitTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("xxx"))
instrumentedTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("yyy"))
unitTestVariant.sourceSetTree.set(KotlinSourceSetTree("xxx"))
instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree("yyy"))
}
kotlin.targetHierarchy.default {
withSourceSetTree(KotlinTargetHierarchy.SourceSetTree("xxx"))
withSourceSetTree(KotlinTargetHierarchy.SourceSetTree("yyy"))
kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
withSourceSetTree(KotlinSourceSetTree("xxx"))
withSourceSetTree(KotlinSourceSetTree("yyy"))
}
AfterFinaliseRefinesEdges.await()
@@ -8,7 +8,7 @@
package org.jetbrains.kotlin.gradle.unitTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyBuilder
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyBuilder
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
@@ -18,11 +18,11 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.junit.Test
import kotlin.test.fail
class KotlinTargetHierarchyBuilderTest {
class KotlinHierarchyBuilderTest {
@Test
fun `test - interface offers functions for known presets`() {
val kotlinTargetHierarchyBuilderInterface = KotlinTargetHierarchyBuilder::class.java
val kotlinTargetHierarchyBuilderInterface = KotlinHierarchyBuilder::class.java
buildProjectWithMPP().multiplatformExtension.presets
@@ -10,15 +10,15 @@ package org.jetbrains.kotlin.gradle.unitTests
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.buildKotlinTargetHierarchy
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.defaultKotlinTargetHierarchy
import org.jetbrains.kotlin.gradle.plugin.hierarchy.buildHierarchy
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.util.*
import kotlin.test.*
class KotlinTargetHierarchyDslTest {
class KotlinHierarchyDslTest {
private val project = buildProjectWithMPP()
@@ -28,7 +28,8 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy default - targets from all families`() {
kotlin.apply {
targetHierarchy.default()
applyHierarchyTemplate(KotlinHierarchyTemplate.default)
iosArm64()
iosX64()
iosSimulatorArm64()
@@ -154,7 +155,7 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy default - only linuxX64`() {
kotlin.apply {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
kotlin.linuxX64()
}
@@ -175,11 +176,12 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy default - is only applied to main and test compilations`() = project.runLifecycleAwareTest {
assertNotNull(defaultKotlinTargetHierarchy.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.main))
assertNotNull(defaultKotlinTargetHierarchy.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.test))
assertNull(defaultKotlinTargetHierarchy.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("custom")))
assertNotNull(KotlinHierarchyTemplate.default.buildHierarchy(kotlin.linuxX64().compilations.main))
assertNotNull(KotlinHierarchyTemplate.default.buildHierarchy(kotlin.linuxX64().compilations.test))
assertNull(KotlinHierarchyTemplate.default.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("custom")))
kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default)
kotlin.targetHierarchy.default()
kotlin.linuxX64().compilations.maybeCreate("custom").defaultSourceSet.let { customSourceSet ->
if (customSourceSet.dependsOn.isNotEmpty()) {
fail("Expected no dependsOn SourceSets for $customSourceSet (${customSourceSet.dependsOn})")
@@ -198,7 +200,7 @@ class KotlinTargetHierarchyDslTest {
assertAndroidSdkAvailable()
project.androidLibrary { compileSdk = 31 }
kotlin.targetHierarchy.default {
kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common {
group("jvmAndAndroid") {
withJvm()
@@ -243,14 +245,14 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy apply - extend`() {
val descriptor = KotlinTargetHierarchyDescriptor {
val descriptor = KotlinHierarchyTemplate {
group("common") {
group("base")
}
}
kotlin.apply {
targetHierarchy.apply(descriptor) {
applyHierarchyTemplate(descriptor) {
group("base") {
group("extension") {
withLinuxX64()
@@ -279,7 +281,7 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy custom`() {
kotlin.targetHierarchy.custom {
kotlin.applyHierarchyTemplate {
common {
group("native") {
withNative()
@@ -314,7 +316,7 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy js and wasm`() {
kotlin.targetHierarchy.custom {
kotlin.applyHierarchyTemplate {
common {
group("web") {
withJs()
@@ -339,7 +341,7 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy js and wasm split`() {
kotlin.targetHierarchy.custom {
kotlin.applyHierarchyTemplate {
common {
group("jsAndJvm") {
withJs()
@@ -375,14 +377,14 @@ class KotlinTargetHierarchyDslTest {
@Test
fun `test - hierarchy set - extend - with new root`() {
val descriptor = KotlinTargetHierarchyDescriptor {
val descriptor = KotlinHierarchyTemplate {
group("common") {
group("base")
}
}
kotlin.apply {
targetHierarchy.apply(descriptor) {
applyHierarchyTemplate(descriptor) {
group("newRoot") {
group("base") {
group("extension") {
@@ -434,7 +436,7 @@ class KotlinTargetHierarchyDslTest {
*/
@Test
fun `test - diamond hierarchy from documentation example`() {
kotlin.targetHierarchy.custom {
kotlin.applyHierarchyTemplate {
common {
group("ios") {
withIos()
@@ -8,25 +8,26 @@
package org.jetbrains.kotlin.gradle.unitTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.CyclicKotlinTargetHierarchyException
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyTree
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyTree.Node
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.buildKotlinTargetHierarchy
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
import org.jetbrains.kotlin.gradle.plugin.extend
import org.jetbrains.kotlin.gradle.plugin.hierarchy.CyclicKotlinHierarchyException
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinHierarchy
import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinHierarchy.Node
import org.jetbrains.kotlin.gradle.plugin.hierarchy.buildHierarchy
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
import org.jetbrains.kotlin.gradle.util.main
import org.junit.Test
import kotlin.test.*
class KotlinTargetHierarchyDescriptorTest {
class KotlinHierarchyTemplateTest {
private val project = buildProjectWithMPP()
private val kotlin = project.multiplatformExtension
@Test
fun `test - simple descriptor`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor {
val template = KotlinHierarchyTemplate {
common {
group("groupA") { withCompilations { it.target.name == "a" } }
group("groupB") { withCompilations { it.target.name == "b" } }
@@ -43,7 +44,7 @@ class KotlinTargetHierarchyDescriptorTest {
group("groupA")
}
},
descriptor.buildKotlinTargetHierarchy(targetA.compilations.main)
template.buildHierarchy(targetA.compilations.main)
)
assertEquals(
@@ -52,18 +53,18 @@ class KotlinTargetHierarchyDescriptorTest {
group("groupB")
}
},
descriptor.buildKotlinTargetHierarchy(targetB.compilations.main)
template.buildHierarchy(targetB.compilations.main)
)
/* targetC is not mentioned in hierarchy description */
assertNull(
descriptor.buildKotlinTargetHierarchy(targetC.compilations.main)
template.buildHierarchy(targetC.compilations.main)
)
}
@Test
fun `test - extend`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { group("base") }.extend {
val template = KotlinHierarchyTemplate { group("base") }.extend {
group("base") {
group("extension") {
withCompilations { true }
@@ -77,14 +78,14 @@ class KotlinTargetHierarchyDescriptorTest {
group("extension")
}
},
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.getByName("main"))
template.buildHierarchy(kotlin.linuxX64().compilations.getByName("main"))
)
}
@Test
fun `test - extend - with new root`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { group("base") }.extend {
val template = KotlinHierarchyTemplate { group("base") }.extend {
group("newRoot") {
group("base") {
group("extension") {
@@ -102,14 +103,14 @@ class KotlinTargetHierarchyDescriptorTest {
}
}
},
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.main)
template.buildHierarchy(kotlin.linuxX64().compilations.main)
)
}
@Test
fun `test - extend - with two new roots and two extensions`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { group("base") }
val template = KotlinHierarchyTemplate { group("base") }
.extend {
group("newRoot1") {
group("base") {
@@ -129,7 +130,7 @@ class KotlinTargetHierarchyDescriptorTest {
}
}
val hierarchy = assertNotNull(descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.main))
val hierarchy = assertNotNull(template.buildHierarchy(kotlin.linuxX64().compilations.main))
assertEquals(
hierarchy {
@@ -149,7 +150,7 @@ class KotlinTargetHierarchyDescriptorTest {
}, hierarchy
)
fun KotlinTargetHierarchyTree.collectChildren(): List<KotlinTargetHierarchyTree> {
fun KotlinHierarchy.collectChildren(): List<KotlinHierarchy> {
return children.toList() + children.flatMap { it.collectChildren() }
}
@@ -165,7 +166,7 @@ class KotlinTargetHierarchyDescriptorTest {
@Test
fun `test - cycle`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor {
val template = KotlinHierarchyTemplate {
group("x") { // decoy 1
group("a") {
group("xx") // decoy 2
@@ -183,8 +184,8 @@ class KotlinTargetHierarchyDescriptorTest {
}
}
val cycleStack = assertFailsWith<CyclicKotlinTargetHierarchyException> {
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.main)
val cycleStack = assertFailsWith<CyclicKotlinHierarchyException> {
template.buildHierarchy(kotlin.linuxX64().compilations.main)
}.cycle
assertEquals(
@@ -196,7 +197,7 @@ class KotlinTargetHierarchyDescriptorTest {
@Suppress("DEPRECATION")
@Test
fun `test - filterCompilations`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor {
val template = KotlinHierarchyTemplate {
filterCompilations { it.name in setOf("a", "b") }
common {
group("x") {
@@ -211,36 +212,36 @@ class KotlinTargetHierarchyDescriptorTest {
group("x")
}
},
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("a"))
template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("a"))
)
assertEquals(
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")),
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("b"))
template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")),
template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("b"))
)
assertNull(
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("c"))
template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("c"))
)
}
@Suppress("DEPRECATION")
@Test
fun `test - filterCompilations - include them again`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor {
val template = KotlinHierarchyTemplate {
withCompilations { true }
filterCompilations { it.name == "a" }
}
assertNotNull(descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")))
assertNull(descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
assertNotNull(template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")))
assertNull(template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
val extended = descriptor.extend {
val extended = template.extend {
withCompilations { true } // <- adds all compilations back again!
}
assertNull(descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
assertNotNull(extended.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
assertNull(template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
assertNotNull(extended.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
}
}
@@ -251,9 +252,9 @@ private class TestHierarchyBuilder(private val node: Node) {
children.add(TestHierarchyBuilder(Node.Group(name)).also(builder))
}
fun build(): KotlinTargetHierarchyTree = KotlinTargetHierarchyTree(node, children.map { it.build() }.toSet())
fun build(): KotlinHierarchy = KotlinHierarchy(node, children.map { it.build() }.toSet())
}
private fun hierarchy(build: TestHierarchyBuilder.() -> Unit): KotlinTargetHierarchyTree {
private fun hierarchy(build: TestHierarchyBuilder.() -> Unit): KotlinHierarchy {
return TestHierarchyBuilder(Node.Root).also(build).build()
}
@@ -26,7 +26,7 @@ class KotlinMetadataTargetCompilationsTest {
kotlin.jvm()
kotlin.linuxX64()
kotlin.linuxArm64()
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
project.runLifecycleAwareTest {
val target = kotlin.metadata() as KotlinMetadataTarget
@@ -46,7 +46,7 @@ class KotlinMetadataTargetCompilationsTest {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.jvm()
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
project.runLifecycleAwareTest {
val target = kotlin.metadata() as KotlinMetadataTarget
@@ -58,7 +58,7 @@ class KotlinNativeCompilationModuleNameTest {
}
) {
with(multiplatformExtension) {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
linuxX64()
linuxArm64()
}
@@ -18,7 +18,7 @@ class KotlinSourceSetTreeDependsOnMismatchTest {
private fun checkDiagnostics(configure: KotlinMultiplatformExtension.() -> Unit): List<ToolingDiagnostic> {
val project = buildProjectWithMPP {
kotlin {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
androidTarget()
project.androidApplication { compileSdk = 32 }
iosX64(); iosArm64(); iosSimulatorArm64()
@@ -24,7 +24,7 @@ import kotlin.test.assertNotNull
class SourceSetVisibilityInferenceTest {
private val project = buildProjectWithMPP()
private val kotlin = project.multiplatformExtension.apply {
targetHierarchy.default()
applyDefaultHierarchyTemplate()
}
@Test