[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 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 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 getFriendModulesDisabled ()Lorg/gradle/api/provider/Property;
public abstract fun getMain ()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 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 interface class org/jetbrains/kotlin/gradle/dsl/KotlinTopLevelExtensionConfig {
public abstract fun explicitApi ()V public abstract fun explicitApi ()V
public abstract fun explicitApiWarning ()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/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 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 BOTH Lorg/jetbrains/kotlin/gradle/plugin/KotlinJsCompilerType;
public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/KotlinJsCompilerType$Companion; 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 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 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 (Lkotlin/jvm/functions/Function1;)V
public abstract fun attributes (Lorg/gradle/api/Action;)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 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 static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/KotlinTargetHierarchy$SourceSetTree$Companion;
public fun <init> (Ljava/lang/String;)V public fun <init> (Ljava/lang/String;)V
public fun equals (Ljava/lang/Object;)Z 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 hashCode ()I
public fun toString ()Ljava/lang/String; 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 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 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; 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.Action
import org.gradle.api.Named import org.gradle.api.Named
import org.gradle.api.Project
import org.gradle.api.attributes.AttributeContainer import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.HasAttributes import org.gradle.api.attributes.HasAttributes
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
@@ -17,7 +16,6 @@ import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptionsDeprecated import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptionsDeprecated
import org.jetbrains.kotlin.gradle.dsl.KotlinCompileDeprecated 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.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.tooling.core.HasMutableExtras 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 package org.jetbrains.kotlin.gradle.plugin
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
@@ -7,18 +5,18 @@ import org.jetbrains.kotlin.konan.target.DEPRECATED_TARGET_MESSAGE
@KotlinTargetsDsl @KotlinTargetsDsl
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
interface KotlinTargetHierarchyBuilder { interface KotlinHierarchyBuilder {
@KotlinTargetsDsl @KotlinTargetsDsl
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
interface Root : KotlinTargetHierarchyBuilder { interface Root : KotlinHierarchyBuilder {
/** /**
* Defines the trees that the described hierarchy is applied to. * 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 * ```kotlin
* targetHierarchy.custom { * applyHierarchyTemplate {
* sourceSetTrees(SourceSetTree.main, SourceSetTree.test) * sourceSetTrees(KotlinSourceSetTree.main, KotlinSourceSetTree.test)
* common { * common {
* withJvm() * withJvm()
* group("ios") { * group("ios") {
@@ -45,7 +43,7 @@ interface KotlinTargetHierarchyBuilder {
* ### Example 2: * ### Example 2:
* Using a different hierarchy for "main" and "test" * Using a different hierarchy for "main" and "test"
*```kotlin *```kotlin
* targetHierarchy.custom { * applyHierarchyTemplate {
* sourceSetTrees(SourceSetTree.main) // ! <- only applied to the "main" tree * sourceSetTrees(SourceSetTree.main) // ! <- only applied to the "main" tree
* common { * common {
* withJvm() * withJvm()
@@ -55,7 +53,7 @@ interface KotlinTargetHierarchyBuilder {
* } * }
* } * }
* *
* targetHierarchy.custom { * applyHierarchyTemplate {
* sourceSetTrees(SourceSetTree.test) // ! <- only applied to the "test" tree * sourceSetTrees(SourceSetTree.test) // ! <- only applied to the "test" tree
* common { * common {
* withJvm() * withJvm()
@@ -78,19 +76,19 @@ interface KotlinTargetHierarchyBuilder {
* iosX64Main iosArm64Main * iosX64Main iosArm64Main
* ``` * ```
*/ */
fun sourceSetTrees(vararg tree: KotlinTargetHierarchy.SourceSetTree) fun sourceSetTrees(vararg tree: KotlinSourceSetTree)
/** /**
* Will add the given [tree]s into for this descriptor. * Will add the given [tree]s into for this descriptor.
* @see sourceSetTrees * @see sourceSetTrees
*/ */
fun withSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree) fun withSourceSetTree(vararg tree: KotlinSourceSetTree)
/** /**
* Will remove the given [tree]s from this descriptor * Will remove the given [tree]s from this descriptor
* @see sourceSetTrees * @see sourceSetTrees
*/ */
fun excludeSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree) fun excludeSourceSetTree(vararg tree: KotlinSourceSetTree)
} }
/* Declaring groups */ /* Declaring groups */
@@ -112,8 +110,8 @@ interface KotlinTargetHierarchyBuilder {
* depend on the usual 'commonMain' * depend on the usual 'commonMain'
* *
*/ */
fun common(build: KotlinTargetHierarchyBuilder.() -> Unit) = group("common", build) fun common(build: KotlinHierarchyBuilder.() -> Unit) = group("common", build)
fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit = {}) fun group(name: String, build: KotlinHierarchyBuilder.() -> Unit = {})
/* low-level APIs */ /* low-level APIs */
fun withCompilations(predicate: (KotlinCompilation<*>) -> Boolean) 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() linuxArm64()
linuxX64() linuxX64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies { sourceSets.commonMain.get().dependencies {
implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT") implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT")
@@ -20,7 +20,7 @@ kotlin {
linuxX64() linuxX64()
linuxArm64() linuxArm64()
targetHierarchy.custom { applyHierarchyTemplate {
group("nativeCommon") { group("nativeCommon") {
withNative() withNative()
} }
@@ -10,7 +10,7 @@ kotlin {
macosX64() macosX64()
macosArm64() macosArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
targets.withType<KotlinNativeTarget>().all { targets.withType<KotlinNativeTarget>().all {
compilations.getByName("main").cinterops.create("libapp") { compilations.getByName("main").cinterops.create("libapp") {
@@ -9,7 +9,7 @@ kotlin {
macosX64() macosX64()
macosArm64() macosArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
/* first cinterop commonizer group */ /* first cinterop commonizer group */
listOf(macosX64(), macosArm64()).forEach { target -> listOf(macosX64(), macosArm64()).forEach { target ->
@@ -1,6 +1,7 @@
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
@@ -8,7 +9,7 @@ plugins {
kotlin { kotlin {
@OptIn(ExperimentalKotlinGradlePluginApi::class) @OptIn(ExperimentalKotlinGradlePluginApi::class)
targetHierarchy.default { applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common { common {
group("concurrent") { group("concurrent") {
withJvm() withJvm()
@@ -12,7 +12,7 @@ repositories {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
@@ -21,7 +21,7 @@ fun KotlinNativeTarget.cinterop(name: String = "a") {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
@@ -20,7 +20,7 @@ fun KotlinNativeTarget.cinterop(name: String = "a") {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
@@ -14,7 +14,7 @@ repositories {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
linuxX64() linuxX64()
macosX64() macosX64()
macosArm64() macosArm64()
@@ -10,7 +10,7 @@ repositories {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
@@ -20,7 +20,7 @@ kotlin {
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
} }
dependencies { dependencies {
@@ -19,7 +19,7 @@ kotlin {
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies { sourceSets.commonMain.get().dependencies {
api(project(":p1")) api(project(":p1"))
@@ -12,6 +12,6 @@ kotlin {
linuxX64() linuxX64()
linuxArm64() linuxArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
} }
@@ -16,7 +16,7 @@ repositories {
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) @OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm {} jvm {}
linuxX64 {} linuxX64 {}
linuxArm64 {} linuxArm64 {}
@@ -5,7 +5,7 @@ plugins {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
@@ -10,7 +10,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT" version = "1.0.0-SNAPSHOT"
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
@@ -5,7 +5,7 @@ plugins {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
iosX64() iosX64()
iosArm64() iosArm64()
@@ -10,7 +10,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT" version = "1.0.0-SNAPSHOT"
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
iosX64() iosX64()
iosArm64() iosArm64()
@@ -5,7 +5,7 @@ plugins {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
@@ -12,7 +12,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT" version = "1.0.0-SNAPSHOT"
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
@@ -5,7 +5,7 @@ plugins {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
@@ -10,7 +10,7 @@ group = "org.jetbrains.sample"
version = "1.0.0-SNAPSHOT" version = "1.0.0-SNAPSHOT"
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
@@ -11,7 +11,7 @@ kotlin {
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies { sourceSets.commonMain.get().dependencies {
implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT") implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT")
@@ -12,7 +12,7 @@ kotlin {
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
sourceSets.commonMain.get().dependencies { sourceSets.commonMain.get().dependencies {
implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT") implementation("org.jetbrains.sample:producer:1.0.0-SNAPSHOT")
@@ -21,7 +21,7 @@ kotlin {
jvm() jvm()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
targetHierarchy.default() applyDefaultHierarchyTemplate()
} }
group = "org.jetbrains.sample" group = "org.jetbrains.sample"
@@ -8,7 +8,7 @@ repositories {
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
@@ -7,7 +7,7 @@ group = "test"
version = "1.0" version = "1.0"
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() linuxX64()
@@ -11,7 +11,7 @@ repositories {
} }
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
jvm() jvm()
linuxX64() 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 abstract interface class org/jetbrains/kotlin/gradle/plugin/ide/IdeAdditionalArtifactResolver {
public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeAdditionalArtifactResolver$Companion; 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 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 getDefaultSourceSet ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSet;
public abstract fun getFriendArtifactResolver ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$FriendArtifactResolver; 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 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 { 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 getDefaultSourceSet ()Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSet;
public final fun getFriendArtifactResolver ()Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$FriendArtifactResolver; 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 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 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 setCompilationFactory (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor$CompilationFactory;)V
public final fun setCompilationName (Ljava/lang/String;)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 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 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 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 { 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.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider 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.*
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyDslImpl import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import javax.inject.Inject import javax.inject.Inject
abstract class KotlinMultiplatformExtension(project: Project) : abstract class KotlinMultiplatformExtension(project: Project) :
@@ -19,7 +20,8 @@ abstract class KotlinMultiplatformExtension(project: Project) :
KotlinTargetContainerWithPresetFunctions, KotlinTargetContainerWithPresetFunctions,
KotlinTargetContainerWithJsPresetFunctions, KotlinTargetContainerWithJsPresetFunctions,
KotlinTargetContainerWithWasmPresetFunctions, KotlinTargetContainerWithWasmPresetFunctions,
KotlinTargetContainerWithNativeShortcuts { KotlinTargetContainerWithNativeShortcuts,
KotlinHierarchyDsl {
override val presets: NamedDomainObjectCollection<KotlinTargetPreset<*>> = project.container(KotlinTargetPreset::class.java) override val presets: NamedDomainObjectCollection<KotlinTargetPreset<*>> = project.container(KotlinTargetPreset::class.java)
final override val targets: NamedDomainObjectCollection<KotlinTarget> = project.container(KotlinTarget::class.java) final override val targets: NamedDomainObjectCollection<KotlinTarget> = project.container(KotlinTarget::class.java)
@@ -45,12 +47,189 @@ abstract class KotlinMultiplatformExtension(project: Project) :
configure(presetExtension) configure(presetExtension)
} }
internal val internalKotlinTargetHierarchy by lazy { internal val hierarchy by lazy { KotlinHierarchyDslImpl(targets, sourceSets) }
KotlinTargetHierarchyDslImpl(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 @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 @Suppress("unused") // DSL
val testableTargets: NamedDomainObjectCollection<KotlinTargetWithTests<*, *>> val testableTargets: NamedDomainObjectCollection<KotlinTargetWithTests<*, *>>
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers package org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet 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.KotlinGradleProjectChecker
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext 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.KotlinSourceSetDependsOnDefaultCompilationSourceSet
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.KotlinSourceSetTreeDependsOnMismatch import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.KotlinSourceSetTreeDependsOnMismatch
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector 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.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.awaitPlatformCompilations
import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.plugin.sources.internal
@@ -22,14 +22,14 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
val sourceSets = this.multiplatformExtension?.awaitSourceSets() ?: return val sourceSets = this.multiplatformExtension?.awaitSourceSets() ?: return
// A "good" source set is part of only single Source Set Tree // 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 // 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 // A "leaf" source set is a source set with known Source Set Tree by default
val leafSourceSets = multiplatformExtension val leafSourceSets = multiplatformExtension
.awaitTargets() .awaitTargets()
.filter { it !is KotlinMetadataTarget } .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() .toMap()
val reverseSourceSetDependencies = mutableMapOf<KotlinSourceSet, MutableSet<KotlinSourceSet>>() val reverseSourceSetDependencies = mutableMapOf<KotlinSourceSet, MutableSet<KotlinSourceSet>>()
@@ -40,7 +40,7 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
sourceSet.dependsOn.forEach { it.addReverseDependencyTo(sourceSet) } sourceSet.dependsOn.forEach { it.addReverseDependencyTo(sourceSet) }
val platformCompilations = sourceSet.internal.awaitPlatformCompilations() 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 val totalDistinctSourceSetTrees = distinctSourceSetTrees.size
@@ -124,7 +124,7 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
private fun KotlinGradleProjectCheckerContext.reportSingleSourceSetWithDifferentSourceSetTree( private fun KotlinGradleProjectCheckerContext.reportSingleSourceSetWithDifferentSourceSetTree(
collector: KotlinToolingDiagnosticsCollector, collector: KotlinToolingDiagnosticsCollector,
badSourceSet: KotlinSourceSet, badSourceSet: KotlinSourceSet,
dependentsBySourceSetTree: Map<SourceSetTree?, List<KotlinSourceSet>> dependentsBySourceSetTree: Map<KotlinSourceSetTree?, List<KotlinSourceSet>>
): Boolean { ): Boolean {
val singleDependee = dependentsBySourceSetTree val singleDependee = dependentsBySourceSetTree
.values .values
@@ -139,7 +139,7 @@ internal object KotlinSourceSetTreeDependsOnMismatchChecker : KotlinGradleProjec
private fun KotlinGradleProjectCheckerContext.reportAllIncorrectSourceSetEdges( private fun KotlinGradleProjectCheckerContext.reportAllIncorrectSourceSetEdges(
collector: KotlinToolingDiagnosticsCollector, collector: KotlinToolingDiagnosticsCollector,
badSourceSet: KotlinSourceSet, badSourceSet: KotlinSourceSet,
dependentsBySourceSetTree: Map<SourceSetTree?, List<KotlinSourceSet>>, dependentsBySourceSetTree: Map<KotlinSourceSetTree?, List<KotlinSourceSet>>,
) { ) {
val dependentsGroup = dependentsBySourceSetTree val dependentsGroup = dependentsBySourceSetTree
.mapKeys { it.key?.name ?: "null" } .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. * 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.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.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.tooling.core.withClosure import org.jetbrains.kotlin.tooling.core.withClosure
internal data class KotlinTargetHierarchyTree( internal data class KotlinHierarchy(
val node: Node, val children: Set<KotlinTargetHierarchyTree> = emptySet() val node: Node, val children: Set<KotlinHierarchy> = emptySet(),
) { ) {
val childrenClosure: Set<KotlinTargetHierarchyTree> = val childrenClosure: Set<KotlinHierarchy> =
children.withClosure<KotlinTargetHierarchyTree> { it.children } children.withClosure<KotlinHierarchy> { it.children }
sealed class Node { sealed class Node {
abstract suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String? abstract suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String?
@@ -26,7 +26,7 @@ internal data class KotlinTargetHierarchyTree(
data class Group(val name: String) : Node() { data class Group(val name: String) : Node() {
override suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String? { 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) 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. * 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.gradle.api.InvalidUserCodeException
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.konan.target.DEPRECATED_TARGET_MESSAGE import org.jetbrains.kotlin.konan.target.DEPRECATED_TARGET_MESSAGE
import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.tooling.core.closure import org.jetbrains.kotlin.tooling.core.closure
internal suspend fun KotlinTargetHierarchyDescriptor.buildKotlinTargetHierarchy(compilation: KotlinCompilation<*>): KotlinTargetHierarchyTree? {
val context = KotlinTargetHierarchyBuilderImplContext(compilation) internal suspend fun KotlinHierarchyTemplate.buildHierarchy(compilation: KotlinCompilation<*>): KotlinHierarchy? {
describe(context.root) val context = KotlinHierarchyBuilderImplContext(compilation)
return context.build(KotlinTargetHierarchyTree.Node.Root) context.root.applyHierarchyTemplate(this)
return context.build(KotlinHierarchy.Node.Root)
} }
private class KotlinTargetHierarchyBuilderImplContext(private val compilation: KotlinCompilation<*>) { private class KotlinHierarchyBuilderImplContext(private val compilation: KotlinCompilation<*>) {
val root by lazy { KotlinTargetHierarchyBuilderRootImpl(getOrCreateBuilder(KotlinTargetHierarchyTree.Node.Root)) } val root by lazy { KotlinHierarchyBuilderRootImpl(getOrCreateBuilder(KotlinHierarchy.Node.Root)) }
private val builders = hashMapOf<KotlinTargetHierarchyTree.Node, KotlinTargetHierarchyBuilderImpl>() private val builders = hashMapOf<KotlinHierarchy.Node, KotlinHierarchyBuilderImpl>()
private val builtValues = hashMapOf<KotlinTargetHierarchyTree.Node, KotlinTargetHierarchyTree?>() private val builtValues = hashMapOf<KotlinHierarchy.Node, KotlinHierarchy?>()
fun getOrCreateBuilder(node: KotlinTargetHierarchyTree.Node): KotlinTargetHierarchyBuilderImpl = builders.getOrPut(node) { fun getOrCreateBuilder(node: KotlinHierarchy.Node): KotlinHierarchyBuilderImpl = builders.getOrPut(node) {
KotlinTargetHierarchyBuilderImpl(this, node) KotlinHierarchyBuilderImpl(this, node)
} }
suspend fun build(node: KotlinTargetHierarchyTree.Node): KotlinTargetHierarchyTree? { suspend fun build(node: KotlinHierarchy.Node): KotlinHierarchy? {
return builtValues.getOrPut(node) { return builtValues.getOrPut(node) {
val builder = getOrCreateBuilder(node) val builder = getOrCreateBuilder(node)
if (!builder.contains(compilation)) return@getOrPut null 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 children = builder.children.mapNotNull { child -> build(child.node) }
val directChildren = children.toSet() - children.flatMap { child -> child.childrenClosure }.toSet() val directChildren = children.toSet() - children.flatMap { child -> child.childrenClosure }.toSet()
KotlinTargetHierarchyTree(node, directChildren) KotlinHierarchy(node, directChildren)
} }
} }
} }
private class KotlinTargetHierarchyBuilderRootImpl( private class KotlinHierarchyBuilderRootImpl(
private val builder: KotlinTargetHierarchyBuilderImpl, private val builder: KotlinHierarchyBuilderImpl,
) : KotlinTargetHierarchyBuilder.Root, KotlinTargetHierarchyBuilder by builder { ) : KotlinHierarchyBuilder.Root, KotlinHierarchyBuilder by builder {
override fun sourceSetTrees(vararg tree: KotlinTargetHierarchy.SourceSetTree) { override fun sourceSetTrees(vararg tree: KotlinSourceSetTree) {
builder.sourceSetTrees = tree.toHashSet() builder.sourceSetTrees = tree.toHashSet()
} }
override fun withSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree) { override fun withSourceSetTree(vararg tree: KotlinSourceSetTree) {
builder.sourceSetTrees = builder.sourceSetTrees.orEmpty().plus(tree) builder.sourceSetTrees = builder.sourceSetTrees.orEmpty().plus(tree)
} }
override fun excludeSourceSetTree(vararg tree: KotlinTargetHierarchy.SourceSetTree) { override fun excludeSourceSetTree(vararg tree:KotlinSourceSetTree) {
val modules = tree.toHashSet() val modules = tree.toHashSet()
if (modules.isEmpty()) return if (modules.isEmpty()) return
builder.sourceSetTrees = builder.sourceSetTrees.orEmpty() - modules builder.sourceSetTrees = builder.sourceSetTrees.orEmpty() - modules
@@ -76,15 +75,15 @@ private class KotlinTargetHierarchyBuilderRootImpl(
} }
private class KotlinTargetHierarchyBuilderImpl( private class KotlinHierarchyBuilderImpl(
val context: KotlinTargetHierarchyBuilderImplContext, val context: KotlinHierarchyBuilderImplContext,
val node: KotlinTargetHierarchyTree.Node, val node: KotlinHierarchy.Node,
) : KotlinTargetHierarchyBuilder { ) : KotlinHierarchyBuilder {
val children = mutableSetOf<KotlinTargetHierarchyBuilderImpl>() val children = mutableSetOf<KotlinHierarchyBuilderImpl>()
val childrenClosure get() = closure { it.children } 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 includePredicate: ((KotlinCompilation<*>) -> Boolean) = { false }
private var excludePredicate: ((KotlinCompilation<*>) -> Boolean) = { false } private var excludePredicate: ((KotlinCompilation<*>) -> Boolean) = { false }
@@ -105,7 +104,7 @@ private class KotlinTargetHierarchyBuilderImpl(
suspend fun contains(compilation: KotlinCompilation<*>): Boolean { suspend fun contains(compilation: KotlinCompilation<*>): Boolean {
sourceSetTrees?.let { sourceSetTrees -> sourceSetTrees?.let { sourceSetTrees ->
val sourceSetTree = KotlinTargetHierarchy.SourceSetTree.orNull(compilation) ?: return false val sourceSetTree = KotlinSourceSetTree.orNull(compilation) ?: return false
if (sourceSetTree !in sourceSetTrees) 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) } private inline fun withTargets(crossinline predicate: (KotlinTarget) -> Boolean) = withCompilations { predicate(it.target) }
override fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit) { override fun group(name: String, build: KotlinHierarchyBuilder.() -> Unit) {
val node = KotlinTargetHierarchyTree.Node.Group(name) val node = KotlinHierarchy.Node.Group(name)
val child = context.getOrCreateBuilder(node).also(build) val child = context.getOrCreateBuilder(node).also(build)
children.add(child) children.add(child)
checkCyclicHierarchy() checkCyclicHierarchy()
@@ -281,20 +280,20 @@ private class KotlinTargetHierarchyBuilderImpl(
} }
override fun toString(): String { 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 stack = mutableListOf(node)
val visited = hashSetOf<KotlinTargetHierarchyBuilderImpl>() val visited = hashSetOf<KotlinHierarchyBuilderImpl>()
fun checkChild(child: KotlinTargetHierarchyBuilderImpl) { fun checkChild(child: KotlinHierarchyBuilderImpl) {
if (!visited.add(child)) return if (!visited.add(child)) return
stack += child.node stack += child.node
if (this == child) throw CyclicKotlinTargetHierarchyException(stack) if (this == child) throw CyclicKotlinHierarchyException(stack)
child.children.forEach { next -> checkChild(next) } child.children.forEach { next -> checkChild(next) }
stack -= child.node stack -= child.node
} }
@@ -303,6 +302,6 @@ private fun KotlinTargetHierarchyBuilderImpl.checkCyclicHierarchy(): Nothing? {
return null return null
} }
internal class CyclicKotlinTargetHierarchyException(val cycle: List<KotlinTargetHierarchyTree.Node>) : InvalidUserCodeException( internal class CyclicKotlinHierarchyException(val cycle: List<KotlinHierarchy.Node>) : InvalidUserCodeException(
"KotlinTargetHierarchy cycle detected: ${cycle.joinToString(" -> ")}" "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.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
import org.jetbrains.kotlin.gradle.plugin.* 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.kotlinIdeMultiplatformImport
import org.jetbrains.kotlin.gradle.plugin.ide.locateOrRegisterIdeResolveDependenciesTask 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.KotlinMultiplatformPlugin.Companion.sourceSetFreeCompilerArgsPropertyName
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.addBuildListenerForXcode 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.internal.runDeprecationDiagnostics
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes 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.DefaultLanguageSettingsBuilder
import org.jetbrains.kotlin.gradle.plugin.sources.awaitPlatformCompilations import org.jetbrains.kotlin.gradle.plugin.sources.awaitPlatformCompilations
import org.jetbrains.kotlin.gradle.plugin.sources.checkSourceSetVisibilityRequirements import org.jetbrains.kotlin.gradle.plugin.sources.checkSourceSetVisibilityRequirements
@@ -181,9 +180,10 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseRefinesEdges) { project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseRefinesEdges) {
/* Only setup default refines edges when no KotlinTargetHierarchy was applied */ /* Only setup default refines edges when no KotlinTargetHierarchy was applied */
if (project.multiplatformExtension.internalKotlinTargetHierarchy.appliedDescriptors.isNotEmpty()) return@launchInStage if (project.multiplatformExtension.internalKotlinTargetHierarchy.appliedDescriptors.isNotEmpty()) return@launchInStage
if (project.multiplatformExtension.hierarchy.appliedTemplates.isNotEmpty()) return@launchInStage
target.compilations.forEach { compilation -> 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 val commonSourceSet = sourceSets.findByName(lowerCamelCaseName("common", sourceSetTree.name)) ?: return@forEach
compilation.defaultSourceSet.dependsOn(commonSourceSet) compilation.defaultSourceSet.dependsOn(commonSourceSet)
} }
@@ -330,7 +330,7 @@ internal fun Project.setupGeneralKotlinExtensionParameters() {
val isMainSourceSet = sourceSet val isMainSourceSet = sourceSet
.internal .internal
.awaitPlatformCompilations() .awaitPlatformCompilations()
.any { SourceSetTree.orNull(it) == SourceSetTree.main } .any { KotlinSourceSetTree.orNull(it) == KotlinSourceSetTree.main }
languageSettings.explicitApi = project.providers.provider { languageSettings.explicitApi = project.providers.provider {
val explicitApiFlag = project.kotlinExtension.explicitApiModeAsCompilerArg() 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.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget 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.DecoratedKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.* import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.*
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.SourceSetTreeClassifier import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.SourceSetTreeClassifier
@@ -55,7 +56,12 @@ interface ExternalKotlinCompilationDescriptor<T : DecoratedExternalKotlinCompila
val compilationFactory: CompilationFactory<T> val compilationFactory: CompilationFactory<T>
val friendArtifactResolver: FriendArtifactResolver<T>? val friendArtifactResolver: FriendArtifactResolver<T>?
val compilationAssociator: CompilationAssociator<T>? val compilationAssociator: CompilationAssociator<T>?
@Suppress("DEPRECATION")
@Deprecated("Use .sourceSetTreeClassifierV2 instead")
val sourceSetTreeClassifier: SourceSetTreeClassifier val sourceSetTreeClassifier: SourceSetTreeClassifier
val sourceSetTreeClassifierV2: KotlinSourceSetTreeClassifier?
val configure: ((T) -> Unit)? val configure: ((T) -> Unit)?
} }
@@ -73,6 +79,7 @@ fun <T : DecoratedExternalKotlinCompilation> ExternalKotlinCompilationDescriptor
friendArtifactResolver = friendArtifactResolver, friendArtifactResolver = friendArtifactResolver,
compilationAssociator = compilationAssociator, compilationAssociator = compilationAssociator,
sourceSetTreeClassifier = sourceSetTreeClassifier, sourceSetTreeClassifier = sourceSetTreeClassifier,
sourceSetTreeClassifierV2 = sourceSetTreeClassifierV2,
configure = this.configure configure = this.configure
) )
} }
@@ -87,7 +94,12 @@ class ExternalKotlinCompilationDescriptorBuilder<T : DecoratedExternalKotlinComp
var compilationFactory: CompilationFactory<T> by Delegates.notNull() var compilationFactory: CompilationFactory<T> by Delegates.notNull()
var friendArtifactResolver: FriendArtifactResolver<T>? = null var friendArtifactResolver: FriendArtifactResolver<T>? = null
var compilationAssociator: CompilationAssociator<T>? = null var compilationAssociator: CompilationAssociator<T>? = null
@Suppress("DEPRECATION")
@Deprecated("Use sourceSetTreeClassifierV2 instead")
var sourceSetTreeClassifier: SourceSetTreeClassifier = SourceSetTreeClassifier.Default var sourceSetTreeClassifier: SourceSetTreeClassifier = SourceSetTreeClassifier.Default
var sourceSetTreeClassifierV2: KotlinSourceSetTreeClassifier? = null
internal var configure: ((T) -> Unit)? = null internal var configure: ((T) -> Unit)? = null
@@ -106,6 +118,9 @@ private data class ExternalKotlinCompilationDescriptorImpl<T : DecoratedExternal
override val compilationFactory: CompilationFactory<T>, override val compilationFactory: CompilationFactory<T>,
override val friendArtifactResolver: FriendArtifactResolver<T>?, override val friendArtifactResolver: FriendArtifactResolver<T>?,
override val compilationAssociator: CompilationAssociator<T>?, override val compilationAssociator: CompilationAssociator<T>?,
@Deprecated("Use .sourceSetTreeClassifierV2 instead")
@Suppress("DEPRECATION")
override val sourceSetTreeClassifier: SourceSetTreeClassifier, override val sourceSetTreeClassifier: SourceSetTreeClassifier,
override val sourceSetTreeClassifierV2: KotlinSourceSetTreeClassifier?,
override val configure: ((T) -> Unit)?, override val configure: ((T) -> Unit)?,
) : ExternalKotlinCompilationDescriptor<T> ) : 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.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.plugin.* 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.DefaultKotlinCompilationAssociator
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationAssociator 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.compilationImpl.factory.*
import org.jetbrains.kotlin.gradle.plugin.mpp.decoratedInstance 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.external.DecoratedExternalKotlinCompilation.Delegate
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.sourceSetTreeClassifier
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
/** /**
@@ -70,7 +71,10 @@ fun <T : DecoratedExternalKotlinCompilation> DecoratedExternalKotlinTarget.creat
val compilationImpl = compilationImplFactory.create(this, descriptor.compilationName) val compilationImpl = compilationImplFactory.create(this, descriptor.compilationName)
val decoratedCompilation = descriptor.compilationFactory.create(Delegate(compilationImpl)) val decoratedCompilation = descriptor.compilationFactory.create(Delegate(compilationImpl))
decoratedCompilation.sourceSetTreeClassifier = descriptor.sourceSetTreeClassifier
decoratedCompilation.sourceSetTreeClassifier = descriptor.sourceSetTreeClassifierV2
?: @Suppress("DEPRECATION") SourceSetTreeClassifierWrapper(descriptor.sourceSetTreeClassifier)
descriptor.configure?.invoke(decoratedCompilation) descriptor.configure?.invoke(decoratedCompilation)
this.delegate.compilations.add(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. * 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 package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation 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
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilationFactory import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
/** /**
* Classifier providing the corresponding [SourceSetTree] associated with any given [KotlinCompilation] * 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' * there will not be a dependsOn edge to 'commonTest', but (if present) 'commonUnitTest'
*/ */
@ExternalKotlinTargetApi @ExternalKotlinTargetApi
@Deprecated(
"Use org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier instead",
ReplaceWith("org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinSourceSetTreeClassifier"),
)
sealed class SourceSetTreeClassifier { sealed class SourceSetTreeClassifier {
/** /**
@@ -80,13 +86,13 @@ sealed class SourceSetTreeClassifier {
* make the [SourceSetTree] configurable. * make the [SourceSetTree] configurable.
*/ */
@ExternalKotlinTargetApi @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 { override fun toString(): String {
return property.toString() return property.toString()
} }
} }
internal suspend fun classify(compilation: KotlinCompilation<*>): SourceSetTree? { internal suspend fun classify(compilation: KotlinCompilation<*>): KotlinSourceSetTree? {
return when (this) { return when (this) {
is Default -> SourceSetTree(compilation.name) is Default -> SourceSetTree(compilation.name)
is Property -> property.awaitFinalValue() 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 import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
internal object MultiplatformLayoutV2DependsOnConfigurator : KotlinAndroidSourceSetConfigurator { internal object MultiplatformLayoutV2DependsOnConfigurator : KotlinAndroidSourceSetConfigurator {
@Suppress("DEPRECATION")
override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: AndroidSourceSet) { override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: AndroidSourceSet) {
val androidBaseSourceSetName = AndroidBaseSourceSetName.byName(androidSourceSet.name) ?: return val androidBaseSourceSetName = AndroidBaseSourceSetName.byName(androidSourceSet.name) ?: return
setDefaultDependsOn(target, kotlinSourceSet, androidBaseSourceSetName.variantType) setDefaultDependsOn(target, kotlinSourceSet, androidBaseSourceSetName.variantType)
@@ -32,8 +33,8 @@ internal object MultiplatformLayoutV2DependsOnConfigurator : KotlinAndroidSource
private fun setDefaultDependsOn(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, variantType: AndroidVariantType) { private fun setDefaultDependsOn(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, variantType: AndroidVariantType) {
target.project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseRefinesEdges) { target.project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseRefinesEdges) {
/* Only setup default if not KotlinTargetHierarchy was applied */ /* Only setup default if no hierarchy template was applied */
if (target.project.multiplatformExtensionOrNull?.internalKotlinTargetHierarchy?.appliedDescriptors.orEmpty().isNotEmpty()) { if (target.project.multiplatformExtensionOrNull?.hierarchy?.appliedTemplates.orEmpty().isNotEmpty()) {
return@launchInStage return@launchInStage
} }
@@ -39,7 +39,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
val mainVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply { val mainVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply {
sourceSetTree.convention(SourceSetTree.main) sourceSetTree.convention(KotlinSourceSetTree.main)
} }
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
@@ -54,7 +54,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
val unitTestVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply { val unitTestVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply {
sourceSetTree.convention(SourceSetTree.test) sourceSetTree.convention(KotlinSourceSetTree.test)
} }
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
@@ -69,7 +69,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
val instrumentedTestVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply { val instrumentedTestVariant: KotlinAndroidTargetVariantDsl = KotlinAndroidTargetVariantDslImpl(project.objects).apply {
sourceSetTree.convention(SourceSetTree.instrumentedTest) sourceSetTree.convention(KotlinSourceSetTree.instrumentedTest)
} }
@ExperimentalKotlinGradlePluginApi @ExperimentalKotlinGradlePluginApi
@@ -9,6 +9,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi 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.plugin.KotlinTargetHierarchy.SourceSetTree
import org.jetbrains.kotlin.gradle.utils.property import org.jetbrains.kotlin.gradle.utils.property
@@ -30,9 +31,9 @@ interface KotlinAndroidTargetVariantDsl {
* Will ensure that all android instrumented tests (androidInstrumentedTest, androidInstrumentedTestDebug, ...) * Will ensure that all android instrumented tests (androidInstrumentedTest, androidInstrumentedTestDebug, ...)
* will be placed into the 'test' SourceSet tree (with 'commonTest' as root) * 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 { 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 package org.jetbrains.kotlin.gradle.plugin.mpp
import com.android.build.gradle.api.BaseVariant 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.DefaultKotlinCompilationFriendPathsResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinAndroidCompilationAssociator 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.AndroidCompilationSourceSetsContainerFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory 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.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.AndroidVariantType
import org.jetbrains.kotlin.gradle.plugin.sources.android.type import org.jetbrains.kotlin.gradle.plugin.sources.android.type
@@ -49,7 +49,7 @@ class KotlinJvmAndroidCompilationFactory internal constructor(
AndroidVariantType.Main -> Property(target.mainVariant.sourceSetTree) AndroidVariantType.Main -> Property(target.mainVariant.sourceSetTree)
AndroidVariantType.UnitTest -> Property(target.unitTestVariant.sourceSetTree) AndroidVariantType.UnitTest -> Property(target.unitTestVariant.sourceSetTree)
AndroidVariantType.InstrumentedTest -> Property(target.instrumentedTestVariant.sourceSetTree) AndroidVariantType.InstrumentedTest -> Property(target.instrumentedTestVariant.sourceSetTree)
AndroidVariantType.Unknown -> SourceSetTreeClassifier.None AndroidVariantType.Unknown -> KotlinSourceSetTreeClassifier.None
} }
} }
} }
@@ -41,7 +41,8 @@ class ResolvableMetadataConfigurationTest {
kotlin.jvm() kotlin.jvm()
kotlin.linuxArm64() kotlin.linuxArm64()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.targetHierarchy.default()
kotlin.applyDefaultHierarchyTemplate()
val commonMain = kotlin.sourceSets.getByName("commonMain") val commonMain = kotlin.sourceSets.getByName("commonMain")
val nativeMain = kotlin.sourceSets.getByName("nativeMain") val nativeMain = kotlin.sourceSets.getByName("nativeMain")
@@ -34,7 +34,7 @@ class IdeBinaryDependencyResolverTest {
} }
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm() kotlin.jvm()
kotlin.linuxX64() kotlin.linuxX64()
@@ -98,7 +98,7 @@ class IdeBinaryDependencyResolverTest {
/* Setup android target and add MVIKotlin dependency */ /* Setup android target and add MVIKotlin dependency */
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.androidTarget() kotlin.androidTarget()
val commonMain = kotlin.sourceSets.getByName("commonMain") val commonMain = kotlin.sourceSets.getByName("commonMain")
commonMain.dependencies { commonMain.dependencies {
@@ -20,7 +20,7 @@ class IdeDependsOnDependencyResolverTest {
fun `test - sample 0 - default dependsOn to commonMain and commonTest`() { fun `test - sample 0 - default dependsOn to commonMain and commonTest`() {
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm() kotlin.jvm()
val commonMain = kotlin.sourceSets.getByName("commonMain") val commonMain = kotlin.sourceSets.getByName("commonMain")
@@ -42,7 +42,7 @@ class IdeDependsOnDependencyResolverTest {
fun `test - sample 1 - custom dependsOn edge`() { fun `test - sample 1 - custom dependsOn edge`() {
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm() kotlin.jvm()
val commonMain = kotlin.sourceSets.getByName("commonMain") val commonMain = kotlin.sourceSets.getByName("commonMain")
val customMain = kotlin.sourceSets.create("customMain") val customMain = kotlin.sourceSets.create("customMain")
@@ -37,7 +37,7 @@ class IdeJvmAndAndroidDependencyResolutionTest {
if (enableDefaultStdlib) repositories.mavenLocal() if (enableDefaultStdlib) repositories.mavenLocal()
repositories.mavenCentralCacheRedirector() repositories.mavenCentralCacheRedirector()
project.multiplatformExtension.targetHierarchy.custom { project.multiplatformExtension.applyHierarchyTemplate {
common { common {
group("jvmAndAndroid") { group("jvmAndAndroid") {
withJvm() withJvm()
@@ -25,7 +25,7 @@ class IdeNativePlatformDependencyResolverTest {
fun `test - posix on linux`() { fun `test - posix on linux`() {
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64() kotlin.linuxX64()
project.evaluate() project.evaluate()
@@ -50,7 +50,7 @@ class IdeNativePlatformDependencyResolverTest {
Assume.assumeTrue("Macos host required for this test", HostManager.hostIsMac) Assume.assumeTrue("Macos host required for this test", HostManager.hostIsMac)
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.macosArm64() kotlin.macosArm64()
project.evaluate() project.evaluate()
@@ -36,7 +36,7 @@ class IdeOriginalMetadataDependencyResolverTest {
kotlin.linuxX64() kotlin.linuxX64()
kotlin.linuxArm64() kotlin.linuxArm64()
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
project.evaluate() project.evaluate()
@@ -64,7 +64,7 @@ class IdeOriginalMetadataDependencyResolverTest {
kotlin.jvm() kotlin.jvm()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
val commonMain = kotlin.sourceSets.getByName("commonMain") val commonMain = kotlin.sourceSets.getByName("commonMain")
@@ -27,7 +27,7 @@ class IdeSourceDependencyResolutionTest {
applyMultiplatformPlugin() applyMultiplatformPlugin()
multiplatformExtension.apply { multiplatformExtension.apply {
targetHierarchy.default() applyDefaultHierarchyTemplate()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
jvm() jvm()
@@ -39,7 +39,7 @@ class IdeSourceDependencyResolutionTest {
applyMultiplatformPlugin() applyMultiplatformPlugin()
multiplatformExtension.apply { multiplatformExtension.apply {
targetHierarchy.default() applyDefaultHierarchyTemplate()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
jvm() jvm()
@@ -142,7 +142,7 @@ class IdeSourceDependencyResolutionTest {
androidLibrary { compileSdk = 33 } androidLibrary { compileSdk = 33 }
multiplatformExtension.apply { multiplatformExtension.apply {
targetHierarchy.default() applyDefaultHierarchyTemplate()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
jvm() jvm()
@@ -349,7 +349,7 @@ class IdeSourceSetConstraintTest {
val project = buildMppProject() val project = buildMppProject()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm() kotlin.jvm()
kotlin.js(KotlinJsCompilerType.IR) kotlin.js(KotlinJsCompilerType.IR)
@@ -38,7 +38,7 @@ class IdeSourcesAndDocumentationResolutionTest {
} }
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm() kotlin.jvm()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.linuxArm64() kotlin.linuxArm64()
@@ -31,7 +31,7 @@ class IdeTransformedMetadataDependencyResolverTest {
} }
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.jvm() kotlin.jvm()
kotlin.linuxX64() kotlin.linuxX64()
@@ -10,7 +10,9 @@ package org.jetbrains.kotlin.gradle.regressionTests
import org.gradle.api.artifacts.component.ModuleComponentIdentifier import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.kotlin.dsl.repositories import org.gradle.kotlin.dsl.repositories
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension 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.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.util.* import org.jetbrains.kotlin.gradle.util.*
import org.junit.Test import org.junit.Test
@@ -33,7 +35,7 @@ class KT55929MetadataConfigurationsTest {
kotlin.linuxX64() kotlin.linuxX64()
kotlin.linuxArm64() kotlin.linuxArm64()
kotlin.targetHierarchy.default { kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common { common {
group("jvmAndLinux") { group("jvmAndLinux") {
withCompilations { it.platformType == KotlinPlatformType.jvm } withCompilations { it.platformType == KotlinPlatformType.jvm }
@@ -127,7 +129,7 @@ class KT55929MetadataConfigurationsTest {
} }
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.linuxArm64() kotlin.linuxArm64()
@@ -144,7 +146,7 @@ class KT55929MetadataConfigurationsTest {
id is ModuleComponentIdentifier && id.module == "kotlin-stdlib-common" id is ModuleComponentIdentifier && id.module == "kotlin-stdlib-common"
} }
if(stdlibCommonFound) { if (stdlibCommonFound) {
fail("Unexpectedly resolved stdlib-common for 'linuxX64Main'") fail("Unexpectedly resolved stdlib-common for 'linuxX64Main'")
} }
} }
@@ -22,7 +22,7 @@ class KT57023CompileTaskDescriptionsTest {
kotlin.linuxArm64() kotlin.linuxArm64()
kotlin.jvm() kotlin.jvm()
kotlin.js(KotlinJsCompilerType.IR) kotlin.js(KotlinJsCompilerType.IR)
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
project.evaluate() project.evaluate()
@@ -8,8 +8,10 @@
package org.jetbrains.kotlin.gradle.regressionTests package org.jetbrains.kotlin.gradle.regressionTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension 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.KotlinCommonCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation 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.KotlinCompileCommon
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
@@ -23,7 +25,7 @@ class KotlinCompileTaskSourcesTest {
fun `test - sources - shared native compile - KT-54995`() { fun `test - sources - shared native compile - KT-54995`() {
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.linuxArm64() kotlin.linuxArm64()
@@ -63,7 +65,7 @@ class KotlinCompileTaskSourcesTest {
fun `test - sources - linux and jvm`() { fun `test - sources - linux and jvm`() {
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default { kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common { common {
group("jvmAndLinux") { group("jvmAndLinux") {
withLinux() withLinux()
@@ -21,7 +21,7 @@ class KotlinNativeCompileRefinesPathsTest {
fun `test - shared linux - refinesPaths`() { fun `test - shared linux - refinesPaths`() {
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.linuxArm64() kotlin.linuxArm64()
@@ -87,7 +87,7 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
@Test @Test
fun `test task disabled for non shared-native source sets`() { fun `test task disabled for non shared-native source sets`() {
project.enableCInteropCommonization(true) project.enableCInteropCommonization(true)
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
kotlin.linuxArm64() kotlin.linuxArm64()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.jvm() kotlin.jvm()
@@ -131,7 +131,7 @@ class CInteropMetadataDependencyTransformationTaskTest : MultiplatformExtensionT
) { ) {
enableCInteropCommonization(true) enableCInteropCommonization(true)
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
} }
@@ -10,13 +10,13 @@ package org.jetbrains.kotlin.gradle.unitTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle 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.launchInStage
import org.jetbrains.kotlin.gradle.plugin.mpp.external.* 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.ExternalKotlinCompilationDescriptor.CompilationFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.TargetFactory 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.buildProjectWithMPP
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
import org.jetbrains.kotlin.gradle.utils.property import org.jetbrains.kotlin.gradle.utils.property
@@ -49,7 +49,7 @@ class ExternalKotlinTargetApiTests {
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() } val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
val compilation = target.createCompilation<FakeCompilation> { defaults() } val compilation = target.createCompilation<FakeCompilation> { defaults() }
assertEquals(SourceSetTree("fake"), SourceSetTree.orNull(compilation)) assertEquals(KotlinSourceSetTree("fake"), KotlinSourceSetTree.orNull(compilation))
} }
@Test @Test
@@ -57,36 +57,36 @@ class ExternalKotlinTargetApiTests {
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() } val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
val compilation = target.createCompilation<FakeCompilation> { val compilation = target.createCompilation<FakeCompilation> {
defaults() defaults()
sourceSetTreeClassifier = SourceSetTreeClassifier.Name("mySourceSetTree") sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Name("mySourceSetTree")
} }
assertEquals(SourceSetTree("mySourceSetTree"), SourceSetTree.orNull(compilation)) assertEquals(KotlinSourceSetTree("mySourceSetTree"), KotlinSourceSetTree.orNull(compilation))
} }
@Test @Test
fun `test - sourceSetClassifier - custom property`() = buildProjectWithMPP().runLifecycleAwareTest { fun `test - sourceSetClassifier - custom property`() = buildProjectWithMPP().runLifecycleAwareTest {
val myProperty = project.objects.property<SourceSetTree>() val myProperty = project.objects.property<KotlinSourceSetTree>()
val nullProperty = project.objects.property<SourceSetTree>() val nullProperty = project.objects.property<KotlinSourceSetTree>()
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() } val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
val mainCompilation = target.createCompilation<FakeCompilation> { val mainCompilation = target.createCompilation<FakeCompilation> {
defaults() defaults()
sourceSetTreeClassifier = SourceSetTreeClassifier.Property(myProperty) sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Property(myProperty)
} }
val auxCompilation = target.createCompilation<FakeCompilation>() { val auxCompilation = target.createCompilation<FakeCompilation>() {
compilationName = "aux" compilationName = "aux"
compilationFactory = CompilationFactory(::FakeCompilation) compilationFactory = CompilationFactory(::FakeCompilation)
defaultSourceSet = kotlin.sourceSets.create("aux") defaultSourceSet = kotlin.sourceSets.create("aux")
sourceSetTreeClassifier = SourceSetTreeClassifier.Property(nullProperty) sourceSetTreeClassifierV2 = KotlinSourceSetTreeClassifier.Property(nullProperty)
} }
launchInStage(KotlinPluginLifecycle.Stage.FinaliseDsl) { launchInStage(KotlinPluginLifecycle.Stage.FinaliseDsl) {
myProperty.set(SourceSetTree.main) myProperty.set(KotlinSourceSetTree.main)
} }
assertEquals(SourceSetTree.main, SourceSetTree.orNull(mainCompilation)) assertEquals(KotlinSourceSetTree.main, KotlinSourceSetTree.orNull(mainCompilation))
assertNull(SourceSetTree.orNull(auxCompilation)) 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.currentKotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTargetVariantDslImpl import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTargetVariantDslImpl
import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import org.jetbrains.kotlin.gradle.util.* import org.jetbrains.kotlin.gradle.util.*
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@@ -34,8 +35,8 @@ class KotlinAndroidTargetHierarchyDsl {
@Test @Test
fun `test - module - can be set in users afterEvaluate`() = buildProjectWithMPP().runLifecycleAwareTest { fun `test - module - can be set in users afterEvaluate`() = buildProjectWithMPP().runLifecycleAwareTest {
val dsl = KotlinAndroidTargetVariantDslImpl(project.objects) val dsl = KotlinAndroidTargetVariantDslImpl(project.objects)
afterEvaluate { dsl.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("x")) } afterEvaluate { dsl.sourceSetTree.set(KotlinSourceSetTree("x")) }
dsl.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("-set-before-after-evaluate-")) dsl.sourceSetTree.set(KotlinSourceSetTree("-set-before-after-evaluate-"))
assertEquals("x", dsl.sourceSetTree.awaitFinalValue()?.name) assertEquals("x", dsl.sourceSetTree.awaitFinalValue()?.name)
assertEquals(KotlinPluginLifecycle.Stage.AfterFinaliseDsl, currentKotlinPluginLifecycle().stage) assertEquals(KotlinPluginLifecycle.Stage.AfterFinaliseDsl, currentKotlinPluginLifecycle().stage)
} }
@@ -51,8 +52,8 @@ class KotlinAndroidTargetHierarchyDsl {
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
project.runLifecycleAwareTest { project.runLifecycleAwareTest {
kotlin.androidTarget { kotlin.androidTarget {
unitTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree.test) unitTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)
instrumentedTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree.test) instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)
} }
AfterFinaliseRefinesEdges.await() AfterFinaliseRefinesEdges.await()
@@ -73,13 +74,13 @@ class KotlinAndroidTargetHierarchyDsl {
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
project.runLifecycleAwareTest { project.runLifecycleAwareTest {
kotlin.androidTarget { kotlin.androidTarget {
unitTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("xxx")) unitTestVariant.sourceSetTree.set(KotlinSourceSetTree("xxx"))
instrumentedTestVariant.sourceSetTree.set(KotlinTargetHierarchy.SourceSetTree("yyy")) instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree("yyy"))
} }
kotlin.targetHierarchy.default { kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
withSourceSetTree(KotlinTargetHierarchy.SourceSetTree("xxx")) withSourceSetTree(KotlinSourceSetTree("xxx"))
withSourceSetTree(KotlinTargetHierarchy.SourceSetTree("yyy")) withSourceSetTree(KotlinSourceSetTree("yyy"))
} }
AfterFinaliseRefinesEdges.await() AfterFinaliseRefinesEdges.await()
@@ -8,7 +8,7 @@
package org.jetbrains.kotlin.gradle.unitTests package org.jetbrains.kotlin.gradle.unitTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension 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.KotlinJsTargetPreset
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmWithJavaTargetPreset import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmWithJavaTargetPreset
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetPreset
@@ -18,11 +18,11 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.junit.Test import org.junit.Test
import kotlin.test.fail import kotlin.test.fail
class KotlinTargetHierarchyBuilderTest { class KotlinHierarchyBuilderTest {
@Test @Test
fun `test - interface offers functions for known presets`() { fun `test - interface offers functions for known presets`() {
val kotlinTargetHierarchyBuilderInterface = KotlinTargetHierarchyBuilder::class.java val kotlinTargetHierarchyBuilderInterface = KotlinHierarchyBuilder::class.java
buildProjectWithMPP().multiplatformExtension.presets 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.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension 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.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor import org.jetbrains.kotlin.gradle.plugin.hierarchy.buildHierarchy
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.buildKotlinTargetHierarchy import org.jetbrains.kotlin.gradle.plugin.hierarchy.default
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.defaultKotlinTargetHierarchy
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.util.* import org.jetbrains.kotlin.gradle.util.*
import kotlin.test.* import kotlin.test.*
class KotlinTargetHierarchyDslTest { class KotlinHierarchyDslTest {
private val project = buildProjectWithMPP() private val project = buildProjectWithMPP()
@@ -28,7 +28,8 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy default - targets from all families`() { fun `test - hierarchy default - targets from all families`() {
kotlin.apply { kotlin.apply {
targetHierarchy.default() applyHierarchyTemplate(KotlinHierarchyTemplate.default)
iosArm64() iosArm64()
iosX64() iosX64()
iosSimulatorArm64() iosSimulatorArm64()
@@ -154,7 +155,7 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy default - only linuxX64`() { fun `test - hierarchy default - only linuxX64`() {
kotlin.apply { kotlin.apply {
targetHierarchy.default() applyDefaultHierarchyTemplate()
kotlin.linuxX64() kotlin.linuxX64()
} }
@@ -175,11 +176,12 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy default - is only applied to main and test compilations`() = project.runLifecycleAwareTest { fun `test - hierarchy default - is only applied to main and test compilations`() = project.runLifecycleAwareTest {
assertNotNull(defaultKotlinTargetHierarchy.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.main)) assertNotNull(KotlinHierarchyTemplate.default.buildHierarchy(kotlin.linuxX64().compilations.main))
assertNotNull(defaultKotlinTargetHierarchy.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.test)) assertNotNull(KotlinHierarchyTemplate.default.buildHierarchy(kotlin.linuxX64().compilations.test))
assertNull(defaultKotlinTargetHierarchy.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("custom"))) assertNull(KotlinHierarchyTemplate.default.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("custom")))
kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default)
kotlin.targetHierarchy.default()
kotlin.linuxX64().compilations.maybeCreate("custom").defaultSourceSet.let { customSourceSet -> kotlin.linuxX64().compilations.maybeCreate("custom").defaultSourceSet.let { customSourceSet ->
if (customSourceSet.dependsOn.isNotEmpty()) { if (customSourceSet.dependsOn.isNotEmpty()) {
fail("Expected no dependsOn SourceSets for $customSourceSet (${customSourceSet.dependsOn})") fail("Expected no dependsOn SourceSets for $customSourceSet (${customSourceSet.dependsOn})")
@@ -198,7 +200,7 @@ class KotlinTargetHierarchyDslTest {
assertAndroidSdkAvailable() assertAndroidSdkAvailable()
project.androidLibrary { compileSdk = 31 } project.androidLibrary { compileSdk = 31 }
kotlin.targetHierarchy.default { kotlin.applyHierarchyTemplate(KotlinHierarchyTemplate.default) {
common { common {
group("jvmAndAndroid") { group("jvmAndAndroid") {
withJvm() withJvm()
@@ -243,14 +245,14 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy apply - extend`() { fun `test - hierarchy apply - extend`() {
val descriptor = KotlinTargetHierarchyDescriptor { val descriptor = KotlinHierarchyTemplate {
group("common") { group("common") {
group("base") group("base")
} }
} }
kotlin.apply { kotlin.apply {
targetHierarchy.apply(descriptor) { applyHierarchyTemplate(descriptor) {
group("base") { group("base") {
group("extension") { group("extension") {
withLinuxX64() withLinuxX64()
@@ -279,7 +281,7 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy custom`() { fun `test - hierarchy custom`() {
kotlin.targetHierarchy.custom { kotlin.applyHierarchyTemplate {
common { common {
group("native") { group("native") {
withNative() withNative()
@@ -314,7 +316,7 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy js and wasm`() { fun `test - hierarchy js and wasm`() {
kotlin.targetHierarchy.custom { kotlin.applyHierarchyTemplate {
common { common {
group("web") { group("web") {
withJs() withJs()
@@ -339,7 +341,7 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy js and wasm split`() { fun `test - hierarchy js and wasm split`() {
kotlin.targetHierarchy.custom { kotlin.applyHierarchyTemplate {
common { common {
group("jsAndJvm") { group("jsAndJvm") {
withJs() withJs()
@@ -375,14 +377,14 @@ class KotlinTargetHierarchyDslTest {
@Test @Test
fun `test - hierarchy set - extend - with new root`() { fun `test - hierarchy set - extend - with new root`() {
val descriptor = KotlinTargetHierarchyDescriptor { val descriptor = KotlinHierarchyTemplate {
group("common") { group("common") {
group("base") group("base")
} }
} }
kotlin.apply { kotlin.apply {
targetHierarchy.apply(descriptor) { applyHierarchyTemplate(descriptor) {
group("newRoot") { group("newRoot") {
group("base") { group("base") {
group("extension") { group("extension") {
@@ -434,7 +436,7 @@ class KotlinTargetHierarchyDslTest {
*/ */
@Test @Test
fun `test - diamond hierarchy from documentation example`() { fun `test - diamond hierarchy from documentation example`() {
kotlin.targetHierarchy.custom { kotlin.applyHierarchyTemplate {
common { common {
group("ios") { group("ios") {
withIos() withIos()
@@ -8,25 +8,26 @@
package org.jetbrains.kotlin.gradle.unitTests package org.jetbrains.kotlin.gradle.unitTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.CyclicKotlinTargetHierarchyException import org.jetbrains.kotlin.gradle.plugin.extend
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyTree import org.jetbrains.kotlin.gradle.plugin.hierarchy.CyclicKotlinHierarchyException
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyTree.Node import org.jetbrains.kotlin.gradle.plugin.hierarchy.KotlinHierarchy
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.buildKotlinTargetHierarchy 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.buildProjectWithMPP
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
import org.jetbrains.kotlin.gradle.util.main import org.jetbrains.kotlin.gradle.util.main
import org.junit.Test import org.junit.Test
import kotlin.test.* import kotlin.test.*
class KotlinTargetHierarchyDescriptorTest { class KotlinHierarchyTemplateTest {
private val project = buildProjectWithMPP() private val project = buildProjectWithMPP()
private val kotlin = project.multiplatformExtension private val kotlin = project.multiplatformExtension
@Test @Test
fun `test - simple descriptor`() = project.runLifecycleAwareTest { fun `test - simple descriptor`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { val template = KotlinHierarchyTemplate {
common { common {
group("groupA") { withCompilations { it.target.name == "a" } } group("groupA") { withCompilations { it.target.name == "a" } }
group("groupB") { withCompilations { it.target.name == "b" } } group("groupB") { withCompilations { it.target.name == "b" } }
@@ -43,7 +44,7 @@ class KotlinTargetHierarchyDescriptorTest {
group("groupA") group("groupA")
} }
}, },
descriptor.buildKotlinTargetHierarchy(targetA.compilations.main) template.buildHierarchy(targetA.compilations.main)
) )
assertEquals( assertEquals(
@@ -52,18 +53,18 @@ class KotlinTargetHierarchyDescriptorTest {
group("groupB") group("groupB")
} }
}, },
descriptor.buildKotlinTargetHierarchy(targetB.compilations.main) template.buildHierarchy(targetB.compilations.main)
) )
/* targetC is not mentioned in hierarchy description */ /* targetC is not mentioned in hierarchy description */
assertNull( assertNull(
descriptor.buildKotlinTargetHierarchy(targetC.compilations.main) template.buildHierarchy(targetC.compilations.main)
) )
} }
@Test @Test
fun `test - extend`() = project.runLifecycleAwareTest { fun `test - extend`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { group("base") }.extend { val template = KotlinHierarchyTemplate { group("base") }.extend {
group("base") { group("base") {
group("extension") { group("extension") {
withCompilations { true } withCompilations { true }
@@ -77,14 +78,14 @@ class KotlinTargetHierarchyDescriptorTest {
group("extension") group("extension")
} }
}, },
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.getByName("main")) template.buildHierarchy(kotlin.linuxX64().compilations.getByName("main"))
) )
} }
@Test @Test
fun `test - extend - with new root`() = project.runLifecycleAwareTest { fun `test - extend - with new root`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { group("base") }.extend { val template = KotlinHierarchyTemplate { group("base") }.extend {
group("newRoot") { group("newRoot") {
group("base") { group("base") {
group("extension") { group("extension") {
@@ -102,14 +103,14 @@ class KotlinTargetHierarchyDescriptorTest {
} }
} }
}, },
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.main) template.buildHierarchy(kotlin.linuxX64().compilations.main)
) )
} }
@Test @Test
fun `test - extend - with two new roots and two extensions`() = project.runLifecycleAwareTest { fun `test - extend - with two new roots and two extensions`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { group("base") } val template = KotlinHierarchyTemplate { group("base") }
.extend { .extend {
group("newRoot1") { group("newRoot1") {
group("base") { 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( assertEquals(
hierarchy { hierarchy {
@@ -149,7 +150,7 @@ class KotlinTargetHierarchyDescriptorTest {
}, hierarchy }, hierarchy
) )
fun KotlinTargetHierarchyTree.collectChildren(): List<KotlinTargetHierarchyTree> { fun KotlinHierarchy.collectChildren(): List<KotlinHierarchy> {
return children.toList() + children.flatMap { it.collectChildren() } return children.toList() + children.flatMap { it.collectChildren() }
} }
@@ -165,7 +166,7 @@ class KotlinTargetHierarchyDescriptorTest {
@Test @Test
fun `test - cycle`() = project.runLifecycleAwareTest { fun `test - cycle`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { val template = KotlinHierarchyTemplate {
group("x") { // decoy 1 group("x") { // decoy 1
group("a") { group("a") {
group("xx") // decoy 2 group("xx") // decoy 2
@@ -183,8 +184,8 @@ class KotlinTargetHierarchyDescriptorTest {
} }
} }
val cycleStack = assertFailsWith<CyclicKotlinTargetHierarchyException> { val cycleStack = assertFailsWith<CyclicKotlinHierarchyException> {
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.main) template.buildHierarchy(kotlin.linuxX64().compilations.main)
}.cycle }.cycle
assertEquals( assertEquals(
@@ -196,7 +197,7 @@ class KotlinTargetHierarchyDescriptorTest {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@Test @Test
fun `test - filterCompilations`() = project.runLifecycleAwareTest { fun `test - filterCompilations`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { val template = KotlinHierarchyTemplate {
filterCompilations { it.name in setOf("a", "b") } filterCompilations { it.name in setOf("a", "b") }
common { common {
group("x") { group("x") {
@@ -211,36 +212,36 @@ class KotlinTargetHierarchyDescriptorTest {
group("x") group("x")
} }
}, },
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")) template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("a"))
) )
assertEquals( assertEquals(
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")), template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")),
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")) template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("b"))
) )
assertNull( assertNull(
descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("c")) template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("c"))
) )
} }
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@Test @Test
fun `test - filterCompilations - include them again`() = project.runLifecycleAwareTest { fun `test - filterCompilations - include them again`() = project.runLifecycleAwareTest {
val descriptor = KotlinTargetHierarchyDescriptor { val template = KotlinHierarchyTemplate {
withCompilations { true } withCompilations { true }
filterCompilations { it.name == "a" } filterCompilations { it.name == "a" }
} }
assertNotNull(descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("a"))) assertNotNull(template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("a")))
assertNull(descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("b"))) assertNull(template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
val extended = descriptor.extend { val extended = template.extend {
withCompilations { true } // <- adds all compilations back again! withCompilations { true } // <- adds all compilations back again!
} }
assertNull(descriptor.buildKotlinTargetHierarchy(kotlin.linuxX64().compilations.maybeCreate("b"))) assertNull(template.buildHierarchy(kotlin.linuxX64().compilations.maybeCreate("b")))
assertNotNull(extended.buildKotlinTargetHierarchy(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)) 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() return TestHierarchyBuilder(Node.Root).also(build).build()
} }
@@ -26,7 +26,7 @@ class KotlinMetadataTargetCompilationsTest {
kotlin.jvm() kotlin.jvm()
kotlin.linuxX64() kotlin.linuxX64()
kotlin.linuxArm64() kotlin.linuxArm64()
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
project.runLifecycleAwareTest { project.runLifecycleAwareTest {
val target = kotlin.metadata() as KotlinMetadataTarget val target = kotlin.metadata() as KotlinMetadataTarget
@@ -46,7 +46,7 @@ class KotlinMetadataTargetCompilationsTest {
val project = buildProjectWithMPP() val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension val kotlin = project.multiplatformExtension
kotlin.jvm() kotlin.jvm()
kotlin.targetHierarchy.default() kotlin.applyDefaultHierarchyTemplate()
project.runLifecycleAwareTest { project.runLifecycleAwareTest {
val target = kotlin.metadata() as KotlinMetadataTarget val target = kotlin.metadata() as KotlinMetadataTarget
@@ -58,7 +58,7 @@ class KotlinNativeCompilationModuleNameTest {
} }
) { ) {
with(multiplatformExtension) { with(multiplatformExtension) {
targetHierarchy.default() applyDefaultHierarchyTemplate()
linuxX64() linuxX64()
linuxArm64() linuxArm64()
} }
@@ -18,7 +18,7 @@ class KotlinSourceSetTreeDependsOnMismatchTest {
private fun checkDiagnostics(configure: KotlinMultiplatformExtension.() -> Unit): List<ToolingDiagnostic> { private fun checkDiagnostics(configure: KotlinMultiplatformExtension.() -> Unit): List<ToolingDiagnostic> {
val project = buildProjectWithMPP { val project = buildProjectWithMPP {
kotlin { kotlin {
targetHierarchy.default() applyDefaultHierarchyTemplate()
androidTarget() androidTarget()
project.androidApplication { compileSdk = 32 } project.androidApplication { compileSdk = 32 }
iosX64(); iosArm64(); iosSimulatorArm64() iosX64(); iosArm64(); iosSimulatorArm64()
@@ -24,7 +24,7 @@ import kotlin.test.assertNotNull
class SourceSetVisibilityInferenceTest { class SourceSetVisibilityInferenceTest {
private val project = buildProjectWithMPP() private val project = buildProjectWithMPP()
private val kotlin = project.multiplatformExtension.apply { private val kotlin = project.multiplatformExtension.apply {
targetHierarchy.default() applyDefaultHierarchyTemplate()
} }
@Test @Test