Implement source sets visibility inference via associate compilations
Add non-public API for the IDE to query additional visible source sets for each source set. Implement visibility inference via associate compilation links. Implement visibility requirements for source sets and requirements satisfaction checks in Gradle build.
This commit is contained in:
+3
@@ -42,5 +42,8 @@ interface KotlinSourceSet : Named, HasKotlinDependencies {
|
||||
|
||||
val customSourceFilesExtensions: Iterable<String> // lazy iterable expected
|
||||
|
||||
val requiresVisibilityOf: Set<KotlinSourceSet>
|
||||
fun requiresVisibilityOf(other: KotlinSourceSet)
|
||||
|
||||
fun addCustomSourceFilesExtensions(extensions: List<String>) {}
|
||||
}
|
||||
+8
-3
@@ -21,12 +21,13 @@ import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
|
||||
import org.gradle.api.tasks.compile.AbstractCompile
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.configureOrCreate
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.checkSourceSetVisibilityRequirements
|
||||
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
@@ -91,8 +92,6 @@ class KotlinMultiplatformPlugin(
|
||||
setupCompilerPluginOptions(project)
|
||||
|
||||
project.pluginManager.apply(ScriptingGradleSubplugin::class.java)
|
||||
|
||||
UnusedSourceSetsChecker.checkSourceSets(project)
|
||||
}
|
||||
|
||||
private fun setupCompilerPluginOptions(project: Project) {
|
||||
@@ -256,6 +255,12 @@ class KotlinMultiplatformPlugin(
|
||||
sourceSets.findByName(testCompilation.defaultSourceSetName)?.dependsOn(test)
|
||||
}
|
||||
}
|
||||
|
||||
UnusedSourceSetsChecker.checkSourceSets(project)
|
||||
|
||||
project.whenEvaluated {
|
||||
checkSourceSetVisibilityRequirements(project)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+14
-2
@@ -16,9 +16,8 @@ import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.GranularMetadataTransformation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinProjectStructureMetadata
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
@@ -119,6 +118,15 @@ class DefaultKotlinSourceSet(
|
||||
|
||||
internal val dependencyTransformations: MutableMap<KotlinDependencyScope, GranularMetadataTransformation> = mutableMapOf()
|
||||
|
||||
private val _requiresVisibilityOf = mutableSetOf<KotlinSourceSet>()
|
||||
|
||||
override val requiresVisibilityOf: MutableSet<KotlinSourceSet>
|
||||
get() = Collections.unmodifiableSet(_requiresVisibilityOf)
|
||||
|
||||
override fun requiresVisibilityOf(other: KotlinSourceSet) {
|
||||
requiresVisibilityOf += other
|
||||
}
|
||||
|
||||
//region IDE import for Granular source sets metadata
|
||||
|
||||
data class MetadataDependencyTransformation(
|
||||
@@ -141,6 +149,10 @@ class DefaultKotlinSourceSet(
|
||||
return getDependenciesTransformation(scope)
|
||||
}
|
||||
|
||||
@Suppress("unused") // Used in IDE import
|
||||
fun getAdditionalVisibleSourceSets(): Set<KotlinSourceSet> =
|
||||
getVisibleSourceSetsFromAssociateCompilations(project, this)
|
||||
|
||||
internal fun getDependenciesTransformation(scope: KotlinDependencyScope): Iterable<MetadataDependencyTransformation> {
|
||||
val metadataDependencyResolutionByModule =
|
||||
dependencyTransformations[scope]?.metadataDependencyResolutions
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.sources
|
||||
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
||||
|
||||
fun getSourceSetsFromAssociatedCompilations(fromCompilation: KotlinCompilation<*>): Map<KotlinCompilation<*>, Set<KotlinSourceSet>> =
|
||||
fromCompilation.associateWithTransitiveClosure.associate { it to it.allKotlinSourceSets }
|
||||
|
||||
fun getVisibleSourceSetsFromAssociateCompilations(
|
||||
project: Project,
|
||||
sourceSet: KotlinSourceSet
|
||||
) = getVisibleSourceSetsFromAssociateCompilations(
|
||||
CompilationSourceSetUtil.compilationsBySourceSets(project).getValue(sourceSet)
|
||||
)
|
||||
|
||||
internal fun getVisibleSourceSetsFromAssociateCompilations(
|
||||
participatesInCompilations: Set<KotlinCompilation<*>>
|
||||
): Set<KotlinSourceSet> {
|
||||
val visibleInCompilations = participatesInCompilations.map {
|
||||
val sourceSetsInAssociatedCompilations = getSourceSetsFromAssociatedCompilations(it)
|
||||
when (sourceSetsInAssociatedCompilations.size) {
|
||||
0 -> emptySet()
|
||||
1 -> sourceSetsInAssociatedCompilations.values.single()
|
||||
else -> mutableSetOf<KotlinSourceSet>().apply {
|
||||
for ((_, sourceSets) in sourceSetsInAssociatedCompilations) {
|
||||
addAll(sourceSets)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intersect the sets of source sets from the compilations:
|
||||
return when (visibleInCompilations.size) {
|
||||
0 -> emptySet()
|
||||
1 -> visibleInCompilations.single()
|
||||
else -> visibleInCompilations.first().toMutableSet().apply {
|
||||
visibleInCompilations.subList(1, visibleInCompilations.size).forEach { retainAll(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnsatisfiedSourceSetVisibilityException(
|
||||
val sourceSet: KotlinSourceSet,
|
||||
val compilations: Set<KotlinCompilation<*>>,
|
||||
val visibleSourceSets: Set<KotlinSourceSet>,
|
||||
val requiredButNotVisible: Set<KotlinSourceSet>
|
||||
) : GradleException() {
|
||||
|
||||
override val message: String?
|
||||
get() = buildString {
|
||||
fun singularOrPlural(collection: Collection<*>, singular: String, plural: String = singular + "s") =
|
||||
if (collection.size == 1) singular else plural
|
||||
|
||||
fun compilationWithTarget(compilation: KotlinCompilation<*>) = "${compilation.name} (target ${compilation.target.name})"
|
||||
|
||||
append(
|
||||
"The source set ${sourceSet.name} requires visibility of the " +
|
||||
singularOrPlural(requiredButNotVisible, "source set", "source sets:") + " " +
|
||||
"${requiredButNotVisible.joinToString()}. " +
|
||||
"This requirement was not satisfied.\n\n"
|
||||
)
|
||||
|
||||
append("${sourceSet.name} takes part in the ${singularOrPlural(compilations, "compilation")}:\n")
|
||||
|
||||
fun appendCompilationRecursively(compilation: KotlinCompilation<*>, depth: Int) {
|
||||
val isAssociatedCompilation = depth > 0
|
||||
|
||||
val sourceSetsInAssociatedCompilations =
|
||||
getSourceSetsFromAssociatedCompilations(compilation)
|
||||
val allKotlinSourceSets = compilation.allKotlinSourceSets
|
||||
|
||||
val indent = " ".repeat(depth + 1)
|
||||
|
||||
val prefix = if (isAssociatedCompilation)
|
||||
"$indent- ${"indirectly ".takeIf { depth > 1 }.orEmpty()}associated with"
|
||||
else
|
||||
"$indent-"
|
||||
|
||||
append("$prefix ${compilationWithTarget(compilation)}")
|
||||
|
||||
append(
|
||||
if (isAssociatedCompilation)
|
||||
", which compiles" +
|
||||
singularOrPlural(allKotlinSourceSets, "source set ", "source sets: ") +
|
||||
allKotlinSourceSets.joinToString { it.name } +
|
||||
"\n"
|
||||
else "\n"
|
||||
)
|
||||
|
||||
compilation.associateWith.forEach { appendCompilationRecursively(it, depth + 1) }
|
||||
|
||||
if (!isAssociatedCompilation) {
|
||||
val missingRequiredSourceSets = requiredButNotVisible.filter { missingSourceSet ->
|
||||
sourceSetsInAssociatedCompilations.values.none { missingSourceSet in it }
|
||||
}
|
||||
|
||||
if (missingRequiredSourceSets.isEmpty()) {
|
||||
append("${indent}The compilation ${compilationWithTarget(compilation)} requires no changes.\n")
|
||||
} else {
|
||||
append(
|
||||
"${indent}To ensure the required visibility, the compilation " + compilationWithTarget(compilation) +
|
||||
"must have a direct or indirect associate that compiles the source " +
|
||||
singularOrPlural(missingRequiredSourceSets, "set ", "sets: ") +
|
||||
missingRequiredSourceSets.joinToString() + "\n"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compilations.forEach {
|
||||
appendCompilationRecursively(it, 0)
|
||||
append("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkSourceSetVisibilityRequirements(
|
||||
project: Project
|
||||
) = checkSourceSetVisibilityRequirements(
|
||||
project.kotlinExtension.sourceSets,
|
||||
CompilationSourceSetUtil.compilationsBySourceSets(project)
|
||||
)
|
||||
|
||||
internal fun checkSourceSetVisibilityRequirements(
|
||||
sourceSets: Iterable<KotlinSourceSet>,
|
||||
compilationsBySourceSet: Map<KotlinSourceSet, Set<KotlinCompilation<*>>>
|
||||
) {
|
||||
sourceSets.forEach { sourceSet ->
|
||||
val requiredVisibility = sourceSet.requiresVisibilityOf
|
||||
val inferredVisibility =
|
||||
getVisibleSourceSetsFromAssociateCompilations(compilationsBySourceSet[sourceSet].orEmpty())
|
||||
|
||||
val requiredButNotVisible = requiredVisibility - inferredVisibility //TODO minus dependsOn?
|
||||
|
||||
if (requiredButNotVisible.isNotEmpty()) {
|
||||
val compilations = compilationsBySourceSet.getValue(sourceSet)
|
||||
|
||||
throw UnsatisfiedSourceSetVisibilityException(
|
||||
sourceSet,
|
||||
compilations,
|
||||
inferredVisibility,
|
||||
requiredButNotVisible
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.sources
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class SourceSetVisibilityTest {
|
||||
@Test
|
||||
fun testBasicSuccessful(): Unit = with(SourceSetCompilationDsl()) {
|
||||
val commonMain = sourceSet("commonMain")
|
||||
val jvmMain = sourceSet("jvmMain", commonMain)
|
||||
|
||||
val commonTest = sourceSet("commonTest") {
|
||||
requiresVisibilityOf(commonMain)
|
||||
}
|
||||
val jvmTest = sourceSet("jvmTest", commonTest) {
|
||||
requiresVisibilityOf(jvmMain)
|
||||
}
|
||||
|
||||
val jvmMainCompilation = compilation("jvm/main", jvmMain)
|
||||
compilation("jvm/test", jvmTest, jvmMainCompilation)
|
||||
|
||||
checkInferredSourceSetsVisibility(jvmTest.name, commonMain.name, jvmMain.name)
|
||||
|
||||
// should not throw exception
|
||||
checkSourceSetVisibilityRequirements(sourceSets, compilationsBySourceSets)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFailureWithNoAssociation(): Unit = with(SourceSetCompilationDsl()) {
|
||||
val commonMain = sourceSet("commonMain")
|
||||
val jvmMain = sourceSet("jvmMain", commonMain)
|
||||
|
||||
val commonTest = sourceSet("commonTest") {
|
||||
requiresVisibilityOf(commonMain)
|
||||
}
|
||||
val jvmTest = sourceSet("jvmTest", commonTest) {
|
||||
requiresVisibilityOf(jvmMain)
|
||||
}
|
||||
|
||||
compilation("jvm/main", jvmMain)
|
||||
val jvmTestCompilation = compilation("jvm/test", jvmTest) // note: no association with jvmMainCompilation
|
||||
|
||||
checkInferredSourceSetsVisibility("jvmTest", *arrayOf())
|
||||
|
||||
assertFailsWith<UnsatisfiedSourceSetVisibilityException> {
|
||||
checkSourceSetVisibilityRequirements(setOf(jvmTest), compilationsBySourceSets)
|
||||
}.apply {
|
||||
assertEquals(jvmTest, sourceSet)
|
||||
assertEquals(emptySet(), visibleSourceSets)
|
||||
assertEquals(setOf(jvmMain), requiredButNotVisible)
|
||||
assertEquals(setOf(jvmTestCompilation), compilations)
|
||||
}
|
||||
|
||||
assertFailsWith<UnsatisfiedSourceSetVisibilityException> {
|
||||
checkSourceSetVisibilityRequirements(setOf(commonTest), compilationsBySourceSets)
|
||||
}.apply {
|
||||
assertEquals(commonTest, sourceSet)
|
||||
assertEquals(emptySet(), visibleSourceSets)
|
||||
assertEquals(setOf(commonMain), requiredButNotVisible)
|
||||
assertEquals(setOf(jvmTestCompilation), compilations)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SourceSetCompilationDsl.checkInferredSourceSetsVisibility(
|
||||
forSourceSetName: String,
|
||||
vararg expectedVisibleSourceSetNames: String
|
||||
) = assertEquals(
|
||||
setOf(*expectedVisibleSourceSetNames),
|
||||
getVisibleSourceSetsFromAssociateCompilations(
|
||||
compilationsBySourceSets.getValue(sourceSetsByName.getValue(forSourceSetName))
|
||||
).mapTo(mutableSetOf<String>()) { it.name }
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testInferenceForHierarchy() = with(SourceSetCompilationDsl()) {
|
||||
for (suffix in listOf("Main", "Test")) {
|
||||
val common = sourceSet("common$suffix")
|
||||
val jvmAndJs = sourceSet("jvmAndJs$suffix", common) {
|
||||
sourceSetsByName["jvmAndJsMain"]?.let(this::requiresVisibilityOf)
|
||||
}
|
||||
val linuxAndJs = sourceSet("linuxAndJs$suffix", common) {
|
||||
sourceSetsByName["linuxAndJsMain"]?.let(this::requiresVisibilityOf)
|
||||
}
|
||||
val jvm = sourceSet("jvm$suffix", common, jvmAndJs) {
|
||||
sourceSetsByName["jvmMain"]?.let(this::requiresVisibilityOf)
|
||||
}
|
||||
val linux = sourceSet("linux$suffix", common, linuxAndJs) {
|
||||
sourceSetsByName["linuxMain"]?.let(this::requiresVisibilityOf)
|
||||
}
|
||||
val js = sourceSet("js$suffix", common, jvmAndJs, linuxAndJs) {
|
||||
sourceSetsByName["jsMain"]?.let(this::requiresVisibilityOf)
|
||||
}
|
||||
|
||||
compilation("jvm / $suffix", jvm, *listOfNotNull(compilationsByName["jvm / Main"]).toTypedArray())
|
||||
compilation("linux / $suffix", linux, *listOfNotNull(compilationsByName["linux / Main"]).toTypedArray())
|
||||
compilation("js / $suffix", js, *listOfNotNull(compilationsByName["js / Main"]).toTypedArray())
|
||||
}
|
||||
|
||||
checkInferredSourceSetsVisibility("commonMain", *arrayOf())
|
||||
checkInferredSourceSetsVisibility("jvmMain", *arrayOf())
|
||||
checkInferredSourceSetsVisibility("jvmAndJsMain", *arrayOf())
|
||||
|
||||
checkInferredSourceSetsVisibility("commonTest", "commonMain")
|
||||
checkInferredSourceSetsVisibility("jvmAndJsTest", "commonMain", "jvmAndJsMain")
|
||||
checkInferredSourceSetsVisibility("linuxAndJsTest", "commonMain", "linuxAndJsMain")
|
||||
checkInferredSourceSetsVisibility("jvmTest", "commonMain", "jvmAndJsMain", "jvmMain")
|
||||
|
||||
checkSourceSetVisibilityRequirements(sourceSets, compilationsBySourceSets)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInferenceThroughIndirectAssociation(): Unit = with(SourceSetCompilationDsl()) {
|
||||
for ((previousSuffix, suffix) in listOf(null, "Main", "Test", "IntegrationTest").zipWithNext()) {
|
||||
val common = sourceSet("common$suffix") {
|
||||
if (previousSuffix != null) requiresVisibilityOf(sourceSetsByName.getValue("common$previousSuffix"))
|
||||
}
|
||||
val jvm = sourceSet("jvm$suffix", common) {
|
||||
if (previousSuffix != null) requiresVisibilityOf(sourceSetsByName.getValue("jvm$previousSuffix"))
|
||||
}
|
||||
val js = sourceSet("js$suffix", common) {
|
||||
if (previousSuffix != null) requiresVisibilityOf(sourceSetsByName.getValue("js$previousSuffix"))
|
||||
}
|
||||
|
||||
compilation("jvm / $suffix", jvm, *listOfNotNull(compilationsByName["jvm / $previousSuffix"]).toTypedArray())
|
||||
compilation("js / $suffix", js, *listOfNotNull(compilationsByName["js / $previousSuffix"]).toTypedArray())
|
||||
}
|
||||
|
||||
checkInferredSourceSetsVisibility("commonIntegrationTest", "commonMain", "commonTest")
|
||||
checkInferredSourceSetsVisibility("jvmIntegrationTest", "commonMain", "jvmMain", "commonTest", "jvmTest")
|
||||
|
||||
checkSourceSetVisibilityRequirements(sourceSets, compilationsBySourceSets)
|
||||
|
||||
// Now break visibility between *Test and *Main:
|
||||
|
||||
compilationsByName.getValue("jvm / Test").associateWith.clear()
|
||||
compilationsByName.getValue("js / Test").associateWith.clear()
|
||||
val commonIntegrationTest = sourceSetsByName.getValue("commonIntegrationTest")
|
||||
commonIntegrationTest.requiresVisibilityOf(sourceSetsByName.getValue("commonMain"))
|
||||
|
||||
assertFailsWith<UnsatisfiedSourceSetVisibilityException> {
|
||||
checkSourceSetVisibilityRequirements(setOf(commonIntegrationTest), compilationsBySourceSets)
|
||||
}.apply {
|
||||
assertEquals(commonIntegrationTest, this.sourceSet)
|
||||
assertEquals(setOf("commonTest"), visibleSourceSets.map { it.name }.toSet())
|
||||
assertEquals(setOf("commonMain"), requiredButNotVisible.map { it.name }.toSet())
|
||||
assertEquals(setOf("jvm / IntegrationTest", "js / IntegrationTest"), compilations.map { it.name }.toSet())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFailureWithPlatformSpecificRequirement(): Unit = with(SourceSetCompilationDsl()) {
|
||||
val commonMain = sourceSet("commonMain")
|
||||
val jvmMain = sourceSet("jvmMain", commonMain)
|
||||
val jsMain = sourceSet("jvmMain", commonMain)
|
||||
|
||||
val commonTest = sourceSet("commonTest") {
|
||||
requiresVisibilityOf(jvmMain) // <- invalid requirement!
|
||||
}
|
||||
val jvmTest = sourceSet("jvmTest", commonTest) {
|
||||
requiresVisibilityOf(jvmMain)
|
||||
}
|
||||
val jsTest = sourceSet("jsTest", commonTest) {
|
||||
requiresVisibilityOf(jsMain)
|
||||
}
|
||||
|
||||
val jvmMainCompilation = compilation("jvm / main", jvmMain)
|
||||
val jsMainCompilation = compilation("js / main", jsMain)
|
||||
val jvmTestCompilation = compilation("jvm / test", jvmTest, jvmMainCompilation)
|
||||
val jsTestCompilation = compilation("js / test", jsTest, jsMainCompilation)
|
||||
|
||||
assertFailsWith<UnsatisfiedSourceSetVisibilityException> {
|
||||
checkSourceSetVisibilityRequirements(setOf(commonTest), compilationsBySourceSets)
|
||||
}.apply {
|
||||
assertEquals(commonTest, this.sourceSet)
|
||||
assertEquals(setOf(commonMain), visibleSourceSets)
|
||||
assertEquals(setOf(jvmMain), requiredButNotVisible)
|
||||
assertEquals(setOf(jvmTestCompilation, jsTestCompilation), compilations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SourceSetCompilationDsl {
|
||||
val compilations: Set<MockKotlinCompilation> get() = compilationsByName.values.toSet()
|
||||
val sourceSets: Set<MockKotlinSourceSet> get() = sourceSetsByName.values.toSet()
|
||||
|
||||
val sourceSetsByName = mutableMapOf<String, MockKotlinSourceSet>()
|
||||
val compilationsByName = mutableMapOf<String, MockKotlinCompilation>()
|
||||
|
||||
val compilationsBySourceSets: Map<KotlinSourceSet, Set<KotlinCompilation<*>>>
|
||||
get() = mutableMapOf<KotlinSourceSet, MutableSet<KotlinCompilation<*>>>().apply {
|
||||
compilations.forEach { compilation ->
|
||||
compilation.allKotlinSourceSets.filterIsInstance<MockKotlinSourceSet>().forEach { sourceSet ->
|
||||
getOrPut(sourceSet) { mutableSetOf() }.add(compilation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun sourceSet(
|
||||
name: String,
|
||||
vararg dependsOn: MockKotlinSourceSet,
|
||||
configure: MockKotlinSourceSet.() -> Unit = { }
|
||||
) = MockKotlinSourceSet(name).apply {
|
||||
dependsOn.forEach { dependsOn(it) }
|
||||
configure()
|
||||
sourceSetsByName[name] = this
|
||||
}
|
||||
|
||||
fun compilation(
|
||||
name: String,
|
||||
defaultSourceSet: KotlinSourceSet,
|
||||
vararg associateWith: MockKotlinCompilation,
|
||||
configure: MockKotlinCompilation.() -> Unit = { }
|
||||
) = MockKotlinCompilation(name, defaultSourceSet).apply {
|
||||
associateWith.forEach { associateWith(it) }
|
||||
configure()
|
||||
compilationsByName[name] = this
|
||||
}
|
||||
}
|
||||
|
||||
class MockKotlinSourceSet(private val name: String) : KotlinSourceSet {
|
||||
override fun getName(): String = name
|
||||
|
||||
override val dependsOn: MutableSet<KotlinSourceSet> = mutableSetOf()
|
||||
|
||||
override val requiresVisibilityOf: MutableSet<KotlinSourceSet> = mutableSetOf()
|
||||
|
||||
override fun dependsOn(other: KotlinSourceSet) {
|
||||
dependsOn += other
|
||||
}
|
||||
|
||||
override fun requiresVisibilityOf(other: KotlinSourceSet) {
|
||||
requiresVisibilityOf += other
|
||||
}
|
||||
|
||||
//region Not implemented
|
||||
override val kotlin: SourceDirectorySet get() = throw UnsupportedOperationException()
|
||||
|
||||
override fun kotlin(configureClosure: Closure<Any?>): SourceDirectorySet = throw UnsupportedOperationException()
|
||||
override val resources: SourceDirectorySet get() = throw UnsupportedOperationException()
|
||||
override val languageSettings: LanguageSettingsBuilder get() = throw UnsupportedOperationException()
|
||||
override fun languageSettings(configureClosure: Closure<Any?>): LanguageSettingsBuilder = languageSettings
|
||||
override val apiMetadataConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val implementationMetadataConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val compileOnlyMetadataConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val runtimeOnlyMetadataConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val customSourceFilesExtensions: Iterable<String> get() = throw UnsupportedOperationException()
|
||||
override fun dependencies(configure: KotlinDependencyHandler.() -> Unit) = throw UnsupportedOperationException()
|
||||
override fun dependencies(configureClosure: Closure<Any?>) = throw UnsupportedOperationException()
|
||||
override val apiConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val implementationConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val compileOnlyConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val runtimeOnlyConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
//endregion
|
||||
}
|
||||
|
||||
class MockKotlinCompilation(
|
||||
override val compilationName: String,
|
||||
override val defaultSourceSet: KotlinSourceSet
|
||||
) : KotlinCompilation<KotlinCommonOptions> {
|
||||
override val kotlinSourceSets: Set<KotlinSourceSet> = setOf(defaultSourceSet)
|
||||
|
||||
override val allKotlinSourceSets: Set<KotlinSourceSet>
|
||||
get() = mutableSetOf<KotlinSourceSet>().apply {
|
||||
fun visit(sourceSet: KotlinSourceSet) {
|
||||
if (add(sourceSet)) {
|
||||
sourceSet.dependsOn.forEach(::visit)
|
||||
}
|
||||
}
|
||||
visit(defaultSourceSet)
|
||||
}
|
||||
|
||||
override fun source(sourceSet: KotlinSourceSet) = defaultSourceSet.dependsOn(sourceSet)
|
||||
|
||||
override fun associateWith(other: KotlinCompilation<*>) {
|
||||
associateWith += other
|
||||
}
|
||||
|
||||
override val associateWith: MutableSet<KotlinCompilation<*>> = mutableSetOf()
|
||||
|
||||
override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) = defaultSourceSet.run(configure)
|
||||
|
||||
//region Not implemented
|
||||
override val target: KotlinTarget get() = throw UnsupportedOperationException()
|
||||
|
||||
override fun getAttributes(): AttributeContainer = throw UnsupportedOperationException()
|
||||
override fun dependencies(configure: KotlinDependencyHandler.() -> Unit) = throw UnsupportedOperationException()
|
||||
override fun dependencies(configureClosure: Closure<Any?>) = throw UnsupportedOperationException()
|
||||
override val apiConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val implementationConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val compileOnlyConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override val runtimeOnlyConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override fun defaultSourceSet(configure: Closure<*>) = throw UnsupportedOperationException()
|
||||
override val compileDependencyConfigurationName: String get() = throw UnsupportedOperationException()
|
||||
override var compileDependencyFiles: FileCollection
|
||||
get() = throw UnsupportedOperationException()
|
||||
set(value) = throw UnsupportedOperationException()
|
||||
override val output: KotlinCompilationOutput get() = throw UnsupportedOperationException()
|
||||
override val compileKotlinTaskName: String get() = throw UnsupportedOperationException()
|
||||
override val compileKotlinTask: KotlinCompile<KotlinCommonOptions> get() = throw UnsupportedOperationException()
|
||||
override val kotlinOptions: KotlinCommonOptions get() = throw UnsupportedOperationException()
|
||||
override fun kotlinOptions(configure: KotlinCommonOptions.() -> Unit) = throw UnsupportedOperationException()
|
||||
override fun kotlinOptions(configure: Closure<*>) = throw UnsupportedOperationException()
|
||||
override fun attributes(configure: AttributeContainer.() -> Unit) = throw UnsupportedOperationException()
|
||||
override fun attributes(configure: Closure<*>) = throw UnsupportedOperationException()
|
||||
override val compileAllTaskName: String get() = throw UnsupportedOperationException()
|
||||
//endregion
|
||||
|
||||
override fun toString(): String = "compilation '${name}'"
|
||||
}
|
||||
Reference in New Issue
Block a user