Replace transitiveClosure (commonizer-api) with closure (tooling-core)
This commit is contained in:
committed by
Space
parent
530a3bb6ea
commit
14046b81ff
+2
-2
@@ -13,7 +13,7 @@ import org.gradle.api.file.SourceDirectorySet
|
||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
import org.jetbrains.kotlin.project.model.withRefinesClosure
|
||||
|
||||
interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, KotlinFragmentDependencyConfigurations, Named {
|
||||
override val kotlinSourceRoots: SourceDirectorySet
|
||||
@@ -59,4 +59,4 @@ interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, Ko
|
||||
}
|
||||
|
||||
val KotlinGradleFragment.refinesClosure: Set<KotlinGradleFragment>
|
||||
get() = (this as KotlinModuleFragment).refinesClosure.mapTo(mutableSetOf()) { it as KotlinGradleFragment }
|
||||
get() = (this as KotlinModuleFragment).withRefinesClosure.mapTo(mutableSetOf()) { it as KotlinGradleFragment }
|
||||
|
||||
+11
-11
@@ -11,8 +11,8 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllSourceSetsDependingOn
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.findSourceSetsDependingOn
|
||||
import org.junit.Test
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.assertEquals
|
||||
@@ -45,17 +45,17 @@ class ResolveKotlinSourceSetsTest {
|
||||
|
||||
assertEquals(
|
||||
setOf(nativeMain, linuxMain, macosMain, jvmMain),
|
||||
kotlin.resolveAllSourceSetsDependingOn(commonMain)
|
||||
kotlin.findSourceSetsDependingOn(commonMain)
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf(linuxMain, macosMain),
|
||||
kotlin.resolveAllSourceSetsDependingOn(nativeMain)
|
||||
kotlin.findSourceSetsDependingOn(nativeMain)
|
||||
)
|
||||
|
||||
assertEquals(emptySet(), kotlin.resolveAllSourceSetsDependingOn(linuxMain))
|
||||
assertEquals(emptySet(), kotlin.resolveAllSourceSetsDependingOn(macosMain))
|
||||
assertEquals(emptySet(), kotlin.resolveAllSourceSetsDependingOn(jvmMain))
|
||||
assertEquals(emptySet(), kotlin.findSourceSetsDependingOn(linuxMain))
|
||||
assertEquals(emptySet(), kotlin.findSourceSetsDependingOn(macosMain))
|
||||
assertEquals(emptySet(), kotlin.findSourceSetsDependingOn(jvmMain))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -72,19 +72,19 @@ class ResolveKotlinSourceSetsTest {
|
||||
macosMain.dependsOn(nativeMain)
|
||||
|
||||
assertEquals(
|
||||
setOf(nativeMain, commonMain), linuxMain.resolveAllDependsOnSourceSets()
|
||||
setOf(nativeMain, commonMain), linuxMain.dependsOnClosure
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf(commonMain), nativeMain.resolveAllDependsOnSourceSets()
|
||||
setOf(commonMain), nativeMain.dependsOnClosure
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
emptySet(), commonMain.resolveAllDependsOnSourceSets()
|
||||
emptySet(), commonMain.dependsOnClosure
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
setOf(commonMain), jvmMain.resolveAllDependsOnSourceSets()
|
||||
setOf(commonMain), jvmMain.dependsOnClosure
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -27,9 +27,9 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.kpmModules
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.targets.android.findAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.JvmCompilationsTestRunSource
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
@@ -166,7 +166,7 @@ private fun chooseAndAddStdlibDependency(
|
||||
val sourceSetDependencyConfigurations =
|
||||
KotlinDependencyScope.values().map { project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, it) }
|
||||
|
||||
val hierarchySourceSetsDependencyConfigurations = kotlinSourceSet.resolveAllDependsOnSourceSets().flatMap { hierarchySourceSet ->
|
||||
val hierarchySourceSetsDependencyConfigurations = kotlinSourceSet.dependsOnClosure.flatMap { hierarchySourceSet ->
|
||||
KotlinDependencyScope.values().map { scope ->
|
||||
project.sourceSetDependencyConfigurationByScope(hierarchySourceSet, scope)
|
||||
}
|
||||
@@ -281,7 +281,7 @@ internal fun configureKotlinTestDependency(project: Project) {
|
||||
|
||||
project.tryWithDependenciesIfUnresolved(configuration) { dependencies ->
|
||||
val parentOrOwnVersions: List<String?> =
|
||||
kotlinSourceSet.withAllDependsOnSourceSets().filter(versionOrNullBySourceSet::contains)
|
||||
kotlinSourceSet.withDependsOnClosure.filter(versionOrNullBySourceSet::contains)
|
||||
.map(versionOrNullBySourceSet::get)
|
||||
|
||||
finalizingDependencies = true
|
||||
|
||||
-1
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.gradle.model.impl.SourceSetImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.getConvention
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
|
||||
/**
|
||||
|
||||
+11
-12
@@ -15,7 +15,6 @@ import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
import org.jetbrains.kotlin.commonizer.util.transitiveClosure
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
@@ -28,8 +27,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.unambiguousNameInProject
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.kpm.FragmentMappedKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
|
||||
@@ -37,6 +36,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSou
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
import org.jetbrains.kotlin.tooling.core.closure
|
||||
import java.util.*
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
@@ -69,8 +69,8 @@ interface CompilationDetailsWithRuntime<T : KotlinCommonOptions> : CompilationDe
|
||||
val runtimeDependencyFilesHolder: DependencyFilesHolder
|
||||
}
|
||||
|
||||
internal val CompilationDetails<*>.associateWithTransitiveClosure: Iterable<CompilationDetails<*>>
|
||||
get() = transitiveClosure(this) { associateCompilations }
|
||||
internal val CompilationDetails<*>.associateCompilationsClosure: Iterable<CompilationDetails<*>>
|
||||
get() = closure { it.associateCompilations }
|
||||
|
||||
open class DefaultCompilationDetails<T : KotlinCommonOptions>(
|
||||
final override val target: KotlinTarget,
|
||||
@@ -122,8 +122,7 @@ open class DefaultCompilationDetails<T : KotlinCommonOptions>(
|
||||
get() = target.disambiguationClassifier
|
||||
|
||||
override val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||
get() = directlyIncludedKotlinSourceSets.plus(directlyIncludedKotlinSourceSets.resolveAllDependsOnSourceSets())
|
||||
.associate { it.name to it.kotlin }
|
||||
get() = directlyIncludedKotlinSourceSets.withDependsOnClosure.associate { it.name to it.kotlin }
|
||||
|
||||
override val compileKotlinTaskName: String
|
||||
get() = lowerCamelCaseName(
|
||||
@@ -163,12 +162,12 @@ open class DefaultCompilationDetails<T : KotlinCommonOptions>(
|
||||
|
||||
override val friendPaths: Iterable<FileCollection>
|
||||
get() = mutableListOf<FileCollection>().also { allCollections ->
|
||||
associateWithTransitiveClosure.forEach { allCollections.add(it.compilationData.output.classesDirs) }
|
||||
associateCompilationsClosure.forEach { allCollections.add(it.compilationData.output.classesDirs) }
|
||||
allCollections.add(friendArtifacts)
|
||||
}
|
||||
|
||||
private val friendArtifactsTask: TaskProvider<AbstractArchiveTask>? by lazy {
|
||||
if (associateWithTransitiveClosure.any { it.compilationData.isMainCompilationData() }) {
|
||||
if (associateCompilationsClosure.any { it.compilationData.isMainCompilationData() }) {
|
||||
val archiveTasks = target.project.tasks.withType(AbstractArchiveTask::class.java)
|
||||
if (!archiveTasks.isEmpty()) {
|
||||
try {
|
||||
@@ -270,7 +269,7 @@ open class DefaultCompilationDetails<T : KotlinCommonOptions>(
|
||||
override fun source(sourceSet: KotlinSourceSet) {
|
||||
if (directlyIncludedKotlinSourceSets.add(sourceSet)) {
|
||||
target.project.whenEvaluated {
|
||||
addExactSourceSetsEagerly(sourceSet.withAllDependsOnSourceSets())
|
||||
addExactSourceSetsEagerly(sourceSet.withDependsOnClosure)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,7 +388,7 @@ internal open class SharedNativeCompilationDetails(
|
||||
val friendSourceSets = getVisibleSourceSetsFromAssociateCompilations(project, defaultSourceSet).toMutableSet().apply {
|
||||
// TODO: implement proper dependsOn/refines compiler args for Kotlin/Native and pass the dependsOn klibs separately;
|
||||
// But for now, those dependencies don't have any special semantics, so passing all them as friends works, too
|
||||
addAll(defaultSourceSet.resolveAllDependsOnSourceSets())
|
||||
addAll(defaultSourceSet.dependsOnClosure)
|
||||
}
|
||||
project.files(friendSourceSets.mapNotNull { project.getMetadataCompilationForSourceSet(it)?.output?.classesDirs })
|
||||
})
|
||||
@@ -671,4 +670,4 @@ internal class KotlinDependencyConfigurationsHolder(
|
||||
|
||||
override fun dependencies(configureClosure: Closure<Any?>) =
|
||||
dependencies f@{ project.configure(this@f, configureClosure) }
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ 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.sources.KotlinDependencyScope.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.ALL_COMPILE_METADATA_CONFIGURATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider
|
||||
@@ -42,7 +42,7 @@ open class TransformKotlinGranularMetadata
|
||||
}
|
||||
|
||||
private val participatingSourceSets: Set<KotlinSourceSet>
|
||||
get() = transformation.kotlinSourceSet.withAllDependsOnSourceSets().toMutableSet().apply {
|
||||
get() = transformation.kotlinSourceSet.withDependsOnClosure.toMutableSet().apply {
|
||||
if (any { it.name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME })
|
||||
add(project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME))
|
||||
}
|
||||
|
||||
+6
-13
@@ -19,11 +19,12 @@ import org.gradle.api.tasks.TaskState
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||
import org.jetbrains.kotlin.tooling.core.closure
|
||||
import java.util.*
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
@@ -137,8 +138,7 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
||||
get() = target
|
||||
|
||||
override val allKotlinSourceSets: Set<KotlinSourceSet>
|
||||
get() = compilationDetails.directlyIncludedKotlinSourceSets +
|
||||
compilationDetails.directlyIncludedKotlinSourceSets.resolveAllDependsOnSourceSets()
|
||||
get() = compilationDetails.directlyIncludedKotlinSourceSets.withDependsOnClosure
|
||||
|
||||
override val relatedConfigurationNames: List<String>
|
||||
get() = compilationDetails.kotlinDependenciesHolder.relatedConfigurationNames + compileDependencyConfigurationName
|
||||
@@ -181,15 +181,8 @@ internal fun addSourcesToKotlinCompileTask(
|
||||
}
|
||||
}
|
||||
|
||||
internal val KotlinCompilation<*>.associateWithTransitiveClosure: Iterable<KotlinCompilation<*>>
|
||||
get() = mutableSetOf<KotlinCompilation<*>>().apply {
|
||||
fun visit(other: KotlinCompilation<*>) {
|
||||
if (add(other)) {
|
||||
other.associateWith.forEach(::visit)
|
||||
}
|
||||
}
|
||||
associateWith.forEach(::visit)
|
||||
}
|
||||
internal val KotlinCompilation<*>.associateWithClosure: Iterable<KotlinCompilation<*>>
|
||||
get() = this.closure { it.associateWith }
|
||||
|
||||
abstract class AbstractKotlinCompilationToRunnableFiles<T : KotlinCommonOptions>(
|
||||
override val compilationDetails: CompilationDetailsWithRuntime<T>,
|
||||
@@ -292,4 +285,4 @@ internal object CompilationSourceSetUtil {
|
||||
private val invalidModuleNameCharactersRegex = """[\\/\r\n\t]""".toRegex()
|
||||
|
||||
internal fun filterModuleName(moduleName: String): String =
|
||||
moduleName.replace(invalidModuleNameCharactersRegex, "_")
|
||||
moduleName.replace(invalidModuleNameCharactersRegex, "_")
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ internal class FragmentGranularMetadataResolver(
|
||||
val relevantVariantResolution = variantResolutions
|
||||
.filterIsInstance<VariantResolution.VariantMatch>()
|
||||
// find some of our variants that resolved a dependency's variant containing the fragment
|
||||
.find { hostSpecificFragment in it.chosenVariant.refinesClosure }
|
||||
.find { hostSpecificFragment in it.chosenVariant.withRefinesClosure }
|
||||
// resolve the dependencies of that variant getting the host-specific metadata artifact
|
||||
relevantVariantResolution?.let { resolution ->
|
||||
val configurationResolvingPlatformVariant =
|
||||
|
||||
+2
-3
@@ -9,7 +9,6 @@ import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
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.pm20Extension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.GradleModuleVariantResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
|
||||
@@ -18,7 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.project.model.VariantResolution
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
import org.jetbrains.kotlin.project.model.withRefinesClosure
|
||||
|
||||
interface KotlinVariantCompilationDataInternal<T : KotlinCommonOptions> : KotlinVariantCompilationData<T> {
|
||||
override val compileKotlinTaskName: String
|
||||
@@ -28,7 +27,7 @@ interface KotlinVariantCompilationDataInternal<T : KotlinCommonOptions> : Kotlin
|
||||
get() = owner.disambiguateName("classes")
|
||||
|
||||
override val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||
get() = owner.refinesClosure.filterIsInstance<KotlinGradleVariant>().associate { it.disambiguateName("") to it.kotlinSourceRoots }
|
||||
get() = owner.withRefinesClosure.filterIsInstance<KotlinGradleVariant>().associate { it.disambiguateName("") to it.kotlinSourceRoots }
|
||||
|
||||
override val friendPaths: Iterable<FileCollection>
|
||||
get() {
|
||||
|
||||
+2
-3
@@ -7,12 +7,11 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
|
||||
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
import org.jetbrains.kotlin.project.model.withRefinesClosure
|
||||
|
||||
/**
|
||||
* Will register a 'hostSpecificMetadataJar' [Jar] task containing compilation outputs of host specific metadata.
|
||||
@@ -30,7 +29,7 @@ val KotlinFragmentHostSpecificMetadataArtifact = FragmentArtifacts<KotlinNativeV
|
||||
val metadataFragment = metadataCompilation.fragment
|
||||
if (metadataCompilation is KotlinNativeFragmentMetadataCompilationData) {
|
||||
jar.from(project.files(project.provider {
|
||||
if (metadataFragment in fragment.refinesClosure && metadataFragment.isNativeHostSpecific())
|
||||
if (metadataFragment in fragment.withRefinesClosure && metadataFragment.isNativeHostSpecific())
|
||||
project.filesWithUnpackedArchives(metadataCompilation.output.allOutputs, setOf(KLIB_FILE_EXTENSION))
|
||||
else emptyList<Any>()
|
||||
})) { spec -> spec.into(metadataFragment.name) }
|
||||
|
||||
+2
-4
@@ -11,13 +11,11 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||
import org.jetbrains.kotlin.gradle.kpm.KotlinExternalModelContainer
|
||||
import org.jetbrains.kotlin.gradle.kpm.KotlinMutableExternalModelContainer
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinDependencyConfigurationsHolder
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.toModuleDependency
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.FragmentConsistencyChecker
|
||||
@@ -26,7 +24,7 @@ import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
|
||||
import org.jetbrains.kotlin.project.model.KotlinModuleDependency
|
||||
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
import org.jetbrains.kotlin.project.model.withRefinesClosure
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KotlinGradleFragmentInternal @Inject constructor(
|
||||
@@ -118,4 +116,4 @@ open class KotlinGradleFragmentInternal @Inject constructor(
|
||||
}
|
||||
|
||||
val KotlinGradleFragment.refinesClosure: Set<KotlinGradleFragment>
|
||||
get() = (this as KotlinModuleFragment).refinesClosure.map { it as KotlinGradleFragment }.toSet()
|
||||
get() = (this as KotlinModuleFragment).withRefinesClosure.map { it as KotlinGradleFragment }.toSet()
|
||||
|
||||
+2
-2
@@ -5,13 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.util.transitiveClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleDependencyGraph
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleDependencyGraphNode
|
||||
import org.jetbrains.kotlin.project.model.KotlinModule
|
||||
import org.jetbrains.kotlin.tooling.core.withClosure
|
||||
|
||||
internal val GradleDependencyGraph.allDependencyNodes: Iterable<GradleDependencyGraphNode>
|
||||
get() = transitiveClosure(root) { dependenciesByFragment.values.flatten() }
|
||||
get() = root.withClosure { it.dependenciesByFragment.values.flatten() }
|
||||
|
||||
internal val GradleDependencyGraph.allDependencyModules: Iterable<KotlinModule>
|
||||
get() = allDependencyNodes.map { it.module }
|
||||
|
||||
+9
-21
@@ -11,13 +11,14 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
|
||||
import org.jetbrains.kotlin.commonizer.util.transitiveClosure
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
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.*
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.tooling.core.closure
|
||||
import org.jetbrains.kotlin.tooling.core.withClosure
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
@@ -252,28 +253,15 @@ internal fun KotlinSourceSet.disambiguateName(simpleName: String): String {
|
||||
internal fun createDefaultSourceDirectorySet(project: Project, name: String?): SourceDirectorySet =
|
||||
project.objects.sourceDirectorySet(name!!, name)
|
||||
|
||||
/**
|
||||
* Like [resolveAllDependsOnSourceSets] but will include the receiver source set also!
|
||||
*/
|
||||
internal fun KotlinSourceSet.withAllDependsOnSourceSets(): Set<KotlinSourceSet> {
|
||||
return this + this.resolveAllDependsOnSourceSets()
|
||||
}
|
||||
|
||||
internal operator fun KotlinSourceSet.plus(sourceSets: Set<KotlinSourceSet>): Set<KotlinSourceSet> {
|
||||
return HashSet<KotlinSourceSet>(sourceSets.size + 1).also { set ->
|
||||
set.add(this)
|
||||
set.addAll(sourceSets)
|
||||
}
|
||||
}
|
||||
val KotlinSourceSet.dependsOnClosure get() = closure { it.dependsOn }
|
||||
|
||||
internal fun KotlinSourceSet.resolveAllDependsOnSourceSets(): Set<KotlinSourceSet> {
|
||||
return transitiveClosure(this) { dependsOn }
|
||||
}
|
||||
val KotlinSourceSet.withDependsOnClosure get() = withClosure { it.dependsOn }
|
||||
|
||||
internal fun Iterable<KotlinSourceSet>.resolveAllDependsOnSourceSets(): Set<KotlinSourceSet> {
|
||||
return flatMapTo(mutableSetOf()) { it.resolveAllDependsOnSourceSets() }
|
||||
}
|
||||
val Iterable<KotlinSourceSet>.dependsOnClosure get() = closure<KotlinSourceSet> { it.dependsOn }
|
||||
|
||||
internal fun KotlinMultiplatformExtension.resolveAllSourceSetsDependingOn(sourceSet: KotlinSourceSet): Set<KotlinSourceSet> {
|
||||
return transitiveClosure(sourceSet) { sourceSets.filter { otherSourceSet -> this in otherSourceSet.dependsOn } }
|
||||
val Iterable<KotlinSourceSet>.withDependsOnClosure get() = withClosure<KotlinSourceSet> { it.dependsOn }
|
||||
|
||||
internal fun KotlinMultiplatformExtension.findSourceSetsDependingOn(sourceSet: KotlinSourceSet): Set<KotlinSourceSet> {
|
||||
return sourceSet.closure { seedSourceSet -> sourceSets.filter { otherSourceSet -> seedSourceSet in otherSourceSet.dependsOn } }
|
||||
}
|
||||
|
||||
+3
-3
@@ -11,10 +11,10 @@ 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
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure
|
||||
|
||||
fun getSourceSetsFromAssociatedCompilations(fromCompilation: KotlinCompilation<*>): Map<KotlinCompilation<*>, Set<KotlinSourceSet>> =
|
||||
fromCompilation.associateWithTransitiveClosure.associate { it to it.allKotlinSourceSets }
|
||||
fromCompilation.associateWithClosure.associate { it to it.allKotlinSourceSets }
|
||||
|
||||
fun getVisibleSourceSetsFromAssociateCompilations(
|
||||
project: Project,
|
||||
@@ -140,7 +140,7 @@ internal fun checkSourceSetVisibilityRequirements(
|
||||
val inferredVisibility =
|
||||
getVisibleSourceSetsFromAssociateCompilations(compilationsBySourceSet[sourceSet].orEmpty())
|
||||
|
||||
val requiredButNotVisible = requiredVisibility - inferredVisibility - sourceSet.withAllDependsOnSourceSets()
|
||||
val requiredButNotVisible = requiredVisibility - inferredVisibility - sourceSet.withDependsOnClosure
|
||||
|
||||
if (requiredButNotVisible.isNotEmpty()) {
|
||||
val compilations = compilationsBySourceSet.getValue(sourceSet)
|
||||
|
||||
+4
-5
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil.compilationsBySourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.metadataCompilationRegistryByModuleId
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.*
|
||||
@@ -257,7 +256,7 @@ class KotlinMetadataTargetConfigurator :
|
||||
* See also: [buildKotlinProjectStructureMetadata], where these dependencies must be included into the source set exported deps.
|
||||
*/
|
||||
if (isSharedNativeCompilation) {
|
||||
sourceSet.withAllDependsOnSourceSets().forEach { hierarchySourceSet ->
|
||||
sourceSet.withDependsOnClosure.forEach { hierarchySourceSet ->
|
||||
apiElementsConfiguration.extendsFrom(
|
||||
sourceSetDependencyConfigurationByScope(hierarchySourceSet, KotlinDependencyScope.IMPLEMENTATION_SCOPE)
|
||||
)
|
||||
@@ -438,14 +437,14 @@ class KotlinMetadataTargetConfigurator :
|
||||
val sourceSet = compilation.defaultSourceSet
|
||||
|
||||
val dependsOnCompilationOutputs = lazy {
|
||||
sourceSet.withAllDependsOnSourceSets().mapNotNull { hierarchySourceSet ->
|
||||
sourceSet.withDependsOnClosure.mapNotNull { hierarchySourceSet ->
|
||||
val dependencyCompilation = project.getMetadataCompilationForSourceSet(hierarchySourceSet)
|
||||
dependencyCompilation?.output?.classesDirs.takeIf { hierarchySourceSet != sourceSet }
|
||||
}
|
||||
}
|
||||
|
||||
val resolvedMetadataFilesProviders = lazy {
|
||||
val transformationTaskHolders = sourceSet.withAllDependsOnSourceSets().mapNotNull { hierarchySourceSet ->
|
||||
val transformationTaskHolders = sourceSet.withDependsOnClosure.mapNotNull { hierarchySourceSet ->
|
||||
project.locateTask<TransformKotlinGranularMetadata>(transformGranularMetadataTaskName(hierarchySourceSet.name))
|
||||
}
|
||||
transformationTaskHolders.map { SourceSetResolvedMetadataProvider(it) }
|
||||
@@ -565,7 +564,7 @@ internal fun isSharedNativeSourceSet(project: Project, sourceSet: KotlinSourceSe
|
||||
}
|
||||
|
||||
internal fun dependsOnClosureWithInterCompilationDependencies(project: Project, sourceSet: KotlinSourceSet): Set<KotlinSourceSet> =
|
||||
sourceSet.resolveAllDependsOnSourceSets().toMutableSet().apply {
|
||||
sourceSet.dependsOnClosure.toMutableSet().apply {
|
||||
addAll(getVisibleSourceSetsFromAssociateCompilations(project, sourceSet))
|
||||
}
|
||||
|
||||
|
||||
-6
@@ -10,19 +10,13 @@ import groovy.lang.Closure
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil.compilationsBySourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier.Scope
|
||||
import org.jetbrains.kotlin.gradle.utils.UnsafeApi
|
||||
|
||||
@@ -59,7 +59,7 @@ internal fun CInteropCommonizerDependent.Factory.from(
|
||||
This relationship should not be declared, but we try to be lenient towards it here.
|
||||
*/
|
||||
val filteredCompilations = compilations.filter { compilation ->
|
||||
compilation.associateWithTransitiveClosure.none { associateCompilation -> associateCompilation in compilations }
|
||||
compilation.associateWithClosure.none { associateCompilation -> associateCompilation in compilations }
|
||||
}.ifEmpty { return null }.toSet()
|
||||
|
||||
val scopes: Set<Scope> = filteredCompilations
|
||||
@@ -95,7 +95,7 @@ internal fun CInteropCommonizerDependent.Factory.fromAssociateCompilations(
|
||||
target = project.getCommonizerTarget(sourceSet) as? SharedCommonizerTarget ?: return null,
|
||||
compilations = (compilationsBySourceSets(project)[sourceSet] ?: return null)
|
||||
.filterIsInstance<KotlinNativeCompilation>()
|
||||
.flatMap { compilation -> compilation.associateWithTransitiveClosure }
|
||||
.flatMap { compilation -> compilation.associateWithClosure }
|
||||
.filterIsInstance<KotlinNativeCompilation>()
|
||||
.toSet()
|
||||
)
|
||||
|
||||
+3
-2
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinSourceSetsIncludingDefault
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerTask.CInteropGist
|
||||
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
@@ -34,7 +34,8 @@ internal open class CInteropCommonizerTask : AbstractCInteropCommonizerTask() {
|
||||
) {
|
||||
@Suppress("unused") // Used for UP-TO-DATE check
|
||||
@get:Input
|
||||
val allSourceSetNames: Provider<List<String>> = sourceSets.map { it.resolveAllDependsOnSourceSets().map(Any::toString) }
|
||||
val allSourceSetNames: Provider<List<String>> = sourceSets
|
||||
.map { it.withDependsOnClosure.map(Any::toString) }
|
||||
}
|
||||
|
||||
override val outputDirectory: File = project.buildDir.resolve("classes/kotlin/commonizer")
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.Choos
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toModuleIdentifiers
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.SourceSetMetadataStorageForIde
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.tasks.dependsOn
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.withType
|
||||
@@ -87,7 +87,7 @@ internal fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTas
|
||||
*/
|
||||
private fun CInteropMetadataDependencyTransformationTask.configureTaskOrder() {
|
||||
val tasksForVisibleSourceSets = Callable {
|
||||
val allVisibleSourceSets = sourceSet.resolveAllDependsOnSourceSets() + sourceSet.getAdditionalVisibleSourceSets()
|
||||
val allVisibleSourceSets = sourceSet.dependsOnClosure + sourceSet.getAdditionalVisibleSourceSets()
|
||||
project.tasks.withType<CInteropMetadataDependencyTransformationTask>().matching { it.sourceSet in allVisibleSourceSets }
|
||||
}
|
||||
mustRunAfter(tasksForVisibleSourceSets)
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinSourceSetsIncludingDefault
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withDependsOnClosure
|
||||
|
||||
internal fun KotlinSharedNativeCompilation.getImplicitlyDependingNativeCompilations(): Set<KotlinNativeCompilation> {
|
||||
val multiplatformExtension = project.multiplatformExtensionOrNull ?: return emptySet()
|
||||
@@ -30,5 +30,5 @@ internal fun KotlinSharedNativeCompilation.getImplicitlyDependingNativeCompilati
|
||||
* see KT-45412
|
||||
*/
|
||||
private fun KotlinCompilation<*>.allParticipatingSourceSets(): Set<KotlinSourceSet> {
|
||||
return kotlinSourceSetsIncludingDefault + kotlinSourceSetsIncludingDefault.resolveAllDependsOnSourceSets()
|
||||
return kotlinSourceSetsIncludingDefault.withDependsOnClosure
|
||||
}
|
||||
|
||||
+2
-3
@@ -38,8 +38,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.AbstractKotlinFragmentMetadat
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.refinesClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.report.BuildReportMode
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.dependsOnClosure
|
||||
import org.jetbrains.kotlin.gradle.utils.propertyWithConvention
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
@@ -65,7 +64,7 @@ abstract class KotlinCompileCommon @Inject constructor(
|
||||
is KotlinCompilation<*> -> {
|
||||
val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet
|
||||
val metadataTarget = compilation.owner as KotlinTarget
|
||||
defaultKotlinSourceSet.resolveAllDependsOnSourceSets()
|
||||
defaultKotlinSourceSet.dependsOnClosure
|
||||
.mapNotNull { sourceSet -> metadataTarget.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
||||
.flatten()
|
||||
}
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
|
||||
task.friendPaths.from(project.provider { compilation.friendPaths })
|
||||
|
||||
if (compilation is KotlinCompilation<*>) {
|
||||
task.friendSourceSets.set(project.provider { compilation.associateWithTransitiveClosure.map { it.name } })
|
||||
task.friendSourceSets.set(project.provider { compilation.associateWithClosure.map { it.name } })
|
||||
// FIXME support compiler plugins with PM20
|
||||
task.pluginClasspath.from(project.configurations.getByName(compilation.pluginConfigurationName))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ standardPublicJars()
|
||||
|
||||
dependencies {
|
||||
implementation(kotlinStdlib())
|
||||
|
||||
implementation(project(":kotlin-tooling-core"))
|
||||
testImplementation(kotlin("test-junit"))
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.project.model
|
||||
|
||||
import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment
|
||||
import org.jetbrains.kotlin.tooling.core.closure
|
||||
import org.jetbrains.kotlin.tooling.core.withClosure
|
||||
import java.io.File
|
||||
|
||||
interface KotlinModuleFragment {
|
||||
@@ -39,13 +41,10 @@ val KotlinModuleFragment.fragmentAttributeSets: Map<KotlinAttributeKey, Set<Stri
|
||||
}
|
||||
|
||||
val KotlinModuleFragment.refinesClosure: Set<KotlinModuleFragment>
|
||||
get() = mutableSetOf<KotlinModuleFragment>().apply {
|
||||
fun visit(moduleFragment: KotlinModuleFragment) {
|
||||
if (add(moduleFragment))
|
||||
moduleFragment.directRefinesDependencies.forEach(::visit)
|
||||
}
|
||||
visit(this@refinesClosure)
|
||||
}
|
||||
get() = this.closure { it.directRefinesDependencies }
|
||||
|
||||
val KotlinModuleFragment.withRefinesClosure: Set<KotlinModuleFragment>
|
||||
get() = this.withClosure { it.directRefinesDependencies }
|
||||
|
||||
val KotlinModuleVariant.platform get() = variantAttributes[KotlinPlatformTypeAttribute]
|
||||
|
||||
@@ -67,7 +66,7 @@ class BasicKotlinModuleVariant(
|
||||
containingModule: KotlinModule,
|
||||
fragmentName: String,
|
||||
languageSettings: LanguageSettings? = null
|
||||
) : BasicKotlinModuleFragment (
|
||||
) : BasicKotlinModuleFragment(
|
||||
containingModule,
|
||||
fragmentName,
|
||||
languageSettings
|
||||
|
||||
@@ -49,7 +49,7 @@ class DefaultModuleFragmentsResolver(
|
||||
|
||||
val chosenFragments = chosenVariants.map { variantResolution ->
|
||||
when (variantResolution) {
|
||||
is VariantResolution.VariantMatch -> variantResolution.chosenVariant.refinesClosure
|
||||
is VariantResolution.VariantMatch -> variantResolution.chosenVariant.withRefinesClosure
|
||||
else -> emptySet()
|
||||
}
|
||||
}
|
||||
@@ -63,4 +63,4 @@ class DefaultModuleFragmentsResolver(
|
||||
|
||||
return FragmentResolution.ChosenFragments(requestingFragment, dependencyModule, result, chosenVariants)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,22 +8,14 @@ package org.jetbrains.kotlin.project.model.utils
|
||||
import org.jetbrains.kotlin.project.model.KotlinModule
|
||||
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
||||
import org.jetbrains.kotlin.project.model.KotlinModuleVariant
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
import org.jetbrains.kotlin.project.model.withRefinesClosure
|
||||
import org.jetbrains.kotlin.tooling.core.closure
|
||||
|
||||
fun KotlinModule.variantsContainingFragment(fragment: KotlinModuleFragment): Iterable<KotlinModuleVariant> =
|
||||
variants.filter { fragment in it.refinesClosure }
|
||||
variants.filter { variant -> fragment in variant.withRefinesClosure }
|
||||
|
||||
fun KotlinModule.findRefiningFragments(fragment: KotlinModuleFragment): Iterable<KotlinModuleFragment> {
|
||||
val refining = mutableSetOf<KotlinModuleFragment>()
|
||||
val notRefining = mutableSetOf<KotlinModuleFragment>()
|
||||
|
||||
fun isRefining(other: KotlinModuleFragment): Boolean = when {
|
||||
other in refining -> true
|
||||
other in notRefining -> false
|
||||
fragment in other.directRefinesDependencies -> true.also { refining.add(other) }
|
||||
fragment.directRefinesDependencies.any { isRefining(it) } -> true.also { refining.add(other) }
|
||||
else -> false.also { notRefining.add(other) }
|
||||
return fragment.closure { seedFragment ->
|
||||
fragments.filter { otherFragment -> seedFragment in otherFragment.directRefinesDependencies }
|
||||
}
|
||||
|
||||
return fragments.filter(::isRefining)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.commonizer.util
|
||||
|
||||
|
||||
public inline fun <reified T> transitiveClosure(seed: T, edges: T.() -> Iterable<T>): Set<T> {
|
||||
// Fast path when initial edges are empty
|
||||
val initialEdges = seed.edges()
|
||||
if (initialEdges is Collection && initialEdges.isEmpty()) return emptySet()
|
||||
|
||||
val queue = deque<T>(initialEdges.count() * 2)
|
||||
val results = mutableSetOf<T>()
|
||||
queue.addAll(initialEdges)
|
||||
while (queue.isNotEmpty()) {
|
||||
// ArrayDeque implementation will optimize this call to 'removeFirst'
|
||||
val resolved = queue.removeAt(0)
|
||||
if (resolved != seed && results.add(resolved)) {
|
||||
queue.addAll(resolved.edges())
|
||||
}
|
||||
}
|
||||
|
||||
return results.toSet()
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal inline fun <reified T> deque(initialSize: Int): MutableList<T> {
|
||||
return if (KotlinVersion.CURRENT.isAtLeast(1, 4)) ArrayDeque(initialSize)
|
||||
else ArrayList(initialSize)
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.commonizer
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class TransitiveClosureTest {
|
||||
private class Node(val value: String, val children: MutableList<Node> = mutableListOf()) {
|
||||
|
||||
override fun toString(): String {
|
||||
return value
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is Node) return false
|
||||
return other.value == value
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return value.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Node.transitiveClosure() = org.jetbrains.kotlin.commonizer.util.transitiveClosure(this) { children }
|
||||
|
||||
@Test
|
||||
fun `transitiveClosure does not include root node`() {
|
||||
val closure = Node("a", mutableListOf(Node("b"), Node("c"))).transitiveClosure()
|
||||
assertEquals(setOf(Node("b"), Node("c")), closure, "Expected transitiveClosure to not include root node")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `transitiveClosure handles loop and self references`() {
|
||||
val nodeA = Node("a")
|
||||
val nodeB = Node("b")
|
||||
val nodeC = Node("c")
|
||||
val nodeD = Node("d")
|
||||
|
||||
// a -> b -> c -> d
|
||||
nodeA.children.add(nodeB)
|
||||
nodeB.children.add(nodeC)
|
||||
nodeC.children.add(nodeD)
|
||||
|
||||
// add self reference to b
|
||||
nodeB.children.add(nodeB)
|
||||
|
||||
// add loop from c -> a
|
||||
nodeC.children.add(nodeA)
|
||||
|
||||
val closure = nodeA.transitiveClosure()
|
||||
assertEquals(
|
||||
setOf(nodeB, nodeC, nodeD), closure,
|
||||
"Expected transitiveClosure to be robust against loops and self references"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,14 @@ dependencies {
|
||||
embedded(project(":kotlinx-metadata-klib")) { isTransitive = false }
|
||||
embedded(project(":kotlinx-metadata")) { isTransitive = false }
|
||||
embedded(project(":native:kotlin-klib-commonizer-api")) { isTransitive = false }
|
||||
embedded(project(":kotlin-tooling-core")) { isTransitive = false }
|
||||
|
||||
// N.B. The order of "kotlinx-metadata*" dependencies makes sense for runtime classpath
|
||||
// of the "runCommonizer" task. Please, don't mix them up.
|
||||
compileOnly(project(":kotlinx-metadata-klib")) { isTransitive = false }
|
||||
compileOnly(project(":kotlinx-metadata")) { isTransitive = false }
|
||||
compileOnly(project(":native:kotlin-klib-commonizer-api")) { isTransitive = false }
|
||||
compileOnly(project(":kotlin-tooling-core")) { isTransitive = false }
|
||||
compileOnly(project(":compiler:cli-common"))
|
||||
compileOnly(project(":compiler:ir.serialization.common"))
|
||||
compileOnly(project(":compiler:frontend"))
|
||||
@@ -40,6 +42,7 @@ dependencies {
|
||||
testImplementation(project(":kotlinx-metadata-klib")) { isTransitive = false }
|
||||
testImplementation(project(":kotlinx-metadata")) { isTransitive = false }
|
||||
testImplementation(project(":native:kotlin-klib-commonizer-api"))
|
||||
testImplementation(project(":kotlin-tooling-core"))
|
||||
testApi(intellijCore())
|
||||
}
|
||||
|
||||
|
||||
+4
-12
@@ -5,16 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.core
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirClassType
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirType
|
||||
import org.jetbrains.kotlin.commonizer.cir.SimpleCirSupertypesResolver
|
||||
import org.jetbrains.kotlin.commonizer.cir.*
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirProvided
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.findClass
|
||||
import org.jetbrains.kotlin.commonizer.util.transitiveClosure
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.tooling.core.withClosure
|
||||
|
||||
private typealias Supertypes = List<CirType>
|
||||
|
||||
@@ -188,12 +184,8 @@ private class TypeNode(
|
||||
val supertypes: List<TypeNode>,
|
||||
var isConsumed: Boolean = false
|
||||
) {
|
||||
val allNodes: List<TypeNode> by lazy {
|
||||
val allSupertypes = transitiveClosure(this, TypeNode::supertypes)
|
||||
ArrayList<TypeNode>(allSupertypes.size + 1).also { list ->
|
||||
list.add(this)
|
||||
list.addAll(allSupertypes)
|
||||
}
|
||||
val allNodes: Set<TypeNode> by lazy {
|
||||
this.withClosure(TypeNode::supertypes)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
|
||||
+2
-2
@@ -7,10 +7,10 @@ package org.jetbrains.kotlin.commonizer.tree.deserializer
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirClassType
|
||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeClass
|
||||
import org.jetbrains.kotlin.commonizer.util.transitiveClosure
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.tooling.core.withClosure
|
||||
import kotlin.test.*
|
||||
|
||||
class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() {
|
||||
@@ -130,7 +130,7 @@ class CirTreeClassDeserializerTest : AbstractCirTreeDeserializerTest() {
|
||||
)
|
||||
|
||||
val pkg = module.assertSinglePackage()
|
||||
val xClass = pkg.classes.flatMap { transitiveClosure(it, CirTreeClass::classes) + it }
|
||||
val xClass = pkg.classes.withClosure<CirTreeClass> { it.classes }
|
||||
.singleOrNull { it.clazz.name.toStrippedString() == "X" } ?: kotlin.test.fail("Missing class 'X'")
|
||||
val xSuperType = xClass.clazz.supertypes.singleOrNull()
|
||||
?: kotlin.test.fail("Expected single supertype for 'X'. Found ${xClass.clazz.supertypes}")
|
||||
|
||||
Reference in New Issue
Block a user