Split global cache in KotlinCacheService into separate caches for libraries and for modules

This commit is contained in:
Pavel V. Talanov
2014-09-16 14:33:58 +04:00
parent faa9f4bb14
commit 8368689af8
3 changed files with 42 additions and 22 deletions
@@ -151,4 +151,6 @@ private data class LibraryWithoutSourceScope(project: Project, private val libra
//TODO: (module refactoring) android sdk has modified scope //TODO: (module refactoring) android sdk has modified scope
private data class SdkScope(project: Project, private val sdk: Sdk) : private data class SdkScope(project: Project, private val sdk: Sdk) :
LibraryScopeBase(project, sdk.getRootProvider().getFiles(OrderRootType.CLASSES), array<VirtualFile>()) LibraryScopeBase(project, sdk.getRootProvider().getFiles(OrderRootType.CLASSES), array<VirtualFile>())
private fun IdeaModuleInfo.isLibraryClasses() = this is SdkInfo || this is LibraryInfo
@@ -39,6 +39,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.context.GlobalContext import org.jetbrains.jet.context.GlobalContext
import org.jetbrains.jet.plugin.stubindex.JetSourceFilterScope import org.jetbrains.jet.plugin.stubindex.JetSourceFilterScope
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.jet.utils.keysToMap
private val LOG = Logger.getInstance(javaClass<KotlinCacheService>()) private val LOG = Logger.getInstance(javaClass<KotlinCacheService>())
@@ -65,22 +66,37 @@ public class KotlinCacheService(val project: Project) {
public fun getInstance(project: Project): KotlinCacheService = ServiceManager.getService(project, javaClass<KotlinCacheService>())!! public fun getInstance(project: Project): KotlinCacheService = ServiceManager.getService(project, javaClass<KotlinCacheService>())!!
} }
private fun globalResolveSessionProvider(platform: TargetPlatform, syntheticFiles: Collection<JetFile> = listOf()): fun globalResolveSessionProvider(
() -> CachedValueProvider.Result<ModuleResolverProvider> = { platform: TargetPlatform,
reuseDataFromCache: KotlinResolveCache? = null,
syntheticFiles: Collection<JetFile> = listOf(),
moduleFilter: (IdeaModuleInfo) -> Boolean = { true }
): () -> CachedValueProvider.Result<ModuleResolverProvider> = {
val analyzerFacade = AnalyzerFacadeProvider.getAnalyzerFacade(platform) val analyzerFacade = AnalyzerFacadeProvider.getAnalyzerFacade(platform)
val moduleMapping = createModuleResolverProvider(project, analyzerFacade, syntheticFiles) val delegateResolverProvider = reuseDataFromCache?.moduleResolverProvider ?: EmptyModuleResolverProvider
val moduleResolverProvider = createModuleResolverProvider(project, analyzerFacade, syntheticFiles, delegateResolverProvider, moduleFilter)
CachedValueProvider.Result.create( CachedValueProvider.Result.create(
moduleMapping, moduleResolverProvider,
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT,
moduleMapping.exceptionTracker moduleResolverProvider.exceptionTracker
) )
} }
private val globalCachesPerPlatform = mapOf( private val globalCachesPerPlatform = listOf(JVM, JS).keysToMap { platform -> GlobalCache(platform) }
JVM to KotlinResolveCache(project, globalResolveSessionProvider(JVM)),
JS to KotlinResolveCache(project, globalResolveSessionProvider(JS)) private inner class GlobalCache(platform: TargetPlatform) {
) val librariesCache = KotlinResolveCache(
project, globalResolveSessionProvider(platform, moduleFilter = { it.isLibraryClasses() })
)
val modulesCache = KotlinResolveCache(
project, globalResolveSessionProvider(platform,
reuseDataFromCache = librariesCache,
moduleFilter = { !it.isLibraryClasses() })
)
}
private fun getGlobalCache(platform: TargetPlatform) = globalCachesPerPlatform[platform]!!.modulesCache
private val syntheticFileCaches = object : SLRUCache<JetFile, KotlinResolveCache>(2, 3) { private val syntheticFileCaches = object : SLRUCache<JetFile, KotlinResolveCache>(2, 3) {
override fun createValue(file: JetFile?): KotlinResolveCache { override fun createValue(file: JetFile?): KotlinResolveCache {
@@ -88,7 +104,7 @@ public class KotlinCacheService(val project: Project) {
project, project,
globalResolveSessionProvider( globalResolveSessionProvider(
TargetPlatformDetector.getPlatform(file!!), TargetPlatformDetector.getPlatform(file!!),
listOf(file) syntheticFiles = listOf(file)
) )
) )
} }
@@ -101,7 +117,7 @@ public class KotlinCacheService(val project: Project) {
} }
public fun getGlobalLazyResolveSession(file: JetFile, platform: TargetPlatform): ResolveSessionForBodies { public fun getGlobalLazyResolveSession(file: JetFile, platform: TargetPlatform): ResolveSessionForBodies {
return globalCachesPerPlatform[platform]!!.getLazyResolveSession(file) return getGlobalCache(platform).getLazyResolveSession(file)
} }
public fun getLazyResolveSession(element: JetElement): ResolveSessionForBodies { public fun getLazyResolveSession(element: JetElement): ResolveSessionForBodies {
@@ -121,8 +137,7 @@ public class KotlinCacheService(val project: Project) {
return getCacheForSyntheticFile(firstFile).getAnalysisResultsForElements(elements) return getCacheForSyntheticFile(firstFile).getAnalysisResultsForElements(elements)
} }
val resolveCache = globalCachesPerPlatform[TargetPlatformDetector.getPlatform(firstFile)]!! return getGlobalCache(TargetPlatformDetector.getPlatform(firstFile)).getAnalysisResultsForElements(elements)
return resolveCache.getAnalysisResultsForElements(elements)
} }
private fun isFileInScope(jetFile: JetFile): Boolean { private fun isFileInScope(jetFile: JetFile): Boolean {
@@ -138,6 +153,6 @@ public class KotlinCacheService(val project: Project) {
} }
public fun <T> get(extension: CacheExtension<T>): T { public fun <T> get(extension: CacheExtension<T>): T {
return globalCachesPerPlatform[extension.platform]!![extension] return getGlobalCache(extension.platform)[extension]
} }
} }
@@ -39,17 +39,20 @@ fun createModuleResolverProvider(
project: Project, project: Project,
analyzerFacade: AnalyzerFacade<ResolverForModule, JvmPlatformParameters>, analyzerFacade: AnalyzerFacade<ResolverForModule, JvmPlatformParameters>,
syntheticFiles: Collection<JetFile>, syntheticFiles: Collection<JetFile>,
delegateProvider: ModuleResolverProvider = EmptyModuleResolverProvider delegateProvider: ModuleResolverProvider,
moduleFilter: (IdeaModuleInfo) -> Boolean
): ModuleResolverProvider { ): ModuleResolverProvider {
val allModuleInfos = collectAllModuleInfosFromIdeaModel(project).toHashSet() val allModuleInfos = collectAllModuleInfosFromIdeaModel(project).toHashSet()
val globalContext = (delegateProvider as? ModuleResolverProviderImpl)?.globalContext ?: GlobalContext() val globalContext = (delegateProvider as? ModuleResolverProviderImpl)?.globalContext ?: GlobalContext()
fun createResolverForProject(): ResolverForProject<IdeaModuleInfo, ResolverForModule> { val syntheticFilesByModule = syntheticFiles.groupBy { it.getModuleInfo() }
val syntheticFilesByModule = syntheticFiles.groupBy { it.getModuleInfo() } allModuleInfos.addAll(syntheticFilesByModule.keySet())
allModuleInfos.addAll(syntheticFilesByModule.keySet())
val modulesToCreateResolversFor = allModuleInfos.filter(moduleFilter)
fun createResolverForProject(): ResolverForProject<IdeaModuleInfo, ResolverForModule> {
val modulesContent = {(module: IdeaModuleInfo) -> val modulesContent = {(module: IdeaModuleInfo) ->
ModuleContent(syntheticFilesByModule[module] ?: listOf(), module.contentScope()) ModuleContent(syntheticFilesByModule[module] ?: listOf(), module.contentScope())
} }
@@ -61,14 +64,14 @@ fun createModuleResolverProvider(
} }
val resolverForProject = analyzerFacade.setupResolverForProject( val resolverForProject = analyzerFacade.setupResolverForProject(
globalContext, project, allModuleInfos, modulesContent, jvmPlatformParameters, delegateProvider.resolverForProject globalContext, project, modulesToCreateResolversFor, modulesContent, jvmPlatformParameters, delegateProvider.resolverForProject
) )
return resolverForProject return resolverForProject
} }
val resolverForProject = createResolverForProject() val resolverForProject = createResolverForProject()
val moduleToBodiesResolveSession = allModuleInfos.keysToMap { val moduleToBodiesResolveSession = modulesToCreateResolversFor.keysToMap {
module -> module ->
val analyzer = resolverForProject.resolverForModule(module) val analyzer = resolverForProject.resolverForModule(module)
ResolveSessionForBodies(project, analyzer.lazyResolveSession) ResolveSessionForBodies(project, analyzer.lazyResolveSession)