Introduce ModuleDescriptor.findImplementingDescriptor() via facets

This function is now used instead of allImplementingCompatibleModules,
thus allowing it to be deleted together with allImplementingModules

So #KT-17369 Fixed
So #KT-17374 Fixed
May fix also some other MPP issues
This commit is contained in:
Mikhail Glukhikh
2017-09-26 16:15:50 +03:00
parent c9f11e4bc2
commit 5687fe6e39
14 changed files with 66 additions and 66 deletions
@@ -118,7 +118,6 @@ class ResolverForProjectImpl<M : ModuleInfo>(
moduleDescriptor.setDependencies(LazyModuleDependencies(
projectContext.storageManager,
module,
modulePlatforms,
firstDependency,
this))
@@ -270,7 +269,6 @@ abstract class AnalyzerFacade {
class LazyModuleDependencies<M: ModuleInfo>(
storageManager: StorageManager,
private val module: M,
modulePlatforms: (M) -> MultiTargetPlatform?,
firstDependency: M? = null,
private val resolverForProject: ResolverForProjectImpl<M>
) : ModuleDependencies {
@@ -292,14 +290,6 @@ class LazyModuleDependencies<M: ModuleInfo>(
}.toList()
}
private val implementingModules = storageManager.createLazyValue {
if (modulePlatforms(module) != MultiTargetPlatform.Common) emptySet<M>()
else resolverForProject.modules
.filterTo(mutableSetOf()) {
modulePlatforms(it) != MultiTargetPlatform.Common && module in it.dependencies()
}
}
override val allDependencies: List<ModuleDescriptorImpl> get() = dependencies()
override val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
@@ -308,8 +298,6 @@ class LazyModuleDependencies<M: ModuleInfo>(
resolverForProject.descriptorForModule(it as M)
}
override val allImplementingModules: Set<ModuleDescriptorImpl>
get() = implementingModules().mapTo(mutableSetOf()) { resolverForProject.descriptorForModule(it) }
}
@@ -40,9 +40,6 @@ interface ModuleDescriptor : DeclarationDescriptor {
*/
val allDependencyModules: List<ModuleDescriptor>
// All platform-specific modules depending on common 'this' module (result is empty if this is platform-specific itself)
val allImplementingModules: Set<ModuleDescriptor>
fun <T> getCapability(capability: Capability<T>): T?
class Capability<T>(val name: String) {
@@ -48,9 +48,6 @@ class ModuleDescriptorImpl @JvmOverloads constructor(
private var packageFragmentProviderForModuleContent: PackageFragmentProvider? = null
override var isValid: Boolean = true
set(value) {
field = value
}
override fun assertValid() {
if (!isValid) {
@@ -68,9 +65,6 @@ class ModuleDescriptorImpl @JvmOverloads constructor(
override val allDependencyModules: List<ModuleDescriptor>
get() = this.dependencies.sure { "Dependencies of module $id were not set" }.allDependencies.filter { it != this }
override val allImplementingModules: Set<ModuleDescriptor>
get() = this.dependencies.sure { "Dependencies of module $id were not set" }.allImplementingModules
override fun getPackage(fqName: FqName): PackageViewDescriptor {
assertValid()
return packages(fqName)
@@ -144,12 +138,9 @@ class ModuleDescriptorImpl @JvmOverloads constructor(
interface ModuleDependencies {
val allDependencies: List<ModuleDescriptorImpl>
val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
val allImplementingModules: Set<ModuleDescriptorImpl>
}
class ModuleDependenciesImpl(
override val allDependencies: List<ModuleDescriptorImpl>,
override val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
) : ModuleDependencies {
override val allImplementingModules: Set<ModuleDescriptorImpl> = emptySet()
}
) : ModuleDependencies
@@ -85,12 +85,6 @@ public class ErrorUtils {
return emptyList();
}
@NotNull
@Override
public Set<ModuleDescriptor> getAllImplementingModules() {
return emptySet();
}
@Override
public <R, D> R accept(@NotNull DeclarationDescriptorVisitor<R, D> visitor, D data) {
return null;
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.caches.resolve
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.TargetPlatform
@@ -33,4 +34,5 @@ interface KotlinCacheService {
fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade
fun getSuppressionCache(): KotlinSuppressCache
fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade?
}
@@ -28,8 +28,7 @@ import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.analyzer.LanguageSettingsProvider
import org.jetbrains.kotlin.analyzer.EmptyResolverForProject
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.config.LanguageFeature
@@ -367,6 +366,9 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
return ResolutionFacadeImpl(projectFacade, moduleInfo)
}
override fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade? =
(moduleInfo as? IdeaModuleInfo)?.let { getResolutionFacadeByModuleInfo(it, platform) }
private fun Collection<KtFile>.filterNotInProjectSource(moduleInfo: IdeaModuleInfo) = mapNotNull {
if (it is KtCodeFragment) it.getContextFile() else it
}.filter {
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors
import org.jetbrains.kotlin.idea.highlighter.markers.actualsFor
import org.jetbrains.kotlin.idea.project.targetPlatform
import org.jetbrains.kotlin.idea.util.module
@@ -41,7 +41,7 @@ class KotlinMultiplatformJUnitRecognizer : JUnitRecognizer() {
if (origin.module?.targetPlatform !is TargetPlatformKind.Common) return false
val moduleDescriptor = origin.containingKtFile.findModuleDescriptor()
val implModules = moduleDescriptor.allImplementingCompatibleModules
val implModules = moduleDescriptor.findImplementingDescriptors()
if (implModules.isEmpty()) return false
val bindingContext = origin.analyze(BodyResolveMode.PARTIAL)
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea.facet
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdk
@@ -26,9 +27,13 @@ import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModel
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.*
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
@@ -111,6 +116,35 @@ val mavenLibraryIdToPlatform: Map<String, TargetPlatformKind<*>> by lazy {
.toMap()
}
private fun Module.findImplementedModuleName(modelsProvider: IdeModifiableModelsProvider): String? {
val facetModel = modelsProvider.getModifiableFacetModel(this)
val facet = facetModel.findFacet(KotlinFacetType.TYPE_ID, KotlinFacetType.INSTANCE.defaultFacetName)
return facet?.configuration?.settings?.implementedModuleName
}
private fun Module.findImplementingModules(modelsProvider: IdeModifiableModelsProvider): List<Module> {
return modelsProvider.modules.filter { module ->
module.findImplementedModuleName(modelsProvider) == name
}
}
fun ModuleDescriptor.findImplementingDescriptors(): List<ModuleDescriptor> {
val moduleSourceInfo = getCapability(ModuleInfo.Capability) as? ModuleSourceInfo ?: return emptyList()
val module = moduleSourceInfo.module
val modelsProvider = IdeModifiableModelsProviderImpl(module.project)
val implementingModules = module.findImplementingModules(modelsProvider)
return implementingModules.mapNotNull {
val implementingModuleInfo = when (moduleSourceInfo) {
is ModuleProductionSourceInfo -> it.productionSourceInfo()
is ModuleTestSourceInfo -> it.testSourceInfo()
else -> null
}
implementingModuleInfo?.let {
KotlinCacheService.getInstance(module.project).getResolutionFacadeByModuleInfo(it, it.platform)?.moduleDescriptor
}
}
}
fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider,
useProjectSettings: Boolean,
commitModel: Boolean = false): KotlinFacet {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,14 +19,11 @@ package org.jetbrains.kotlin.idea.highlighter
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.Annotator
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.ModuleProductionSourceInfo
import org.jetbrains.kotlin.idea.caches.resolve.ModuleTestSourceInfo
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
@@ -37,22 +34,6 @@ import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
val ModuleDescriptor.sourceKind: SourceKind
get() = when (getCapability(ModuleInfo.Capability)) {
is ModuleProductionSourceInfo -> SourceKind.PRODUCTION
is ModuleTestSourceInfo -> SourceKind.TEST
else -> SourceKind.OTHER
}
enum class SourceKind { OTHER, PRODUCTION, TEST }
val ModuleDescriptor.allImplementingCompatibleModules
get() = allImplementingModules.filter { other ->
this.sourceKind == SourceKind.OTHER ||
other.sourceKind == SourceKind.OTHER ||
other.sourceKind == this.sourceKind
}
class PlatformExpectedAnnotator : Annotator {
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
val declaration = element as? KtDeclaration ?: return
@@ -60,7 +41,7 @@ class PlatformExpectedAnnotator : Annotator {
if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Common) return
val implementingModules = declaration.findModuleDescriptor().allImplementingCompatibleModules
val implementingModules = declaration.findModuleDescriptor().findImplementingDescriptors()
if (implementingModules.isEmpty()) return
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
@@ -48,7 +48,7 @@ fun getPlatformActualTooltip(declaration: KtDeclaration): String? {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return null
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
val platformModulesWithActuals = commonModuleDescriptor.allImplementingCompatibleModules.filter {
val platformModulesWithActuals = commonModuleDescriptor.findImplementingDescriptors().filter {
it.hasActualsFor(descriptor)
}
if (platformModulesWithActuals.isEmpty()) return null
@@ -74,7 +74,7 @@ private fun DeclarationDescriptor.actualsForExpected(): Collection<DeclarationDe
if (this is MemberDescriptor) {
if (!this.isExpect) return emptyList()
return module.allImplementingCompatibleModules.flatMap { it.actualsFor(this) }
return module.findImplementingDescriptors().flatMap { it.actualsFor(this) }
}
if (this is ValueParameterDescriptor) {
@@ -16,11 +16,13 @@
package org.jetbrains.kotlin.idea.highlighter.markers
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.ModuleProductionSourceInfo
import org.jetbrains.kotlin.idea.caches.resolve.ModuleTestSourceInfo
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.highlighter.sourceKind
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
@@ -30,6 +32,15 @@ import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.getMultiTargetPlatform
val ModuleDescriptor.sourceKind: SourceKind
get() = when (getCapability(ModuleInfo.Capability)) {
is ModuleProductionSourceInfo -> SourceKind.PRODUCTION
is ModuleTestSourceInfo -> SourceKind.TEST
else -> SourceKind.OTHER
}
enum class SourceKind { OTHER, PRODUCTION, TEST }
fun ModuleDescriptor.commonModuleOrNull(): ModuleDescriptor? {
val sourceKind = sourceKind
return allDependencyModules.firstOrNull { dependency ->
@@ -44,7 +44,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.core.isInheritable
import org.jetbrains.kotlin.idea.core.isOverridable
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -292,7 +292,7 @@ private fun collectActualMarkers(declaration: KtNamedDeclaration,
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
if (commonModuleDescriptor.allImplementingCompatibleModules.none { it.hasActualsFor(descriptor) }) return
if (commonModuleDescriptor.findImplementingDescriptors().none { it.hasActualsFor(descriptor) }) return
val anchor = declaration.nameIdentifier ?: declaration
@@ -53,9 +53,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.isInheritable
import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
import org.jetbrains.kotlin.idea.highlighter.markers.hasActualsFor
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.mainReference
@@ -334,7 +334,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
descriptor as? MemberDescriptor ?: return false
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
return commonModuleDescriptor.allImplementingCompatibleModules.any { it.hasActualsFor(descriptor) } ||
return commonModuleDescriptor.findImplementingDescriptors().any { it.hasActualsFor(descriptor) } ||
commonModuleDescriptor.hasActualsFor(descriptor)
}
@@ -1 +1 @@
<error descr="[NO_ACTUAL_FOR_EXPECT] Expected function 'foo' has no actual declaration in module jvm_base for JVM"><error descr="[NO_ACTUAL_FOR_EXPECT] Expected function 'foo' has no actual declaration in module jvm_user for JVM">expect fun foo(): Int</error></error>
<error descr="[NO_ACTUAL_FOR_EXPECT] Expected function 'foo' has no actual declaration in module jvm_base for JVM">expect fun foo(): Int</error>