Add modCounter to invalidate synthetic file cache
#KT-35186 Fixed
This commit is contained in:
+4
-9
@@ -44,7 +44,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.caches.project.*
|
import org.jetbrains.kotlin.idea.caches.project.*
|
||||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.contextWithCompositeExceptionTracker
|
import org.jetbrains.kotlin.idea.caches.resolve.util.contextWithCompositeExceptionTracker
|
||||||
import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener
|
|
||||||
import org.jetbrains.kotlin.idea.caches.trackers.outOfBlockModificationCount
|
import org.jetbrains.kotlin.idea.caches.trackers.outOfBlockModificationCount
|
||||||
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
||||||
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesModificationTracker
|
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesModificationTracker
|
||||||
@@ -255,13 +254,9 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
|||||||
val settings = specialModuleInfo.platformSettings(specialModuleInfo.platform ?: targetPlatform)
|
val settings = specialModuleInfo.platformSettings(specialModuleInfo.platform ?: targetPlatform)
|
||||||
|
|
||||||
// Dummy files created e.g. by J2K do not receive events.
|
// Dummy files created e.g. by J2K do not receive events.
|
||||||
val dependenciesForSyntheticFileCache = if (files.all { it.originalFile != it }) {
|
val dependencyTrackerForSyntheticFileCache = if (files.all { it.originalFile != it }) {
|
||||||
emptyList()
|
ModificationTracker { files.sumByLong { it.outOfBlockModificationCount } }
|
||||||
} else {
|
} else ModificationTracker { files.sumByLong { it.modificationStamp } }
|
||||||
listOf(ModificationTracker {
|
|
||||||
files.sumByLong { it.modificationStamp }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
val resolverDebugName =
|
val resolverDebugName =
|
||||||
"$resolverForSpecialInfoName $specialModuleInfo for files ${files.joinToString { it.name }} for platform $targetPlatform"
|
"$resolverForSpecialInfoName $specialModuleInfo for files ${files.joinToString { it.name }} for platform $targetPlatform"
|
||||||
@@ -282,7 +277,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
|||||||
syntheticFiles = files,
|
syntheticFiles = files,
|
||||||
reuseDataFrom = reuseDataFrom,
|
reuseDataFrom = reuseDataFrom,
|
||||||
moduleFilter = moduleFilter,
|
moduleFilter = moduleFilter,
|
||||||
dependencies = dependenciesForSyntheticFileCache,
|
dependencies = listOf(dependencyTrackerForSyntheticFileCache),
|
||||||
invalidateOnOOCB = true,
|
invalidateOnOOCB = true,
|
||||||
allModules = allModules
|
allModules = allModules
|
||||||
)
|
)
|
||||||
|
|||||||
+21
-32
@@ -92,20 +92,18 @@ class KotlinCodeBlockModificationListener(
|
|||||||
val changedElements = changeSet.changedElements
|
val changedElements = changeSet.changedElements
|
||||||
|
|
||||||
// skip change if it contains only virtual/fake change
|
// skip change if it contains only virtual/fake change
|
||||||
if (changedElements.isNotEmpty() &&
|
if (changedElements.isNotEmpty()) {
|
||||||
// ignore formatting (whitespaces etc) change
|
// ignore formatting (whitespaces etc)
|
||||||
(isFormattingChange(changeSet) ||
|
if (isFormattingChange(changeSet) || isCommentChange(changeSet)) return
|
||||||
// ignore comment change
|
}
|
||||||
isCommentChange(changeSet) ||
|
|
||||||
changedElements.all { !it.psi.isPhysical })
|
|
||||||
) return
|
|
||||||
|
|
||||||
val inBlockChange = inBlockModifications(changedElements)
|
val inBlockElements = inBlockModifications(changedElements)
|
||||||
|
|
||||||
if (!inBlockChange) {
|
val physical = ktFile.isPhysical
|
||||||
|
if (inBlockElements.isEmpty()) {
|
||||||
messageBusConnection.deliverImmediately()
|
messageBusConnection.deliverImmediately()
|
||||||
|
|
||||||
if (ktFile.isPhysical && !isReplLine(ktFile.virtualFile)) {
|
if (physical && !isReplLine(ktFile.virtualFile)) {
|
||||||
if (isLanguageTrackerEnabled) {
|
if (isLanguageTrackerEnabled) {
|
||||||
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
|
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
|
||||||
perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, true)
|
perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, true)
|
||||||
@@ -116,7 +114,9 @@ class KotlinCodeBlockModificationListener(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
incOutOfBlockModificationCount(ktFile)
|
ktFile.incOutOfBlockModificationCount()
|
||||||
|
} else if (physical) {
|
||||||
|
inBlockElements.forEach { it.containingKtFile.addInBlockModifiedItem(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -165,37 +165,20 @@ class KotlinCodeBlockModificationListener(
|
|||||||
return file.getUserData(KOTLIN_CONSOLE_KEY) == true
|
return file.getUserData(KOTLIN_CONSOLE_KEY) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun incOutOfBlockModificationCount(file: KtFile) {
|
|
||||||
file.clearInBlockModifications()
|
|
||||||
|
|
||||||
val count = file.getUserData(FILE_OUT_OF_BLOCK_MODIFICATION_COUNT) ?: 0
|
|
||||||
file.putUserData(FILE_OUT_OF_BLOCK_MODIFICATION_COUNT, count + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun incFileModificationCount(file: KtFile) {
|
private fun incFileModificationCount(file: KtFile) {
|
||||||
val tracker = file.getUserData(PER_FILE_MODIFICATION_TRACKER)
|
val tracker = file.getUserData(PER_FILE_MODIFICATION_TRACKER)
|
||||||
?: file.putUserDataIfAbsent(PER_FILE_MODIFICATION_TRACKER, SimpleModificationTracker())
|
?: file.putUserDataIfAbsent(PER_FILE_MODIFICATION_TRACKER, SimpleModificationTracker())
|
||||||
tracker.incModificationCount()
|
tracker.incModificationCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inBlockModifications(elements: Array<ASTNode>): Boolean {
|
private fun inBlockModifications(elements: Array<ASTNode>): List<KtElement> {
|
||||||
// When a code fragment is reparsed, Intellij doesn't do an AST diff and considers the entire
|
// When a code fragment is reparsed, Intellij doesn't do an AST diff and considers the entire
|
||||||
// contents to be replaced, which is represented in a POM event as an empty list of changed elements
|
// contents to be replaced, which is represented in a POM event as an empty list of changed elements
|
||||||
if (elements.isEmpty()) return false
|
|
||||||
|
|
||||||
val inBlockElements = mutableSetOf<KtElement>()
|
return elements.mapNotNull { element ->
|
||||||
for (element in elements) {
|
val modificationScope = getInsideCodeBlockModificationScope(element.psi) ?: return emptyList()
|
||||||
// skip fake PSI elements like `IntellijIdeaRulezzz$`
|
modificationScope.blockDeclaration
|
||||||
val psi = element.psi
|
|
||||||
if (!psi.isPhysical) continue
|
|
||||||
|
|
||||||
val modificationScope = getInsideCodeBlockModificationScope(psi) ?: return false
|
|
||||||
|
|
||||||
inBlockElements.add(modificationScope.blockDeclaration)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inBlockElements.forEach { it.containingKtFile.addInBlockModifiedItem(it) }
|
|
||||||
return inBlockElements.isNotEmpty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCommentChange(changeSet: TreeChangeEvent): Boolean =
|
private fun isCommentChange(changeSet: TreeChangeEvent): Boolean =
|
||||||
@@ -359,6 +342,12 @@ private val FILE_OUT_OF_BLOCK_MODIFICATION_COUNT = Key<Long>("FILE_OUT_OF_BLOCK_
|
|||||||
|
|
||||||
val KtFile.outOfBlockModificationCount: Long by NotNullableUserDataProperty(FILE_OUT_OF_BLOCK_MODIFICATION_COUNT, 0)
|
val KtFile.outOfBlockModificationCount: Long by NotNullableUserDataProperty(FILE_OUT_OF_BLOCK_MODIFICATION_COUNT, 0)
|
||||||
|
|
||||||
|
private fun KtFile.incOutOfBlockModificationCount() {
|
||||||
|
clearInBlockModifications()
|
||||||
|
|
||||||
|
val count = getUserData(FILE_OUT_OF_BLOCK_MODIFICATION_COUNT) ?: 0
|
||||||
|
putUserData(FILE_OUT_OF_BLOCK_MODIFICATION_COUNT, count + 1)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inBlockModifications is a collection of block elements those have in-block modifications
|
* inBlockModifications is a collection of block elements those have in-block modifications
|
||||||
|
|||||||
Reference in New Issue
Block a user