Fix setting production-on-test flags in MPP projects
#KT-29854 Fixed
This commit is contained in:
+24
-11
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
|||||||
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
|
||||||
|
|
||||||
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
|
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
|
||||||
override fun getTargetDataKey() = ProjectKeys.MODULE
|
override fun getTargetDataKey() = ProjectKeys.MODULE
|
||||||
@@ -95,11 +96,17 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
for (sourceSet in activeCompilation.sourceSets) {
|
for (sourceSet in activeCompilation.sourceSets) {
|
||||||
if (sourceSet.platform != KotlinPlatform.ANDROID) {
|
if (sourceSet.platform != KotlinPlatform.ANDROID) {
|
||||||
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
|
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
|
||||||
val sourceSetData = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
|
val sourceSetNode = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
|
||||||
(it.data as? ModuleData)?.id == sourceSetId
|
(it.data as? ModuleData)?.id == sourceSetId
|
||||||
}?.data as? ModuleData ?: continue
|
} as? DataNode<out ModuleData>? ?: continue
|
||||||
|
val sourceSetData = sourceSetNode.data as? ModuleData ?: continue
|
||||||
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
|
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
|
||||||
addModuleDependencyIfNeeded(rootModel, sourceSetModule, activeSourceSetInfo.isTestModule)
|
addModuleDependencyIfNeeded(
|
||||||
|
rootModel,
|
||||||
|
sourceSetModule,
|
||||||
|
activeSourceSetInfo.isTestModule,
|
||||||
|
sourceSetNode.kotlinSourceSet?.isTestModule ?: false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +176,8 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
}
|
}
|
||||||
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
|
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
|
||||||
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
|
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
|
||||||
SmartList<DataNode<GradleSourceSetData>>()
|
|
||||||
|
val gradleSourceSetDataNodes = SmartList<DataNode<GradleSourceSetData>>()
|
||||||
.apply {
|
.apply {
|
||||||
addIfNotNull(
|
addIfNotNull(
|
||||||
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
|
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
|
||||||
@@ -181,14 +189,19 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.mapNotNull { modelsProvider.findIdeModule(it.data) }
|
|
||||||
.forEach {
|
val testKotlinModules =
|
||||||
addModuleDependencyIfNeeded(rootModel, it, testScope)
|
gradleSourceSetDataNodes.filter { it.kotlinSourceSet?.isTestModule ?: false }.mapNotNull { modelsProvider.findIdeModule(it.data) }
|
||||||
val dependeeRootModel = modelsProvider.getModifiableRootModel(it)
|
.toSet()
|
||||||
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
|
|
||||||
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope)
|
gradleSourceSetDataNodes.forEach { node ->
|
||||||
}
|
val module = modelsProvider.findIdeModule(node.data) ?: return
|
||||||
|
addModuleDependencyIfNeeded(rootModel, module, testScope, node.kotlinSourceSet?.isTestModule ?: false)
|
||||||
|
val dependeeRootModel = modelsProvider.getModifiableRootModel(module)
|
||||||
|
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
|
||||||
|
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope, testKotlinModules.contains(transitiveDependee))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
|
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
|
||||||
|
|||||||
+24
-11
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
|||||||
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
|
||||||
|
|
||||||
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
|
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
|
||||||
override fun getTargetDataKey() = ProjectKeys.MODULE
|
override fun getTargetDataKey() = ProjectKeys.MODULE
|
||||||
@@ -95,11 +96,17 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
for (sourceSet in activeCompilation.sourceSets) {
|
for (sourceSet in activeCompilation.sourceSets) {
|
||||||
if (sourceSet.platform != KotlinPlatform.ANDROID) {
|
if (sourceSet.platform != KotlinPlatform.ANDROID) {
|
||||||
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
|
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
|
||||||
val sourceSetData = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
|
val sourceSetNode = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
|
||||||
(it.data as? ModuleData)?.id == sourceSetId
|
(it.data as? ModuleData)?.id == sourceSetId
|
||||||
}?.data as? ModuleData ?: continue
|
} as? DataNode<out ModuleData>? ?: continue
|
||||||
|
val sourceSetData = sourceSetNode.data as? ModuleData ?: continue
|
||||||
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
|
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
|
||||||
addModuleDependencyIfNeeded(rootModel, sourceSetModule, activeSourceSetInfo.isTestModule)
|
addModuleDependencyIfNeeded(
|
||||||
|
rootModel,
|
||||||
|
sourceSetModule,
|
||||||
|
activeSourceSetInfo.isTestModule,
|
||||||
|
sourceSetNode.kotlinSourceSet?.isTestModule ?: false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +176,8 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
}
|
}
|
||||||
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
|
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
|
||||||
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
|
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
|
||||||
SmartList<DataNode<GradleSourceSetData>>()
|
|
||||||
|
val gradleSourceSetDataNodes = SmartList<DataNode<GradleSourceSetData>>()
|
||||||
.apply {
|
.apply {
|
||||||
addIfNotNull(
|
addIfNotNull(
|
||||||
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
|
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
|
||||||
@@ -181,14 +189,19 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.mapNotNull { modelsProvider.findIdeModule(it.data) }
|
|
||||||
.forEach {
|
val testKotlinModules =
|
||||||
addModuleDependencyIfNeeded(rootModel, it, testScope)
|
gradleSourceSetDataNodes.filter { it.kotlinSourceSet?.isTestModule ?: false }.mapNotNull { modelsProvider.findIdeModule(it.data) }
|
||||||
val dependeeRootModel = modelsProvider.getModifiableRootModel(it)
|
.toSet()
|
||||||
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
|
|
||||||
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope)
|
gradleSourceSetDataNodes.forEach { node ->
|
||||||
}
|
val module = modelsProvider.findIdeModule(node.data) ?: return
|
||||||
|
addModuleDependencyIfNeeded(rootModel, module, testScope, node.kotlinSourceSet?.isTestModule ?: false)
|
||||||
|
val dependeeRootModel = modelsProvider.getModifiableRootModel(module)
|
||||||
|
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
|
||||||
|
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope, testKotlinModules.contains(transitiveDependee))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
|
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
|
||||||
|
|||||||
+24
-11
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
|||||||
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
|
||||||
|
|
||||||
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
|
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
|
||||||
override fun getTargetDataKey() = ProjectKeys.MODULE
|
override fun getTargetDataKey() = ProjectKeys.MODULE
|
||||||
@@ -95,11 +96,17 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
for (sourceSet in activeCompilation.sourceSets) {
|
for (sourceSet in activeCompilation.sourceSets) {
|
||||||
if (sourceSet.platform != KotlinPlatform.ANDROID) {
|
if (sourceSet.platform != KotlinPlatform.ANDROID) {
|
||||||
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
|
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
|
||||||
val sourceSetData = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
|
val sourceSetNode = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
|
||||||
(it.data as? ModuleData)?.id == sourceSetId
|
(it.data as? ModuleData)?.id == sourceSetId
|
||||||
}?.data as? ModuleData ?: continue
|
} as? DataNode<out ModuleData>? ?: continue
|
||||||
|
val sourceSetData = sourceSetNode.data as? ModuleData ?: continue
|
||||||
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
|
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
|
||||||
addModuleDependencyIfNeeded(rootModel, sourceSetModule, activeSourceSetInfo.isTestModule)
|
addModuleDependencyIfNeeded(
|
||||||
|
rootModel,
|
||||||
|
sourceSetModule,
|
||||||
|
activeSourceSetInfo.isTestModule,
|
||||||
|
sourceSetNode.kotlinSourceSet?.isTestModule ?: false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +176,8 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
}
|
}
|
||||||
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
|
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
|
||||||
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
|
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
|
||||||
SmartList<DataNode<GradleSourceSetData>>()
|
|
||||||
|
val gradleSourceSetDataNodes = SmartList<DataNode<GradleSourceSetData>>()
|
||||||
.apply {
|
.apply {
|
||||||
addIfNotNull(
|
addIfNotNull(
|
||||||
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
|
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
|
||||||
@@ -181,14 +189,19 @@ class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<Modul
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.mapNotNull { modelsProvider.findIdeModule(it.data) }
|
|
||||||
.forEach {
|
val testKotlinModules =
|
||||||
addModuleDependencyIfNeeded(rootModel, it, testScope)
|
gradleSourceSetDataNodes.filter { it.kotlinSourceSet?.isTestModule ?: false }.mapNotNull { modelsProvider.findIdeModule(it.data) }
|
||||||
val dependeeRootModel = modelsProvider.getModifiableRootModel(it)
|
.toSet()
|
||||||
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
|
|
||||||
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope)
|
gradleSourceSetDataNodes.forEach { node ->
|
||||||
}
|
val module = modelsProvider.findIdeModule(node.data) ?: return
|
||||||
|
addModuleDependencyIfNeeded(rootModel, module, testScope, node.kotlinSourceSet?.isTestModule ?: false)
|
||||||
|
val dependeeRootModel = modelsProvider.getModifiableRootModel(module)
|
||||||
|
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
|
||||||
|
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope, testKotlinModules.contains(transitiveDependee))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
|
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
|
||||||
|
|||||||
+14
-2
@@ -28,6 +28,8 @@ class KotlinJavaMPPSourceSetDataService : AbstractProjectDataService<GradleSourc
|
|||||||
project: Project,
|
project: Project,
|
||||||
modelsProvider: IdeModifiableModelsProvider
|
modelsProvider: IdeModifiableModelsProvider
|
||||||
) {
|
) {
|
||||||
|
val testKotlinModules =
|
||||||
|
toImport.filter { it.kotlinSourceSet?.isTestModule ?: false }.map { modelsProvider.findIdeModule(it.data) }.toSet()
|
||||||
val projectNode = toImport.firstOrNull()?.let { ExternalSystemApiUtil.findParent(it, ProjectKeys.PROJECT) } ?: return
|
val projectNode = toImport.firstOrNull()?.let { ExternalSystemApiUtil.findParent(it, ProjectKeys.PROJECT) } ?: return
|
||||||
val targetsByUrl = ExternalSystemApiUtil
|
val targetsByUrl = ExternalSystemApiUtil
|
||||||
.findAllRecursively(projectNode, KotlinTargetData.KEY)
|
.findAllRecursively(projectNode, KotlinTargetData.KEY)
|
||||||
@@ -53,9 +55,19 @@ class KotlinJavaMPPSourceSetDataService : AbstractProjectDataService<GradleSourc
|
|||||||
val compilationInfo = compilationNode.kotlinSourceSet ?: continue
|
val compilationInfo = compilationNode.kotlinSourceSet ?: continue
|
||||||
if (!isTestSourceSet && compilationInfo.isTestModule) continue
|
if (!isTestSourceSet && compilationInfo.isTestModule) continue
|
||||||
val compilationRootModel = modelsProvider.getModifiableRootModel(compilationModule)
|
val compilationRootModel = modelsProvider.getModifiableRootModel(compilationModule)
|
||||||
addModuleDependencyIfNeeded(rootModel, compilationModule, isTestSourceSet)
|
addModuleDependencyIfNeeded(
|
||||||
|
rootModel,
|
||||||
|
compilationModule,
|
||||||
|
isTestSourceSet,
|
||||||
|
compilationNode.kotlinSourceSet?.isTestModule ?: false
|
||||||
|
)
|
||||||
compilationRootModel.getModuleDependencies(isTestSourceSet).forEach { transitiveDependee ->
|
compilationRootModel.getModuleDependencies(isTestSourceSet).forEach { transitiveDependee ->
|
||||||
addModuleDependencyIfNeeded(rootModel, transitiveDependee, isTestSourceSet)
|
addModuleDependencyIfNeeded(
|
||||||
|
rootModel,
|
||||||
|
transitiveDependee,
|
||||||
|
isTestSourceSet,
|
||||||
|
testKotlinModules.contains(transitiveDependee)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootModel.removeOrderEntry(libraryEntry)
|
rootModel.removeOrderEntry(libraryEntry)
|
||||||
|
|||||||
+7
-4
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
|||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.gradle.*
|
import org.jetbrains.kotlin.gradle.*
|
||||||
import org.jetbrains.kotlin.idea.configuration.GradlePropertiesFileFacade.Companion.KOTLIN_NOT_IMPORTED_COMMON_SOURCE_SETS_SETTING
|
import org.jetbrains.kotlin.idea.configuration.GradlePropertiesFileFacade.Companion.KOTLIN_NOT_IMPORTED_COMMON_SOURCE_SETS_SETTING
|
||||||
import org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver.Companion.isNotSupported
|
|
||||||
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
|
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
|
||||||
import org.jetbrains.plugins.gradle.model.*
|
import org.jetbrains.plugins.gradle.model.*
|
||||||
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData
|
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData
|
||||||
@@ -361,7 +360,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
|||||||
for (sourceSet in compilation.sourceSets) {
|
for (sourceSet in compilation.sourceSets) {
|
||||||
if (sourceSet.fullName() == compilation.fullName()) continue
|
if (sourceSet.fullName() == compilation.fullName()) continue
|
||||||
val targetDataNode = getSiblingKotlinModuleData(sourceSet, gradleModule, ideModule, resolverCtx) ?: continue
|
val targetDataNode = getSiblingKotlinModuleData(sourceSet, gradleModule, ideModule, resolverCtx) ?: continue
|
||||||
addDependency(dataNode, targetDataNode)
|
addDependency(dataNode, targetDataNode, sourceSet.isTestModule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,7 +420,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
|||||||
if (sourceSet.platform == KotlinPlatform.ANDROID) continue
|
if (sourceSet.platform == KotlinPlatform.ANDROID) continue
|
||||||
for (dependeeSourceSet in dependeeSourceSets) {
|
for (dependeeSourceSet in dependeeSourceSets) {
|
||||||
val toDataNode = getSiblingKotlinModuleData(dependeeSourceSet, gradleModule, ideModule, resolverCtx) ?: continue
|
val toDataNode = getSiblingKotlinModuleData(dependeeSourceSet, gradleModule, ideModule, resolverCtx) ?: continue
|
||||||
addDependency(fromDataNode, toDataNode)
|
addDependency(fromDataNode, toDataNode, dependeeSourceSet.isTestModule)
|
||||||
}
|
}
|
||||||
if (processedModuleIds.add(getKotlinModuleId(gradleModule, sourceSet, resolverCtx))) {
|
if (processedModuleIds.add(getKotlinModuleId(gradleModule, sourceSet, resolverCtx))) {
|
||||||
val mergedDependencies = LinkedHashSet<KotlinDependency>().apply {
|
val mergedDependencies = LinkedHashSet<KotlinDependency>().apply {
|
||||||
@@ -454,12 +453,13 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
|||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addDependency(fromModule: DataNode<*>, toModule: DataNode<*>) {
|
private fun addDependency(fromModule: DataNode<*>, toModule: DataNode<*>, dependOnTestModule: Boolean) {
|
||||||
val fromData = fromModule.data as? ModuleData ?: return
|
val fromData = fromModule.data as? ModuleData ?: return
|
||||||
val toData = toModule.data as? ModuleData ?: return
|
val toData = toModule.data as? ModuleData ?: return
|
||||||
val moduleDependencyData = ModuleDependencyData(fromData, toData).also {
|
val moduleDependencyData = ModuleDependencyData(fromData, toData).also {
|
||||||
it.scope = DependencyScope.COMPILE
|
it.scope = DependencyScope.COMPILE
|
||||||
it.isExported = false
|
it.isExported = false
|
||||||
|
it.isProductionOnTestDependency = dependOnTestModule
|
||||||
}
|
}
|
||||||
fromModule.createChild(ProjectKeys.MODULE_DEPENDENCY, moduleDependencyData)
|
fromModule.createChild(ProjectKeys.MODULE_DEPENDENCY, moduleDependencyData)
|
||||||
}
|
}
|
||||||
@@ -567,6 +567,9 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
|||||||
sourceSet.name = compilation.fullName()
|
sourceSet.name = compilation.fullName()
|
||||||
sourceSet.targetCompatibility = compilationData.targetCompatibility
|
sourceSet.targetCompatibility = compilationData.targetCompatibility
|
||||||
sourceSet.dependencies += compilation.dependencies
|
sourceSet.dependencies += compilation.dependencies
|
||||||
|
//TODO after applying patch to IDEA core uncomment the following line:
|
||||||
|
// sourceSet.isTest = compilation.sourceSets.filter { isTestModule }.isNotEmpty()
|
||||||
|
// It will allow to get rid of hacks with guessing module type in DataServices and obtain properly set productionOnTest flags
|
||||||
val sourcesWithTypes = SmartList<kotlin.Pair<IExternalSystemSourceType, ExternalSourceDirectorySet>>()
|
val sourcesWithTypes = SmartList<kotlin.Pair<IExternalSystemSourceType, ExternalSourceDirectorySet>>()
|
||||||
if (effectiveClassesDir != null) {
|
if (effectiveClassesDir != null) {
|
||||||
sourcesWithTypes += compilation.sourceType to DefaultExternalSourceDirectorySet().also { dirSet ->
|
sourcesWithTypes += compilation.sourceType to DefaultExternalSourceDirectorySet().also { dirSet ->
|
||||||
|
|||||||
@@ -8,20 +8,58 @@ package org.jetbrains.kotlin.idea
|
|||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.roots.DependencyScope
|
import com.intellij.openapi.roots.DependencyScope
|
||||||
import com.intellij.openapi.roots.ModifiableRootModel
|
import com.intellij.openapi.roots.ModifiableRootModel
|
||||||
|
import com.intellij.openapi.roots.impl.ModuleOrderEntryImpl
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the dependency scope which has flags specific to the both provided scopes
|
||||||
|
*/
|
||||||
|
fun getScopeContainingBoth(scope1: DependencyScope, scope2: DependencyScope?): DependencyScope {
|
||||||
|
if (scope2 == null) {
|
||||||
|
return scope1
|
||||||
|
}
|
||||||
|
|
||||||
|
val compile = scope1.isForProductionCompile || scope2.isForProductionCompile
|
||||||
|
val runtime = scope1.isForProductionRuntime || scope2.isForProductionRuntime
|
||||||
|
val testCompile = scope1.isForTestCompile || scope2.isForTestCompile
|
||||||
|
val testRuntime = scope1.isForTestRuntime || scope2.isForTestRuntime
|
||||||
|
|
||||||
|
//we suppose that scope1 or scope 2 is at least Test
|
||||||
|
val result = if (compile || runtime) DependencyScope.COMPILE else DependencyScope.TEST
|
||||||
|
// validate that result is valid. We could not express several cases (e.g. RUNTIME + TEST), we will log this case
|
||||||
|
if (result.isForProductionCompile != compile ||
|
||||||
|
result.isForProductionRuntime != runtime ||
|
||||||
|
result.isForTestCompile != testCompile ||
|
||||||
|
result.isForTestRuntime != testRuntime
|
||||||
|
) {
|
||||||
|
Logger.getInstance(KotlinJavaMPPSourceSetDataService::class.java)
|
||||||
|
.warn("Could not express cross-module dependency with flags Compile=$compile Runtime=$runtime TestCompile=$testCompile TestRuntime=$testRuntime")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
fun addModuleDependencyIfNeeded(
|
fun addModuleDependencyIfNeeded(
|
||||||
rootModel: ModifiableRootModel,
|
rootModel: ModifiableRootModel,
|
||||||
dependeeModule: Module,
|
dependeeModule: Module,
|
||||||
testScope: Boolean
|
testScope: Boolean,
|
||||||
|
dependOnTest: Boolean
|
||||||
) {
|
) {
|
||||||
val dependencyScope = if (testScope) DependencyScope.TEST else DependencyScope.COMPILE
|
|
||||||
val existingEntry = rootModel.findModuleOrderEntry(dependeeModule)
|
val existingEntry = rootModel.findModuleOrderEntry(dependeeModule)
|
||||||
|
val existingDependOnTest = (existingEntry as? ModuleOrderEntryImpl)?.isProductionOnTestDependency ?: false
|
||||||
|
|
||||||
|
val requiredScope = getScopeContainingBoth(if (testScope) DependencyScope.TEST else DependencyScope.COMPILE, existingEntry?.scope)
|
||||||
if (existingEntry != null) {
|
if (existingEntry != null) {
|
||||||
val existingScope = existingEntry.scope
|
val existingScope = existingEntry.scope
|
||||||
if (existingScope == DependencyScope.COMPILE || existingScope == dependencyScope) return
|
|
||||||
if (dependencyScope == DependencyScope.COMPILE) {
|
|
||||||
|
if (requiredScope != existingScope || (dependOnTest && !existingDependOnTest)) {
|
||||||
rootModel.removeOrderEntry(existingEntry)
|
rootModel.removeOrderEntry(existingEntry)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootModel.addModuleOrderEntry(dependeeModule).also { it.scope = dependencyScope }
|
rootModel.addModuleOrderEntry(dependeeModule).also {
|
||||||
|
it.scope = requiredScope
|
||||||
|
(it as? ModuleOrderEntryImpl)?.isProductionOnTestDependency = dependOnTest || existingDependOnTest
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+13
@@ -536,6 +536,19 @@ class NewMultiplatformProjectImportingTest : MultiplePluginVersionGradleImportin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testProductionOnTestFlag() {
|
||||||
|
configureByFiles()
|
||||||
|
importProject(true)
|
||||||
|
|
||||||
|
checkProjectStructure(false, false, false ) {
|
||||||
|
module("project.javaModule.test") {
|
||||||
|
moduleDependency("project.mppModule.jvmTest", DependencyScope.TEST, true)
|
||||||
|
moduleDependency("project.mppModule.jvmMain", DependencyScope.TEST, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkProjectStructure(
|
private fun checkProjectStructure(
|
||||||
exhaustiveModuleList: Boolean = true,
|
exhaustiveModuleList: Boolean = true,
|
||||||
exhaustiveSourceSourceRootList: Boolean = true,
|
exhaustiveSourceSourceRootList: Boolean = true,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.intellij.openapi.module.ModuleManager
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.project.rootManager
|
import com.intellij.openapi.project.rootManager
|
||||||
import com.intellij.openapi.roots.*
|
import com.intellij.openapi.roots.*
|
||||||
|
import com.intellij.openapi.roots.impl.ModuleOrderEntryImpl
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||||
import org.jetbrains.jps.util.JpsPathUtil
|
import org.jetbrains.jps.util.JpsPathUtil
|
||||||
@@ -147,7 +148,7 @@ class ModuleInfo(
|
|||||||
expectedDependencyNames += libraryEntry.presentableName
|
expectedDependencyNames += libraryEntry.presentableName
|
||||||
}
|
}
|
||||||
|
|
||||||
fun moduleDependency(moduleName: String, scope: DependencyScope) {
|
fun moduleDependency(moduleName: String, scope: DependencyScope, productionOnTest: Boolean? = null) {
|
||||||
val moduleEntry = rootModel.orderEntries.filterIsInstance<ModuleOrderEntry>().singleOrNull { it.moduleName == moduleName }
|
val moduleEntry = rootModel.orderEntries.filterIsInstance<ModuleOrderEntry>().singleOrNull { it.moduleName == moduleName }
|
||||||
if (moduleEntry == null) {
|
if (moduleEntry == null) {
|
||||||
val allModules = rootModel.orderEntries.filterIsInstance<ModuleOrderEntry>().map { it.moduleName }.joinToString(", ")
|
val allModules = rootModel.orderEntries.filterIsInstance<ModuleOrderEntry>().map { it.moduleName }.joinToString(", ")
|
||||||
@@ -155,6 +156,7 @@ class ModuleInfo(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
checkDependencyScope(moduleEntry, scope)
|
checkDependencyScope(moduleEntry, scope)
|
||||||
|
checkProductionOnTest(moduleEntry, productionOnTest)
|
||||||
expectedDependencyNames += moduleEntry.presentableName
|
expectedDependencyNames += moduleEntry.presentableName
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,6 +243,23 @@ class ModuleInfo(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkProductionOnTest(library: ExportableOrderEntry, productionOnTest: Boolean?) {
|
||||||
|
if (productionOnTest == null) return
|
||||||
|
val actualFlag = (library as? ModuleOrderEntryImpl)?.isProductionOnTestDependency
|
||||||
|
if (actualFlag == null) {
|
||||||
|
projectInfo.messageCollector.report(
|
||||||
|
"Module '${module.name}': Dependency '${library.presentableName}' has no productionOnTest property"
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
if (actualFlag != productionOnTest) {
|
||||||
|
projectInfo.messageCollector.report(
|
||||||
|
"Module '${module.name}': Dependency '${library.presentableName}': expected productionOnTest '$productionOnTest' but found '$actualFlag'"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkProjectStructure(
|
fun checkProjectStructure(
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
subprojects {
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
apply plugin: 'kotlin'
|
||||||
|
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile project(':mppModule')
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
apply plugin: 'kotlin-multiplatform'
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
|
||||||
|
}
|
||||||
|
println("mppModule")
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
include 'javaModule'
|
||||||
|
include 'mppModule'
|
||||||
Reference in New Issue
Block a user