[Gradle] Introduce KotlinTargetHierarchy.ModuleName as public concept
KT-34662
This commit is contained in:
committed by
Space Team
parent
78673885e5
commit
78751dcb55
+3
-3
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
|
|||||||
interface KotlinTargetHierarchyDsl {
|
interface KotlinTargetHierarchyDsl {
|
||||||
fun apply(
|
fun apply(
|
||||||
hierarchyDescriptor: KotlinTargetHierarchyDescriptor,
|
hierarchyDescriptor: KotlinTargetHierarchyDescriptor,
|
||||||
describeExtension: (KotlinTargetHierarchyBuilder.() -> Unit)? = null
|
describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,6 +80,6 @@ interface KotlinTargetHierarchyDsl {
|
|||||||
* @param describeExtension: Additional groups can be described to extend the 'default'/'natural' hierarchy:
|
* @param describeExtension: Additional groups can be described to extend the 'default'/'natural' hierarchy:
|
||||||
* @see KotlinTargetHierarchyDescriptor.extend
|
* @see KotlinTargetHierarchyDescriptor.extend
|
||||||
*/
|
*/
|
||||||
fun default(describeExtension: (KotlinTargetHierarchyBuilder.() -> Unit)? = null)
|
fun default(describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)? = null)
|
||||||
fun custom(describe: KotlinTargetHierarchyBuilder.() -> Unit)
|
fun custom(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit)
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
|
||||||
|
data class ModuleName(val name: String) {
|
||||||
|
override fun toString(): String = name
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val main = ModuleName("main")
|
||||||
|
val test = ModuleName("test")
|
||||||
|
val unitTest = ModuleName("unitTest")
|
||||||
|
val integrationTest = ModuleName("integrationTest")
|
||||||
|
val instrumentedTest = ModuleName("instrumentedTest")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
-2
@@ -8,16 +8,27 @@ import org.jetbrains.kotlin.konan.target.DEPRECATED_TARGET_MESSAGE
|
|||||||
@KotlinTargetsDsl
|
@KotlinTargetsDsl
|
||||||
@ExperimentalKotlinGradlePluginApi
|
@ExperimentalKotlinGradlePluginApi
|
||||||
interface KotlinTargetHierarchyBuilder {
|
interface KotlinTargetHierarchyBuilder {
|
||||||
|
|
||||||
|
interface Root : KotlinTargetHierarchyBuilder {
|
||||||
|
fun modules(vararg module: KotlinTargetHierarchy.ModuleName)
|
||||||
|
fun withModule(vararg module: KotlinTargetHierarchy.ModuleName)
|
||||||
|
fun excludeModule(vararg module: KotlinTargetHierarchy.ModuleName)
|
||||||
|
}
|
||||||
|
|
||||||
/* Declaring groups */
|
/* Declaring groups */
|
||||||
fun common(build: KotlinTargetHierarchyBuilder.() -> Unit) = group("common", build)
|
fun common(build: KotlinTargetHierarchyBuilder.() -> Unit) = group("common", build)
|
||||||
fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit = {})
|
fun group(name: String, build: KotlinTargetHierarchyBuilder.() -> Unit = {})
|
||||||
|
|
||||||
/* low-level APIs */
|
/* low-level APIs */
|
||||||
fun withCompilations(predicate: suspend (KotlinCompilation<*>) -> Boolean)
|
fun withCompilations(predicate: suspend (KotlinCompilation<*>) -> Boolean)
|
||||||
fun withoutCompilations(predicate: suspend (KotlinCompilation<*>) -> Boolean)
|
|
||||||
|
fun excludeCompilations(predicate: suspend (KotlinCompilation<*>) -> Boolean)
|
||||||
|
|
||||||
|
@Deprecated("Use 'excludeCompilations' instead", ReplaceWith("excludeCompilations(predicate)"))
|
||||||
|
fun withoutCompilations(predicate: suspend (KotlinCompilation<*>) -> Boolean) = excludeCompilations(predicate)
|
||||||
|
|
||||||
@Deprecated("Use plain 'withoutCompilations(!predicate) instead'", ReplaceWith("withoutCompilations { !predicate(it) }"))
|
@Deprecated("Use plain 'withoutCompilations(!predicate) instead'", ReplaceWith("withoutCompilations { !predicate(it) }"))
|
||||||
fun filterCompilations(predicate: (KotlinCompilation<*>) -> Boolean) = withoutCompilations { !predicate(it) }
|
fun filterCompilations(predicate: (KotlinCompilation<*>) -> Boolean) = excludeCompilations { !predicate(it) }
|
||||||
|
|
||||||
/* Convenient groups */
|
/* Convenient groups */
|
||||||
fun withNative()
|
fun withNative()
|
||||||
|
|||||||
+6
-6
@@ -9,23 +9,23 @@ import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
|||||||
|
|
||||||
@ExperimentalKotlinGradlePluginApi
|
@ExperimentalKotlinGradlePluginApi
|
||||||
interface KotlinTargetHierarchyDescriptor {
|
interface KotlinTargetHierarchyDescriptor {
|
||||||
fun describe(builder: KotlinTargetHierarchyBuilder)
|
fun describe(builder: KotlinTargetHierarchyBuilder.Root)
|
||||||
fun extend(describe: KotlinTargetHierarchyBuilder.() -> Unit): KotlinTargetHierarchyDescriptor
|
fun extend(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit): KotlinTargetHierarchyDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalKotlinGradlePluginApi
|
@ExperimentalKotlinGradlePluginApi
|
||||||
fun KotlinTargetHierarchyDescriptor(
|
fun KotlinTargetHierarchyDescriptor(
|
||||||
describe: KotlinTargetHierarchyBuilder.() -> Unit
|
describe: KotlinTargetHierarchyBuilder.Root.() -> Unit
|
||||||
): KotlinTargetHierarchyDescriptor {
|
): KotlinTargetHierarchyDescriptor {
|
||||||
return KotlinTargetHierarchyDescriptorImpl(describe)
|
return KotlinTargetHierarchyDescriptorImpl(describe)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalKotlinGradlePluginApi
|
@ExperimentalKotlinGradlePluginApi
|
||||||
private class KotlinTargetHierarchyDescriptorImpl(
|
private class KotlinTargetHierarchyDescriptorImpl(
|
||||||
private val describe: KotlinTargetHierarchyBuilder.() -> Unit
|
private val describe: KotlinTargetHierarchyBuilder.Root.() -> Unit
|
||||||
) : KotlinTargetHierarchyDescriptor {
|
) : KotlinTargetHierarchyDescriptor {
|
||||||
|
|
||||||
override fun extend(describe: KotlinTargetHierarchyBuilder.() -> Unit): KotlinTargetHierarchyDescriptor {
|
override fun extend(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit): KotlinTargetHierarchyDescriptor {
|
||||||
val sourceDescribe = this.describe
|
val sourceDescribe = this.describe
|
||||||
return KotlinTargetHierarchyDescriptor {
|
return KotlinTargetHierarchyDescriptor {
|
||||||
sourceDescribe()
|
sourceDescribe()
|
||||||
@@ -33,5 +33,5 @@ private class KotlinTargetHierarchyDescriptorImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun describe(builder: KotlinTargetHierarchyBuilder) = builder.describe()
|
override fun describe(builder: KotlinTargetHierarchyBuilder.Root) = builder.describe()
|
||||||
}
|
}
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.ModuleName
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.android.type
|
||||||
|
|
||||||
|
internal suspend fun ModuleName.Companion.orNull(compilation: KotlinCompilation<*>): ModuleName? =
|
||||||
|
when (compilation) {
|
||||||
|
is KotlinJvmAndroidCompilation -> orNull(compilation.target, compilation.androidVariant.type)
|
||||||
|
else -> when (compilation.name) {
|
||||||
|
"main" -> main
|
||||||
|
"test" -> test
|
||||||
|
else -> ModuleName(compilation.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal suspend fun ModuleName.Companion.orNull(
|
||||||
|
target: KotlinAndroidTarget,
|
||||||
|
variantType: AndroidVariantType
|
||||||
|
): ModuleName? = when (variantType) {
|
||||||
|
AndroidVariantType.Main ->
|
||||||
|
target.main.targetHierarchy.module.awaitFinalValue() ?: main
|
||||||
|
AndroidVariantType.UnitTest ->
|
||||||
|
target.unitTest.targetHierarchy.module.awaitFinalValue() ?: test
|
||||||
|
AndroidVariantType.InstrumentedTest ->
|
||||||
|
target.instrumentedTest.targetHierarchy.module.awaitFinalValue() ?: ModuleName("instrumentedTest")
|
||||||
|
AndroidVariantType.Unknown -> null
|
||||||
|
}
|
||||||
-82
@@ -1,82 +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.KotlinCompilation
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.android.type
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
|
||||||
import org.jetbrains.kotlin.tooling.core.withClosure
|
|
||||||
|
|
||||||
internal data class KotlinTargetHierarchy(
|
|
||||||
val node: Node, val children: Set<KotlinTargetHierarchy> = emptySet()
|
|
||||||
) {
|
|
||||||
|
|
||||||
val childrenClosure: Set<KotlinTargetHierarchy> =
|
|
||||||
children.withClosure<KotlinTargetHierarchy> { it.children }
|
|
||||||
|
|
||||||
sealed class Node {
|
|
||||||
abstract suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String?
|
|
||||||
|
|
||||||
object Root : Node() {
|
|
||||||
override suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String? = null
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Group(val name: String) : Node() {
|
|
||||||
override suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String? {
|
|
||||||
val moduleName = Module.orNull(compilation)?.name ?: return null
|
|
||||||
return lowerCamelCaseName(name, moduleName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun toString(): String = when (this) {
|
|
||||||
is Group -> name
|
|
||||||
is Root -> "<root>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Module(val name: String) {
|
|
||||||
override fun toString(): String = name
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val main = Module("main")
|
|
||||||
val test = Module("test")
|
|
||||||
private val instrumentedTest = Module("instrumentedTest")
|
|
||||||
|
|
||||||
suspend fun orNull(compilation: KotlinCompilation<*>): Module? = when (compilation) {
|
|
||||||
is KotlinJvmAndroidCompilation -> orNull(compilation.target, compilation.androidVariant.type)
|
|
||||||
else -> when (compilation.name) {
|
|
||||||
"main" -> main
|
|
||||||
"test" -> test
|
|
||||||
else -> Module(compilation.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun orNull(target: KotlinAndroidTarget, variantType: AndroidVariantType): Module? {
|
|
||||||
return when (variantType) {
|
|
||||||
AndroidVariantType.Main ->
|
|
||||||
Module(target.main.kotlinModuleName.awaitFinalValue() ?: return main)
|
|
||||||
|
|
||||||
AndroidVariantType.UnitTest ->
|
|
||||||
Module(target.unitTest.kotlinModuleName.awaitFinalValue() ?: return test)
|
|
||||||
|
|
||||||
AndroidVariantType.InstrumentedTest ->
|
|
||||||
Module(target.instrumentedTest.kotlinModuleName.awaitFinalValue() ?: return instrumentedTest)
|
|
||||||
|
|
||||||
AndroidVariantType.Unknown -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
if (children.isEmpty()) return node.toString()
|
|
||||||
return node.toString() + "\n" + children.joinToString("\n").prependIndent("----")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+44
-15
@@ -10,30 +10,29 @@ import org.jetbrains.kotlin.gradle.plugin.*
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmTargetDsl
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
|
|
||||||
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<*>): KotlinTargetHierarchy? {
|
internal suspend fun KotlinTargetHierarchyDescriptor.buildKotlinTargetHierarchy(compilation: KotlinCompilation<*>): KotlinTargetHierarchyTree? {
|
||||||
val context = KotlinTargetHierarchyBuilderImplContext(compilation)
|
val context = KotlinTargetHierarchyBuilderImplContext(compilation)
|
||||||
describe(context.getOrCreateBuilder(KotlinTargetHierarchy.Node.Root))
|
describe(context.root)
|
||||||
return context.build(KotlinTargetHierarchy.Node.Root)
|
return context.build(KotlinTargetHierarchyTree.Node.Root)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KotlinTargetHierarchyBuilderImplContext(private val compilation: KotlinCompilation<*>) {
|
private class KotlinTargetHierarchyBuilderImplContext(private val compilation: KotlinCompilation<*>) {
|
||||||
private val builders = hashMapOf<KotlinTargetHierarchy.Node, KotlinTargetHierarchyBuilderImpl>()
|
val root by lazy { KotlinTargetHierarchyBuilderRootImpl(getOrCreateBuilder(KotlinTargetHierarchyTree.Node.Root)) }
|
||||||
private val builtValues = hashMapOf<KotlinTargetHierarchy.Node, KotlinTargetHierarchy?>()
|
|
||||||
|
|
||||||
fun getOrCreateBuilder(node: KotlinTargetHierarchy.Node): KotlinTargetHierarchyBuilderImpl = builders.getOrPut(node) {
|
private val builders = hashMapOf<KotlinTargetHierarchyTree.Node, KotlinTargetHierarchyBuilderImpl>()
|
||||||
|
private val builtValues = hashMapOf<KotlinTargetHierarchyTree.Node, KotlinTargetHierarchyTree?>()
|
||||||
|
|
||||||
|
fun getOrCreateBuilder(node: KotlinTargetHierarchyTree.Node): KotlinTargetHierarchyBuilderImpl = builders.getOrPut(node) {
|
||||||
KotlinTargetHierarchyBuilderImpl(this, node)
|
KotlinTargetHierarchyBuilderImpl(this, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun build(node: KotlinTargetHierarchy.Node): KotlinTargetHierarchy? {
|
suspend fun build(node: KotlinTargetHierarchyTree.Node): KotlinTargetHierarchyTree? {
|
||||||
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
|
||||||
@@ -51,14 +50,44 @@ 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()
|
||||||
KotlinTargetHierarchy(node, directChildren)
|
KotlinTargetHierarchyTree(node, directChildren)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class KotlinTargetHierarchyBuilderRootImpl(
|
||||||
|
private val builder: KotlinTargetHierarchyBuilder
|
||||||
|
) : KotlinTargetHierarchyBuilder.Root, KotlinTargetHierarchyBuilder by builder {
|
||||||
|
|
||||||
|
private var modules: Set<KotlinTargetHierarchy.ModuleName>? = null
|
||||||
|
|
||||||
|
override fun modules(vararg module: KotlinTargetHierarchy.ModuleName) {
|
||||||
|
this.modules = module.toHashSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun withModule(vararg module: KotlinTargetHierarchy.ModuleName) {
|
||||||
|
this.modules = this.modules.orEmpty().plus(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun excludeModule(vararg module: KotlinTargetHierarchy.ModuleName) {
|
||||||
|
val modules = module.toHashSet()
|
||||||
|
if (modules.isEmpty()) return
|
||||||
|
if (this.modules == null) return
|
||||||
|
this.modules = this.modules.orEmpty() - modules
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
builder.excludeCompilations exclude@{ compilation ->
|
||||||
|
val modules = this.modules ?: return@exclude false
|
||||||
|
val module = KotlinTargetHierarchy.ModuleName.orNull(compilation) ?: return@exclude false
|
||||||
|
module !in modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KotlinTargetHierarchyBuilderImpl(
|
private class KotlinTargetHierarchyBuilderImpl(
|
||||||
val context: KotlinTargetHierarchyBuilderImplContext,
|
val context: KotlinTargetHierarchyBuilderImplContext,
|
||||||
val node: KotlinTargetHierarchy.Node,
|
val node: KotlinTargetHierarchyTree.Node,
|
||||||
) : KotlinTargetHierarchyBuilder {
|
) : KotlinTargetHierarchyBuilder {
|
||||||
|
|
||||||
val children = mutableSetOf<KotlinTargetHierarchyBuilderImpl>()
|
val children = mutableSetOf<KotlinTargetHierarchyBuilderImpl>()
|
||||||
@@ -74,7 +103,7 @@ private class KotlinTargetHierarchyBuilderImpl(
|
|||||||
this.excludePredicate = { previousExcludePredicate(it) && !predicate(it) }
|
this.excludePredicate = { previousExcludePredicate(it) && !predicate(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun withoutCompilations(predicate: suspend (KotlinCompilation<*>) -> Boolean) {
|
override fun excludeCompilations(predicate: suspend (KotlinCompilation<*>) -> Boolean) {
|
||||||
val previousIncludePredicate = this.includePredicate
|
val previousIncludePredicate = this.includePredicate
|
||||||
val previousExcludePredicate = this.excludePredicate
|
val previousExcludePredicate = this.excludePredicate
|
||||||
this.includePredicate = { previousIncludePredicate(it) && !predicate(it) }
|
this.includePredicate = { previousIncludePredicate(it) && !predicate(it) }
|
||||||
@@ -95,7 +124,7 @@ 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: KotlinTargetHierarchyBuilder.() -> Unit) {
|
||||||
val node = KotlinTargetHierarchy.Node.Group(name)
|
val node = KotlinTargetHierarchyTree.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()
|
||||||
@@ -273,6 +302,6 @@ private fun KotlinTargetHierarchyBuilderImpl.checkCyclicHierarchy(): Nothing? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class CyclicKotlinTargetHierarchyException(val cycle: List<KotlinTargetHierarchy.Node>) : InvalidUserCodeException(
|
internal class CyclicKotlinTargetHierarchyException(val cycle: List<KotlinTargetHierarchyTree.Node>) : InvalidUserCodeException(
|
||||||
"KotlinTargetHierarchy cycle detected: ${cycle.joinToString(" -> ")}"
|
"KotlinTargetHierarchy cycle detected: ${cycle.joinToString(" -> ")}"
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-4
@@ -23,21 +23,21 @@ internal class KotlinTargetHierarchyDslImpl(
|
|||||||
|
|
||||||
override fun apply(
|
override fun apply(
|
||||||
hierarchyDescriptor: KotlinTargetHierarchyDescriptor,
|
hierarchyDescriptor: KotlinTargetHierarchyDescriptor,
|
||||||
describeExtension: (KotlinTargetHierarchyBuilder.() -> Unit)?
|
describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)?
|
||||||
) {
|
) {
|
||||||
val descriptor = hierarchyDescriptor.extendIfNotNull(describeExtension)
|
val descriptor = hierarchyDescriptor.extendIfNotNull(describeExtension)
|
||||||
_appliedDescriptors.add(descriptor)
|
_appliedDescriptors.add(descriptor)
|
||||||
applyKotlinTargetHierarchy(descriptor, targets, sourceSets)
|
applyKotlinTargetHierarchy(descriptor, targets, sourceSets)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun default(describeExtension: (KotlinTargetHierarchyBuilder.() -> Unit)?) {
|
override fun default(describeExtension: (KotlinTargetHierarchyBuilder.Root.() -> Unit)?) {
|
||||||
apply(defaultKotlinTargetHierarchy, describeExtension)
|
apply(defaultKotlinTargetHierarchy, describeExtension)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun custom(describe: KotlinTargetHierarchyBuilder.() -> Unit) {
|
override fun custom(describe: KotlinTargetHierarchyBuilder.Root.() -> Unit) {
|
||||||
apply(KotlinTargetHierarchyDescriptor(describe))
|
apply(KotlinTargetHierarchyDescriptor(describe))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinTargetHierarchyDescriptor.extendIfNotNull(describe: (KotlinTargetHierarchyBuilder.() -> Unit)?) =
|
private fun KotlinTargetHierarchyDescriptor.extendIfNotNull(describe: (KotlinTargetHierarchyBuilder.Root.() -> Unit)?) =
|
||||||
if (describe == null) this else extend(describe)
|
if (describe == null) this else extend(describe)
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.KotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.tooling.core.withClosure
|
||||||
|
|
||||||
|
internal data class KotlinTargetHierarchyTree(
|
||||||
|
val node: Node, val children: Set<KotlinTargetHierarchyTree> = emptySet()
|
||||||
|
) {
|
||||||
|
|
||||||
|
val childrenClosure: Set<KotlinTargetHierarchyTree> =
|
||||||
|
children.withClosure<KotlinTargetHierarchyTree> { it.children }
|
||||||
|
|
||||||
|
sealed class Node {
|
||||||
|
abstract suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String?
|
||||||
|
|
||||||
|
object Root : Node() {
|
||||||
|
override suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Group(val name: String) : Node() {
|
||||||
|
override suspend fun sharedSourceSetName(compilation: KotlinCompilation<*>): String? {
|
||||||
|
val moduleName = KotlinTargetHierarchy.ModuleName.orNull(compilation)?.name ?: return null
|
||||||
|
return lowerCamelCaseName(name, moduleName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun toString(): String = when (this) {
|
||||||
|
is Group -> name
|
||||||
|
is Root -> "<root>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
if (children.isEmpty()) return node.toString()
|
||||||
|
return node.toString() + "\n" + children.joinToString("\n").prependIndent("----")
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -28,7 +28,7 @@ internal fun applyKotlinTargetHierarchy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun applyKotlinTargetHierarchy(
|
private suspend fun applyKotlinTargetHierarchy(
|
||||||
hierarchy: KotlinTargetHierarchy,
|
hierarchy: KotlinTargetHierarchyTree,
|
||||||
compilation: KotlinCompilation<*>,
|
compilation: KotlinCompilation<*>,
|
||||||
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>
|
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>
|
||||||
): KotlinSourceSet? {
|
): KotlinSourceSet? {
|
||||||
@@ -52,7 +52,7 @@ private suspend fun applyKotlinTargetHierarchy(
|
|||||||
|
|
||||||
private suspend fun createSharedSourceSetOrNull(
|
private suspend fun createSharedSourceSetOrNull(
|
||||||
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
|
sourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
|
||||||
node: KotlinTargetHierarchy.Node,
|
node: KotlinTargetHierarchyTree.Node,
|
||||||
compilation: KotlinCompilation<*>,
|
compilation: KotlinCompilation<*>,
|
||||||
): KotlinSourceSet? {
|
): KotlinSourceSet? {
|
||||||
val sharedSourceSetName = node.sharedSourceSetName(compilation) ?: return null
|
val sharedSourceSetName = node.sharedSourceSetName(compilation) ?: return null
|
||||||
|
|||||||
+2
-6
@@ -5,16 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
|
package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy.ModuleName
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchyDescriptor
|
||||||
|
|
||||||
private val defaultKotlinTargetHierarchyModules = hashSetOf(
|
|
||||||
KotlinTargetHierarchy.Module.main,
|
|
||||||
KotlinTargetHierarchy.Module.test
|
|
||||||
)
|
|
||||||
|
|
||||||
internal val defaultKotlinTargetHierarchy = KotlinTargetHierarchyDescriptor {
|
internal val defaultKotlinTargetHierarchy = KotlinTargetHierarchyDescriptor {
|
||||||
/* natural hierarchy is only applied to default 'main'/'test' compilations (by default) */
|
/* natural hierarchy is only applied to default 'main'/'test' compilations (by default) */
|
||||||
withoutCompilations { KotlinTargetHierarchy.Module.orNull(it) !in defaultKotlinTargetHierarchyModules }
|
withModule(ModuleName.main, ModuleName.test)
|
||||||
|
|
||||||
common {
|
common {
|
||||||
/* All compilations shall receive be added to the common group by default */
|
/* All compilations shall receive be added to the common group by default */
|
||||||
|
|||||||
+5
-5
@@ -10,8 +10,8 @@ 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.KotlinTargetHierarchyDescriptor
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.CyclicKotlinTargetHierarchyException
|
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.CyclicKotlinTargetHierarchyException
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchy
|
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyTree
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchy.Node
|
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyTree.Node
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.buildKotlinTargetHierarchy
|
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.buildKotlinTargetHierarchy
|
||||||
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
|
||||||
@@ -149,7 +149,7 @@ class KotlinTargetHierarchyDescriptorTest {
|
|||||||
}, hierarchy
|
}, hierarchy
|
||||||
)
|
)
|
||||||
|
|
||||||
fun KotlinTargetHierarchy.collectChildren(): List<KotlinTargetHierarchy> {
|
fun KotlinTargetHierarchyTree.collectChildren(): List<KotlinTargetHierarchyTree> {
|
||||||
return children.toList() + children.flatMap { it.collectChildren() }
|
return children.toList() + children.flatMap { it.collectChildren() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,9 +249,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(): KotlinTargetHierarchy = KotlinTargetHierarchy(node, children.map { it.build() }.toSet())
|
fun build(): KotlinTargetHierarchyTree = KotlinTargetHierarchyTree(node, children.map { it.build() }.toSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hierarchy(build: TestHierarchyBuilder.() -> Unit): KotlinTargetHierarchy {
|
private fun hierarchy(build: TestHierarchyBuilder.() -> Unit): KotlinTargetHierarchyTree {
|
||||||
return TestHierarchyBuilder(Node.Root).also(build).build()
|
return TestHierarchyBuilder(Node.Root).also(build).build()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user