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
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.plugin.stubindex.JetSourceFilterScope
import com.intellij.psi.PsiElement
import org.jetbrains.jet.utils.keysToMap
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>())!!
}
private fun globalResolveSessionProvider(platform: TargetPlatform, syntheticFiles: Collection<JetFile> = listOf()):
() -> CachedValueProvider.Result<ModuleResolverProvider> = {
fun globalResolveSessionProvider(
platform: TargetPlatform,
reuseDataFromCache: KotlinResolveCache? = null,
syntheticFiles: Collection<JetFile> = listOf(),
moduleFilter: (IdeaModuleInfo) -> Boolean = { true }
): () -> CachedValueProvider.Result<ModuleResolverProvider> = {
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(
moduleMapping,
moduleResolverProvider,
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT,
moduleMapping.exceptionTracker
moduleResolverProvider.exceptionTracker
)
}
private val globalCachesPerPlatform = mapOf(
JVM to KotlinResolveCache(project, globalResolveSessionProvider(JVM)),
JS to KotlinResolveCache(project, globalResolveSessionProvider(JS))
)
private val globalCachesPerPlatform = listOf(JVM, JS).keysToMap { platform -> GlobalCache(platform) }
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) {
override fun createValue(file: JetFile?): KotlinResolveCache {
@@ -88,7 +104,7 @@ public class KotlinCacheService(val project: Project) {
project,
globalResolveSessionProvider(
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 {
return globalCachesPerPlatform[platform]!!.getLazyResolveSession(file)
return getGlobalCache(platform).getLazyResolveSession(file)
}
public fun getLazyResolveSession(element: JetElement): ResolveSessionForBodies {
@@ -121,8 +137,7 @@ public class KotlinCacheService(val project: Project) {
return getCacheForSyntheticFile(firstFile).getAnalysisResultsForElements(elements)
}
val resolveCache = globalCachesPerPlatform[TargetPlatformDetector.getPlatform(firstFile)]!!
return resolveCache.getAnalysisResultsForElements(elements)
return getGlobalCache(TargetPlatformDetector.getPlatform(firstFile)).getAnalysisResultsForElements(elements)
}
private fun isFileInScope(jetFile: JetFile): Boolean {
@@ -138,6 +153,6 @@ public class KotlinCacheService(val project: Project) {
}
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,
analyzerFacade: AnalyzerFacade<ResolverForModule, JvmPlatformParameters>,
syntheticFiles: Collection<JetFile>,
delegateProvider: ModuleResolverProvider = EmptyModuleResolverProvider
delegateProvider: ModuleResolverProvider,
moduleFilter: (IdeaModuleInfo) -> Boolean
): ModuleResolverProvider {
val allModuleInfos = collectAllModuleInfosFromIdeaModel(project).toHashSet()
val globalContext = (delegateProvider as? ModuleResolverProviderImpl)?.globalContext ?: GlobalContext()
fun createResolverForProject(): ResolverForProject<IdeaModuleInfo, ResolverForModule> {
val syntheticFilesByModule = syntheticFiles.groupBy { it.getModuleInfo() }
allModuleInfos.addAll(syntheticFilesByModule.keySet())
val syntheticFilesByModule = syntheticFiles.groupBy { it.getModuleInfo() }
allModuleInfos.addAll(syntheticFilesByModule.keySet())
val modulesToCreateResolversFor = allModuleInfos.filter(moduleFilter)
fun createResolverForProject(): ResolverForProject<IdeaModuleInfo, ResolverForModule> {
val modulesContent = {(module: IdeaModuleInfo) ->
ModuleContent(syntheticFilesByModule[module] ?: listOf(), module.contentScope())
}
@@ -61,14 +64,14 @@ fun createModuleResolverProvider(
}
val resolverForProject = analyzerFacade.setupResolverForProject(
globalContext, project, allModuleInfos, modulesContent, jvmPlatformParameters, delegateProvider.resolverForProject
globalContext, project, modulesToCreateResolversFor, modulesContent, jvmPlatformParameters, delegateProvider.resolverForProject
)
return resolverForProject
}
val resolverForProject = createResolverForProject()
val moduleToBodiesResolveSession = allModuleInfos.keysToMap {
val moduleToBodiesResolveSession = modulesToCreateResolversFor.keysToMap {
module ->
val analyzer = resolverForProject.resolverForModule(module)
ResolveSessionForBodies(project, analyzer.lazyResolveSession)