Introduce cached ModuleDescriptor.implementingDescriptors

This property is used instead of findImplementingDescriptors,
which is basically too slow
This commit is contained in:
Mikhail Glukhikh
2017-09-26 19:34:21 +03:00
parent fa23471397
commit 43f1dbeabf
6 changed files with 29 additions and 17 deletions
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.facet.implementingDescriptors
import org.jetbrains.kotlin.idea.highlighter.markers.actualsFor import org.jetbrains.kotlin.idea.highlighter.markers.actualsFor
import org.jetbrains.kotlin.idea.project.targetPlatform import org.jetbrains.kotlin.idea.project.targetPlatform
import org.jetbrains.kotlin.idea.util.module import org.jetbrains.kotlin.idea.util.module
@@ -41,7 +41,7 @@ class KotlinMultiplatformJUnitRecognizer : JUnitRecognizer() {
if (origin.module?.targetPlatform !is TargetPlatformKind.Common) return false if (origin.module?.targetPlatform !is TargetPlatformKind.Common) return false
val moduleDescriptor = origin.containingKtFile.findModuleDescriptor() val moduleDescriptor = origin.containingKtFile.findModuleDescriptor()
val implModules = moduleDescriptor.findImplementingDescriptors() val implModules = moduleDescriptor.implementingDescriptors
if (implModules.isEmpty()) return false if (implModules.isEmpty()) return false
val bindingContext = origin.analyze(BodyResolveMode.PARTIAL) val bindingContext = origin.analyze(BodyResolveMode.PARTIAL)
@@ -25,8 +25,10 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.projectRoots.ProjectJdkTable import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModel import com.intellij.openapi.roots.ModuleRootModel
import com.intellij.openapi.roots.ProjectRootModificationTracker
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.util.CachedValueProvider
import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.cli.common.arguments.*
@@ -128,11 +130,9 @@ private fun Module.findImplementingModules(modelsProvider: IdeModifiableModelsPr
} }
} }
fun ModuleDescriptor.findImplementingDescriptors(): List<ModuleDescriptor> { private fun Module.findImplementingDescriptors(moduleSourceInfo: ModuleSourceInfo): List<ModuleDescriptor> {
val moduleSourceInfo = getCapability(ModuleInfo.Capability) as? ModuleSourceInfo ?: return emptyList() val modelsProvider = IdeModifiableModelsProviderImpl(project)
val module = moduleSourceInfo.module val implementingModules = findImplementingModules(modelsProvider)
val modelsProvider = IdeModifiableModelsProviderImpl(module.project)
val implementingModules = module.findImplementingModules(modelsProvider)
return implementingModules.mapNotNull { return implementingModules.mapNotNull {
val implementingModuleInfo = when (moduleSourceInfo) { val implementingModuleInfo = when (moduleSourceInfo) {
is ModuleProductionSourceInfo -> it.productionSourceInfo() is ModuleProductionSourceInfo -> it.productionSourceInfo()
@@ -140,11 +140,23 @@ fun ModuleDescriptor.findImplementingDescriptors(): List<ModuleDescriptor> {
else -> null else -> null
} }
implementingModuleInfo?.let { implementingModuleInfo?.let {
KotlinCacheService.getInstance(module.project).getResolutionFacadeByModuleInfo(it, it.platform)?.moduleDescriptor KotlinCacheService.getInstance(project).getResolutionFacadeByModuleInfo(it, it.platform)?.moduleDescriptor
} }
} }
} }
val ModuleDescriptor.implementingDescriptors: List<ModuleDescriptor>
get() {
val moduleSourceInfo = getCapability(ModuleInfo.Capability) as? ModuleSourceInfo ?: return emptyList()
val module = moduleSourceInfo.module
return module.cached(CachedValueProvider {
CachedValueProvider.Result(
module.findImplementingDescriptors(moduleSourceInfo),
ProjectRootModificationTracker.getInstance(module.project)
)
})
}
fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider, fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider,
useProjectSettings: Boolean, useProjectSettings: Boolean,
commitModel: Boolean = false): KotlinFacet { commitModel: Boolean = false): KotlinFacet {
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.facet.implementingDescriptors
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
@@ -41,7 +41,7 @@ class PlatformExpectedAnnotator : Annotator {
if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Common) return if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Common) return
val implementingModules = declaration.findModuleDescriptor().findImplementingDescriptors() val implementingModules = declaration.findModuleDescriptor().implementingDescriptors
if (implementingModules.isEmpty()) return if (implementingModules.isEmpty()) return
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: 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.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.facet.implementingDescriptors
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.MultiTargetPlatform import org.jetbrains.kotlin.resolve.MultiTargetPlatform
@@ -48,7 +48,7 @@ fun getPlatformActualTooltip(declaration: KtDeclaration): String? {
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return null val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return null
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
val platformModulesWithActuals = commonModuleDescriptor.findImplementingDescriptors().filter { val platformModulesWithActuals = commonModuleDescriptor.implementingDescriptors.filter {
it.hasActualsFor(descriptor) it.hasActualsFor(descriptor)
} }
if (platformModulesWithActuals.isEmpty()) return null if (platformModulesWithActuals.isEmpty()) return null
@@ -74,7 +74,7 @@ private fun DeclarationDescriptor.actualsForExpected(): Collection<DeclarationDe
if (this is MemberDescriptor) { if (this is MemberDescriptor) {
if (!this.isExpect) return emptyList() if (!this.isExpect) return emptyList()
return module.findImplementingDescriptors().flatMap { it.actualsFor(this) } return module.implementingDescriptors.flatMap { it.actualsFor(this) }
} }
if (this is ValueParameterDescriptor) { if (this is ValueParameterDescriptor) {
@@ -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.isInheritable
import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.core.isOverridable
import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.facet.implementingDescriptors
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -292,7 +292,7 @@ private fun collectActualMarkers(declaration: KtNamedDeclaration,
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
if (commonModuleDescriptor.findImplementingDescriptors().none { it.hasActualsFor(descriptor) }) return if (commonModuleDescriptor.implementingDescriptors.none { it.hasActualsFor(descriptor) }) return
val anchor = declaration.nameIdentifier ?: declaration val anchor = declaration.nameIdentifier ?: declaration
@@ -53,7 +53,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.core.isInheritable
import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor
import org.jetbrains.kotlin.idea.facet.findImplementingDescriptors import org.jetbrains.kotlin.idea.facet.implementingDescriptors
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
import org.jetbrains.kotlin.idea.highlighter.markers.hasActualsFor import org.jetbrains.kotlin.idea.highlighter.markers.hasActualsFor
@@ -334,7 +334,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
descriptor as? MemberDescriptor ?: return false descriptor as? MemberDescriptor ?: return false
val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor() val commonModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
return commonModuleDescriptor.findImplementingDescriptors().any { it.hasActualsFor(descriptor) } || return commonModuleDescriptor.implementingDescriptors.any { it.hasActualsFor(descriptor) } ||
commonModuleDescriptor.hasActualsFor(descriptor) commonModuleDescriptor.hasActualsFor(descriptor)
} }