Introduce separate cache for scripts

^KT-22588 Fixed
This commit is contained in:
Natalia Selezneva
2018-05-04 12:18:08 +03:00
parent 71703636bc
commit 41653e9a50
2 changed files with 39 additions and 13 deletions
@@ -35,8 +35,9 @@ data class ScriptModuleInfo(
override val moduleOrigin: ModuleOrigin
get() = ModuleOrigin.OTHER
val externalDependencies: ScriptDependencies
get() = ScriptDependenciesManager.getInstance(project).getScriptDependencies(scriptFile)
val externalDependencies: ScriptDependencies by lazy {
ScriptDependenciesManager.getInstance(project).getScriptDependencies(scriptFile)
}
val relatedModuleSourceInfo: ModuleSourceInfo? = getScriptRelatedModuleInfo(project, scriptFile)
@@ -216,8 +216,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
val dependenciesForSyntheticFileCache =
listOf(
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT,
filesModificationTracker,
ScriptDependenciesModificationTracker.getInstance(project)
filesModificationTracker
)
val resolverDebugName =
@@ -383,17 +382,37 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
}
}
private val scriptsCacheProvider = CachedValueProvider {
CachedValueProvider.Result(
object : SLRUCache<Set<KtFile>, ProjectResolutionFacade>(2, 3) {
override fun createValue(files: Set<KtFile>) = createFacadeForFilesWithSpecialModuleInfo(files)
},
LibraryModificationTracker.getInstance(project),
ProjectRootModificationTracker.getInstance(project),
ScriptDependenciesModificationTracker.getInstance(project))
}
private fun getFacadeForScripts(files: Set<KtFile>): ProjectResolutionFacade {
return CachedValuesManager.getManager(project).getCachedValue(project, scriptsCacheProvider).get(files)
}
private fun getFacadeToAnalyzeFiles(files: Collection<KtFile>): ResolutionFacade {
val file = files.first()
val moduleInfo = file.getModuleInfo()
val specialFiles = files.filterNotInProjectSourceOrScript(moduleInfo)
return if (specialFiles.isNotEmpty()) {
val projectFacade = getFacadeForSpecialFiles(specialFiles)
ModuleResolutionFacadeImpl(projectFacade, moduleInfo)
} else {
val platform = TargetPlatformDetector.getPlatform(file)
getResolutionFacadeByModuleInfo(moduleInfo, platform)
val scripts = files.filterScripts()
if (scripts.isNotEmpty()) {
val projectFacade = getFacadeForScripts(scripts)
return ModuleResolutionFacadeImpl(projectFacade, moduleInfo)
}
val specialFiles = files.filterNotInProjectSource(moduleInfo)
if (specialFiles.isNotEmpty()) {
val projectFacade = getFacadeForSpecialFiles(specialFiles)
return ModuleResolutionFacadeImpl(projectFacade, moduleInfo)
}
val platform = TargetPlatformDetector.getPlatform(file)
return getResolutionFacadeByModuleInfo(moduleInfo, platform)
}
override fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade? {
@@ -421,14 +440,20 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
override fun getResolutionFacadeByModuleInfo(moduleInfo: ModuleInfo, platform: TargetPlatform): ResolutionFacade? =
(moduleInfo as? IdeaModuleInfo)?.let { getResolutionFacadeByModuleInfo(it, platform) }
private fun Collection<KtFile>.filterNotInProjectSourceOrScript(moduleInfo: IdeaModuleInfo): Set<KtFile> {
private fun Collection<KtFile>.filterNotInProjectSource (moduleInfo: IdeaModuleInfo): Set<KtFile> {
return mapNotNull {
if (it is KtCodeFragment) it.getContextFile() else it
}.filter {
!ProjectRootsUtil.isInProjectSource(it) || !moduleInfo.contentScope().contains(it) || it.isScript()
!ProjectRootsUtil.isInProjectSource(it) || !moduleInfo.contentScope().contains(it)
}.toSet()
}
private fun Collection<KtFile>.filterScripts(): Set<KtFile> {
return mapNotNull {
if (it is KtCodeFragment) it.getContextFile() else it
}.filter { it.isScript() }.toSet()
}
private fun KtCodeFragment.getContextFile(): KtFile? {
val contextElement = context ?: return null
val contextFile = (contextElement as? KtElement)?.containingKtFile