Do not invalidate package caches on generic events, KT-25264

This commit is contained in:
Vladimir Dolzhenko
2019-07-17 17:18:10 +02:00
parent 3e9765f5bb
commit 022275b781
15 changed files with 145 additions and 62 deletions
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.idea.caches
import com.intellij.ProjectTopics
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.Logger
@@ -87,7 +86,7 @@ class KotlinPackageContentModificationListener(private val project: Project) {
class KotlinPackageStatementPsiTreeChangePreprocessor(private val project: Project) : PsiTreeChangePreprocessor {
override fun treeChanged(event: PsiTreeChangeEventImpl) {
val eFile = event.file ?: event.child as? PsiFile
if (eFile == null) LOG.debugIfEnabled(project, "Got PsiEvent: $event without file", true)
if (eFile == null) LOG.debugIfEnabled(project, true) { "Got PsiEvent: $event without file" }
val file = eFile as? KtFile ?: return
when (event.code) {
@@ -96,7 +95,7 @@ class KotlinPackageStatementPsiTreeChangePreprocessor(private val project: Proje
PsiTreeChangeEventImpl.PsiEventType.CHILD_REPLACED,
PsiTreeChangeEventImpl.PsiEventType.CHILD_REMOVED -> {
val child = event.child ?: run {
LOG.debugIfEnabled(project, "Got PsiEvent: $event without child", true)
LOG.debugIfEnabled(project, true) { "Got PsiEvent: $event without child" }
return
}
if (child.getParentOfType<KtPackageDirective>(false) != null)
@@ -104,10 +103,10 @@ class KotlinPackageStatementPsiTreeChangePreprocessor(private val project: Proje
}
PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED -> {
val parent = event.parent ?: run {
LOG.debugIfEnabled(project, "Got PsiEvent: $event without parent", true)
LOG.debugIfEnabled(project, true) { "Got PsiEvent: $event without parent" }
return
}
if (parent.getChildrenOfType<KtPackageDirective>().any())
if (!event.isGenericChange && (parent.getChildrenOfType<KtPackageDirective>().any() || parent is KtPackageDirective))
ServiceManager.getService(project, PerModulePackageCacheService::class.java).notifyPackageChange(file)
}
else -> {
@@ -244,7 +243,7 @@ class PerModulePackageCacheService(private val project: Project) {
}
private fun invalidateCacheForModuleSourceInfo(moduleSourceInfo: ModuleSourceInfo) {
LOG.debugIfEnabled(project, "Invalidated cache for $moduleSourceInfo", false)
LOG.debugIfEnabled(project) { "Invalidated cache for $moduleSourceInfo" }
val perSourceInfoData = cache[moduleSourceInfo.module] ?: return
val dataForSourceInfo = perSourceInfoData[moduleSourceInfo] ?: return
dataForSourceInfo.clear()
@@ -264,14 +263,14 @@ class PerModulePackageCacheService(private val project: Project) {
if (sourceRootUrls.any { url ->
vfile.containedInOrContains(url)
}) {
LOG.debugIfEnabled(project, "Invalidated cache for $module")
LOG.debugIfEnabled(project) { "Invalidated cache for $module" }
data.clear()
}
}
} else {
val infoByVirtualFile = getModuleInfoByVirtualFile(project, vfile)
if (infoByVirtualFile == null || infoByVirtualFile !is ModuleSourceInfo) {
LOG.debugIfEnabled(project, "Skip $vfile as it has mismatched ModuleInfo=$infoByVirtualFile")
LOG.debugIfEnabled(project) { "Skip $vfile as it has mismatched ModuleInfo=$infoByVirtualFile" }
}
(infoByVirtualFile as? ModuleSourceInfo)?.let {
invalidateCacheForModuleSourceInfo(it)
@@ -283,13 +282,13 @@ class PerModulePackageCacheService(private val project: Project) {
pendingKtFileChanges.processPending { file ->
if (file.virtualFile != null && file.virtualFile !in projectScope) {
LOG.debugIfEnabled(project, "Skip $file without vFile, or not in scope: ${file.virtualFile?.let { it !in projectScope }}")
LOG.debugIfEnabled(project) { "Skip $file without vFile, or not in scope: ${file.virtualFile?.let { it !in projectScope }}" }
return@processPending
}
val nullableModuleInfo = file.getNullableModuleInfo()
(nullableModuleInfo as? ModuleSourceInfo)?.let { invalidateCacheForModuleSourceInfo(it) }
if (nullableModuleInfo == null || nullableModuleInfo !is ModuleSourceInfo) {
LOG.debugIfEnabled(project, "Skip $file as it has mismatched ModuleInfo=$nullableModuleInfo")
LOG.debugIfEnabled(project) { "Skip $file as it has mismatched ModuleInfo=$nullableModuleInfo" }
}
implicitPackagePrefixCache.update(file)
}
@@ -329,7 +328,7 @@ class PerModulePackageCacheService(private val project: Project) {
return cacheForCurrentModuleInfo.getOrPut(packageFqName) {
val packageExists = PackageIndexUtil.packageExists(packageFqName, moduleInfo.contentScope(), project)
LOG.debugIfEnabled(project, "Computed cache value for $packageFqName in $moduleInfo is $packageExists")
LOG.debugIfEnabled(project) { "Computed cache value for $packageFqName in $moduleInfo is $packageExists" }
packageExists
}
}
@@ -351,16 +350,14 @@ class PerModulePackageCacheService(private val project: Project) {
}
}
private fun Logger.debugIfEnabled(project: Project, message: String, withCurrentTrace: Boolean = false) {
private fun Logger.debugIfEnabled(project: Project, withCurrentTrace: Boolean = false, message: () -> String) {
if (ApplicationManager.getApplication().isUnitTestMode && project.DEBUG_LOG_ENABLE_PerModulePackageCache) {
val msg = message()
if (withCurrentTrace) {
val e = Exception().apply { fillInStackTrace() }
this.debug(message, e)
this.debug(msg, e)
} else {
this.debug(message)
this.debug(msg)
}
}
}