Introduce SourceType and use KotlinFacetSettings.isTestModule

Refactor dealing with production/test roots
Remove ad-hoc code in KotlinMultiplatformRunLocationsProvider
This commit is contained in:
Pavel V. Talanov
2018-09-25 18:18:34 +02:00
parent 1be491504a
commit cc1be5f559
5 changed files with 55 additions and 37 deletions
@@ -210,8 +210,6 @@ data class ModuleTestSourceInfo internal constructor(override val module: Module
override fun <T> createCachedValueProvider(f: () -> CachedValueProvider.Result<T>) = CachedValueProvider { f() }
}
internal fun ModuleSourceInfo.isTests() = this is ModuleTestSourceInfo
fun Module.productionSourceInfo(): ModuleProductionSourceInfo? = if (hasProductionRoots()) ModuleProductionSourceInfo(this) else null
fun Module.testSourceInfo(): ModuleTestSourceInfo? = if (hasTestRoots()) ModuleTestSourceInfo(this) else null
@@ -444,3 +442,10 @@ data class PlatformModuleInfo(
fun IdeaModuleInfo.projectSourceModules(): List<ModuleSourceInfo>? =
(this as? ModuleSourceInfo)?.let(::listOf) ?: (this as? PlatformModuleInfo)?.containedModules
enum class SourceType {
PRODUCTION,
TEST
}
internal val ModuleSourceInfo.sourceType get() = if (this is ModuleTestSourceInfo) SourceType.TEST else SourceType.PRODUCTION
@@ -6,25 +6,24 @@
package org.jetbrains.kotlin.idea.caches.project
import com.intellij.openapi.module.Module
import com.intellij.util.containers.MultiMap
import com.intellij.openapi.project.Project
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleOrderEntry
import gnu.trove.THashSet
import com.intellij.util.containers.Queue
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.CachedValueProvider
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ProjectRootModificationTracker
import java.util.HashSet
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.util.containers.MultiMap
import com.intellij.util.containers.Queue
import gnu.trove.THashSet
import java.util.*
//NOTE: this is an approximation that may contain more module infos then the exact solution
fun ModuleSourceInfo.getDependentModules(): Set<ModuleSourceInfo> {
val dependents = getDependents(module)
return if (isTests()) {
dependents.mapNotNullTo(HashSet<ModuleSourceInfo>(), Module::testSourceInfo)
} else {
dependents.flatMapTo(HashSet<ModuleSourceInfo>()) { it.correspondingModuleInfos() }
return when (sourceType) {
SourceType.TEST -> dependents.mapNotNullTo(HashSet<ModuleSourceInfo>(), Module::testSourceInfo)
SourceType.PRODUCTION -> dependents.flatMapTo(HashSet<ModuleSourceInfo>()) { it.correspondingModuleInfos() }
}
}
@@ -16,6 +16,8 @@ import com.intellij.psi.util.CachedValueProvider
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.caches.project.SourceType.PRODUCTION
import org.jetbrains.kotlin.idea.caches.project.SourceType.TEST
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.facet.KotlinFacetType
import org.jetbrains.kotlin.idea.facet.KotlinFacetType.Companion.ID
@@ -26,19 +28,24 @@ import org.jetbrains.kotlin.platform.impl.isCommon
import org.jetbrains.kotlin.resolve.TargetPlatform
val Module.isNewMPPModule: Boolean
get() = KotlinFacet.get(this)?.configuration?.settings?.kind?.isNewMPP ?: false
get() = facetSettings?.kind?.isNewMPP ?: false
val Module.externalProjectId: String
get() = KotlinFacet.get(this)?.configuration?.settings?.externalProjectId ?: ""
get() = facetSettings?.externalProjectId ?: ""
val Module.sourceType: SourceType?
get() = facetSettings?.isTestModule?.let { isTest -> if (isTest) SourceType.TEST else PRODUCTION }
val Module.isMPPModule: Boolean
get() {
val settings = KotlinFacet.get(this)?.configuration?.settings ?: return false
val settings = facetSettings ?: return false
return settings.platform.isCommon ||
settings.implementedModuleNames.isNotEmpty() ||
settings.kind.isNewMPP
}
private val Module.facetSettings get() = KotlinFacet.get(this)?.configuration?.settings
val Module.implementingModules: List<Module>
get() = cached(CachedValueProvider {
val moduleManager = ModuleManager.getInstance(project)
@@ -87,12 +94,15 @@ val ModuleDescriptor.implementingDescriptors: List<ModuleDescriptor>
return listOf(this)
}
val moduleSourceInfo = moduleInfo as? ModuleSourceInfo ?: return emptyList()
val implementingModuleInfos = moduleSourceInfo.module.implementingModules.mapNotNull { it.toInfo(moduleSourceInfo.isTests()) }
val implementingModuleInfos = moduleSourceInfo.module.implementingModules.mapNotNull { it.toInfo(moduleSourceInfo.sourceType) }
return implementingModuleInfos.mapNotNull { it.toDescriptor() }
}
private fun Module.toInfo(isTests: Boolean): ModuleSourceInfo? =
if (isTests) testSourceInfo() else productionSourceInfo()
private fun Module.toInfo(type: SourceType): ModuleSourceInfo? = when (type) {
PRODUCTION -> productionSourceInfo()
TEST -> testSourceInfo()
}
val ModuleDescriptor.implementedDescriptors: List<ModuleDescriptor>
get() {
@@ -112,7 +122,7 @@ fun PsiElement.getPlatformModuleInfo(desiredPlatform: TargetPlatform): PlatformM
val moduleInfo = getModuleInfo() as? ModuleSourceInfo ?: return null
return when (moduleInfo.platform) {
TargetPlatform.Common -> {
val correspondingImplementingModule = moduleInfo.module.implementingModules.map { it.toInfo(moduleInfo.isTests()) }
val correspondingImplementingModule = moduleInfo.module.implementingModules.map { it.toInfo(moduleInfo.sourceType) }
.firstOrNull { it?.platform == desiredPlatform } ?: return null
PlatformModuleInfo(correspondingImplementingModule, correspondingImplementingModule.expectedBy)
}