[Misc] Refactor Module.cached extension to accept lambda instead of FunctionalInterface
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.caches.project
|
||||||
|
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||||
|
import com.intellij.openapi.util.UserDataHolder
|
||||||
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
|
||||||
|
fun <T> Module.cacheByClass(classForKey: Class<*>, vararg dependencies: Any, provider: () -> T): T {
|
||||||
|
return CachedValuesManager.getManager(project).cache(this, dependencies, classForKey, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Module.cacheByClassInvalidatingOnRootModifications(classForKey: Class<*>, provider: () -> T): T {
|
||||||
|
return cacheByClass(classForKey, ProjectRootModificationTracker.getInstance(project), provider = provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that it uses lambda's class for caching (essentially, anonymous class), which means that all invocations will be cached
|
||||||
|
* by the one and the same key.
|
||||||
|
* It is encouraged to use explicit class, just for the sake of readability.
|
||||||
|
*/
|
||||||
|
fun <T> Module.cacheInvalidatingOnRootModifications(provider: () -> T): T {
|
||||||
|
return cacheByClassInvalidatingOnRootModifications(provider::class.java, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Project.cacheByClass(classForKey: Class<*>, vararg dependencies: Any, provider: () -> T): T {
|
||||||
|
return CachedValuesManager.getManager(this).cache(this, dependencies, classForKey, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Project.cacheByClassInvalidatingOnRootModifications(classForKey: Class<*>, provider: () -> T): T {
|
||||||
|
return cacheByClass(classForKey, ProjectRootModificationTracker.getInstance(this), provider = provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that it uses lambda's class for caching (essentially, anonymous class), which means that all invocations will be cached
|
||||||
|
* by the one and the same key.
|
||||||
|
* It is encouraged to use explicit class, just for the sake of readability.
|
||||||
|
*/
|
||||||
|
fun <T> Project.cacheInvalidatingOnRootModifications(provider: () -> T): T {
|
||||||
|
return cacheByClassInvalidatingOnRootModifications(provider::class.java, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> CachedValuesManager.cache(
|
||||||
|
holder: UserDataHolder,
|
||||||
|
dependencies: Array<out Any>,
|
||||||
|
classForKey: Class<*>,
|
||||||
|
provider: () -> T
|
||||||
|
): T {
|
||||||
|
return getCachedValue(
|
||||||
|
holder,
|
||||||
|
getKeyForClass(classForKey),
|
||||||
|
{ CachedValueProvider.Result.create(provider(), dependencies) },
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
+14
-22
@@ -17,7 +17,6 @@ import com.intellij.openapi.roots.libraries.Library
|
|||||||
import com.intellij.openapi.util.ModificationTracker
|
import com.intellij.openapi.util.ModificationTracker
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import com.intellij.util.PathUtil
|
import com.intellij.util.PathUtil
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||||
@@ -26,6 +25,7 @@ import org.jetbrains.kotlin.analyzer.CombinedModuleInfo
|
|||||||
import org.jetbrains.kotlin.analyzer.LibraryModuleInfo
|
import org.jetbrains.kotlin.analyzer.LibraryModuleInfo
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.analyzer.TrackableModuleInfo
|
import org.jetbrains.kotlin.analyzer.TrackableModuleInfo
|
||||||
|
import org.jetbrains.kotlin.caches.project.cacheByClassInvalidatingOnRootModifications
|
||||||
import org.jetbrains.kotlin.caches.resolve.resolution
|
import org.jetbrains.kotlin.caches.resolve.resolution
|
||||||
import org.jetbrains.kotlin.config.SourceKotlinRootType
|
import org.jetbrains.kotlin.config.SourceKotlinRootType
|
||||||
import org.jetbrains.kotlin.config.TestSourceKotlinRootType
|
import org.jetbrains.kotlin.config.TestSourceKotlinRootType
|
||||||
@@ -177,16 +177,9 @@ sealed class ModuleSourceInfoWithExpectedBy(private val forProduction: Boolean)
|
|||||||
return expectedByModules.mapNotNull { if (forProduction) it.productionSourceInfo() else it.testSourceInfo() }
|
return expectedByModules.mapNotNull { if (forProduction) it.productionSourceInfo() else it.testSourceInfo() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dependencies(): List<IdeaModuleInfo> = module.cached(createCachedValueProvider {
|
override fun dependencies(): List<IdeaModuleInfo> = module.cacheByClassInvalidatingOnRootModifications(this::class.java) {
|
||||||
CachedValueProvider.Result(
|
ideaModelDependencies(module, forProduction, platform)
|
||||||
ideaModelDependencies(module, forProduction, platform),
|
}
|
||||||
ProjectRootModificationTracker.getInstance(module.project)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
// NB: CachedValueProvider must exist separately in Production / Test source info,
|
|
||||||
// otherwise caching does not work properly
|
|
||||||
protected abstract fun <T> createCachedValueProvider(f: () -> CachedValueProvider.Result<T>): CachedValueProvider<T>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ModuleProductionSourceInfo internal constructor(
|
data class ModuleProductionSourceInfo internal constructor(
|
||||||
@@ -200,8 +193,6 @@ data class ModuleProductionSourceInfo internal constructor(
|
|||||||
override fun contentScope(): GlobalSearchScope {
|
override fun contentScope(): GlobalSearchScope {
|
||||||
return enlargedSearchScope(ModuleProductionSourceScope(module), module, isTestScope = false)
|
return enlargedSearchScope(ModuleProductionSourceScope(module), module, isTestScope = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T> createCachedValueProvider(f: () -> CachedValueProvider.Result<T>) = CachedValueProvider { f() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: (module refactoring) do not create ModuleTestSourceInfo when there are no test roots for module
|
//TODO: (module refactoring) do not create ModuleTestSourceInfo when there are no test roots for module
|
||||||
@@ -217,19 +208,20 @@ data class ModuleTestSourceInfo internal constructor(override val module: Module
|
|||||||
|
|
||||||
override fun contentScope(): GlobalSearchScope = enlargedSearchScope(ModuleTestSourceScope(module), module, isTestScope = true)
|
override fun contentScope(): GlobalSearchScope = enlargedSearchScope(ModuleTestSourceScope(module), module, isTestScope = true)
|
||||||
|
|
||||||
override fun modulesWhoseInternalsAreVisible() = module.cached(CachedValueProvider {
|
override fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> =
|
||||||
val list = SmartList<ModuleInfo>()
|
module.cacheByClassInvalidatingOnRootModifications(KeyForModulesWhoseInternalsAreVisible::class.java) {
|
||||||
|
val list = SmartList<ModuleInfo>()
|
||||||
|
|
||||||
list.addIfNotNull(module.productionSourceInfo())
|
list.addIfNotNull(module.productionSourceInfo())
|
||||||
|
|
||||||
TestModuleProperties.getInstance(module).productionModule?.let {
|
TestModuleProperties.getInstance(module).productionModule?.let {
|
||||||
list.addIfNotNull(it.productionSourceInfo())
|
list.addIfNotNull(it.productionSourceInfo())
|
||||||
|
}
|
||||||
|
|
||||||
|
list
|
||||||
}
|
}
|
||||||
|
|
||||||
CachedValueProvider.Result(list, ProjectRootModificationTracker.getInstance(module.project))
|
private object KeyForModulesWhoseInternalsAreVisible
|
||||||
})
|
|
||||||
|
|
||||||
override fun <T> createCachedValueProvider(f: () -> CachedValueProvider.Result<T>) = CachedValueProvider { f() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Module.productionSourceInfo(): ModuleProductionSourceInfo? = if (hasProductionRoots()) ModuleProductionSourceInfo(this) else null
|
fun Module.productionSourceInfo(): ModuleProductionSourceInfo? = if (hasProductionRoots()) ModuleProductionSourceInfo(this) else null
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.idea.caches.project
|
|
||||||
|
|
||||||
import com.intellij.openapi.module.Module
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import com.intellij.psi.util.CachedValuesManager
|
|
||||||
|
|
||||||
fun <T> Module.cached(provider: CachedValueProvider<T>): T {
|
|
||||||
return CachedValuesManager.getManager(project).getCachedValue(this, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> Project.cached(provider: CachedValueProvider<T>): T {
|
|
||||||
return CachedValuesManager.getManager(this).getCachedValue(this, provider)
|
|
||||||
}
|
|
||||||
+5
-5
@@ -13,17 +13,17 @@ import com.intellij.openapi.projectRoots.Sdk
|
|||||||
import com.intellij.openapi.roots.JdkOrderEntry
|
import com.intellij.openapi.roots.JdkOrderEntry
|
||||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||||
import com.intellij.openapi.roots.ModuleRootManager
|
import com.intellij.openapi.roots.ModuleRootManager
|
||||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.isCommon
|
import org.jetbrains.kotlin.platform.isCommon
|
||||||
import org.jetbrains.kotlin.types.typeUtil.closure
|
import org.jetbrains.kotlin.types.typeUtil.closure
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
fun getModuleInfosFromIdeaModel(project: Project, platform: TargetPlatform): List<IdeaModuleInfo> {
|
fun getModuleInfosFromIdeaModel(project: Project, platform: TargetPlatform): List<IdeaModuleInfo> {
|
||||||
val modelInfosCache = project.cached(CachedValueProvider {
|
val modelInfosCache = project.cacheInvalidatingOnRootModifications {
|
||||||
CachedValueProvider.Result(collectModuleInfosFromIdeaModel(project), ProjectRootModificationTracker.getInstance(project))
|
collectModuleInfosFromIdeaModel(project)
|
||||||
})
|
}
|
||||||
|
|
||||||
return modelInfosCache.forPlatform(platform)
|
return modelInfosCache.forPlatform(platform)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-28
@@ -10,10 +10,9 @@ import com.intellij.facet.FacetTypeRegistry
|
|||||||
import com.intellij.openapi.externalSystem.service.project.IdeModelsProviderImpl
|
import com.intellij.openapi.externalSystem.service.project.IdeModelsProviderImpl
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.module.ModuleManager
|
import com.intellij.openapi.module.ModuleManager
|
||||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
|
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
|
||||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||||
import org.jetbrains.kotlin.config.KotlinFacetSettings
|
import org.jetbrains.kotlin.config.KotlinFacetSettings
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
@@ -49,37 +48,30 @@ val KotlinFacetSettings.isMPPModule: Boolean
|
|||||||
private val Module.facetSettings get() = KotlinFacet.get(this)?.configuration?.settings
|
private val Module.facetSettings get() = KotlinFacet.get(this)?.configuration?.settings
|
||||||
|
|
||||||
val Module.implementingModules: List<Module>
|
val Module.implementingModules: List<Module>
|
||||||
get() = cached(CachedValueProvider {
|
get() = cacheInvalidatingOnRootModifications {
|
||||||
val moduleManager = ModuleManager.getInstance(project)
|
val moduleManager = ModuleManager.getInstance(project)
|
||||||
CachedValueProvider.Result(
|
|
||||||
if (isNewMPPModule) {
|
if (isNewMPPModule) {
|
||||||
moduleManager.getModuleDependentModules(this).filter {
|
moduleManager.getModuleDependentModules(this).filter {
|
||||||
it.isNewMPPModule && it.externalProjectId == externalProjectId
|
it.isNewMPPModule && it.externalProjectId == externalProjectId
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
moduleManager.modules.filter { name in it.findOldFashionedImplementedModuleNames() }
|
moduleManager.modules.filter { name in it.findOldFashionedImplementedModuleNames() }
|
||||||
},
|
}
|
||||||
ProjectRootModificationTracker.getInstance(project)
|
}
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
val Module.implementedModules: List<Module>
|
val Module.implementedModules: List<Module>
|
||||||
get() = cached<List<Module>>(
|
get() = cacheInvalidatingOnRootModifications {
|
||||||
CachedValueProvider {
|
if (isNewMPPModule) {
|
||||||
CachedValueProvider.Result(
|
rootManager.dependencies.filter {
|
||||||
if (isNewMPPModule) {
|
// TODO: remove additional android check
|
||||||
rootManager.dependencies.filter {
|
|
||||||
// TODO: remove additional android check
|
|
||||||
it.isNewMPPModule && it.platform.isCommon() && it.externalProjectId == externalProjectId && (isAndroidModule() || it.isTestModule == isTestModule)
|
it.isNewMPPModule && it.platform.isCommon() && it.externalProjectId == externalProjectId && (isAndroidModule() || it.isTestModule == isTestModule)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val modelsProvider = IdeModelsProviderImpl(project)
|
val modelsProvider = IdeModelsProviderImpl(project)
|
||||||
findOldFashionedImplementedModuleNames().mapNotNull { modelsProvider.findIdeModule(it) }
|
findOldFashionedImplementedModuleNames().mapNotNull { modelsProvider.findIdeModule(it) }
|
||||||
},
|
|
||||||
ProjectRootModificationTracker.getInstance(project)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
private fun Module.findOldFashionedImplementedModuleNames(): List<String> {
|
private fun Module.findOldFashionedImplementedModuleNames(): List<String> {
|
||||||
val facet = FacetManager.getInstance(this).findFacet(
|
val facet = FacetManager.getInstance(this).findFacet(
|
||||||
|
|||||||
+10
-13
@@ -9,12 +9,10 @@ import com.intellij.openapi.module.Module
|
|||||||
import com.intellij.openapi.module.ModuleUtil
|
import com.intellij.openapi.module.ModuleUtil
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.roots.ModuleRootManager
|
import com.intellij.openapi.roots.ModuleRootManager
|
||||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
|
||||||
import com.intellij.openapi.util.ModificationTracker
|
import com.intellij.openapi.util.ModificationTracker
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import com.intellij.util.CommonProcessors
|
import com.intellij.util.CommonProcessors
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.idea.caches.project.cached
|
import org.jetbrains.kotlin.caches.project.cacheByClassInvalidatingOnRootModifications
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class KotlinModuleOutOfCodeBlockModificationTracker private constructor(private val module: Module, private val updater: Updater) :
|
class KotlinModuleOutOfCodeBlockModificationTracker private constructor(private val module: Module, private val updater: Updater) :
|
||||||
@@ -29,18 +27,17 @@ class KotlinModuleOutOfCodeBlockModificationTracker private constructor(private
|
|||||||
// Avoid implicit capturing for this to make CachedValueStabilityChecker happy
|
// Avoid implicit capturing for this to make CachedValueStabilityChecker happy
|
||||||
val module = module
|
val module = module
|
||||||
|
|
||||||
module.cached(CachedValueProvider {
|
module.cacheByClassInvalidatingOnRootModifications(KeyForCachedDependencies::class.java) {
|
||||||
CachedValueProvider.Result.create(
|
HashSet<Module>().also { resultModuleSet ->
|
||||||
HashSet<Module>().also { resultModuleSet ->
|
ModuleRootManager.getInstance(module).orderEntries().recursively().forEachModule(
|
||||||
ModuleRootManager.getInstance(module).orderEntries().recursively().forEachModule(
|
CommonProcessors.CollectProcessor(resultModuleSet)
|
||||||
CommonProcessors.CollectProcessor(resultModuleSet)
|
)
|
||||||
)
|
}
|
||||||
},
|
}
|
||||||
ProjectRootModificationTracker.getInstance(module.project)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object KeyForCachedDependencies
|
||||||
|
|
||||||
override fun getModificationCount(): Long {
|
override fun getModificationCount(): Long {
|
||||||
val currentGlobalCount = kotlinOutOfCodeBlockTracker.modificationCount
|
val currentGlobalCount = kotlinOutOfCodeBlockTracker.modificationCount
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user