Add more diagnostics to address invalid module

Relates to ^KT-42274
This commit is contained in:
Vladimir Dolzhenko
2020-10-12 13:03:22 +00:00
parent fa7104213c
commit 0e7e24c498
4 changed files with 39 additions and 18 deletions
@@ -165,6 +165,9 @@ internal class PerFileAnalysisCache(val file: KtFile, componentProvider: Compone
throw e
}
}
if (fileResult == null) {
file.clearInBlockModifications()
}
return fileResult
}
@@ -228,6 +231,7 @@ internal class PerFileAnalysisCache(val file: KtFile, componentProvider: Compone
return AnalysisResult.EMPTY
}
moduleDescriptor.assertValid()
try {
return KotlinResolveDataProvider.analyze(
project,
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
@@ -102,13 +103,8 @@ internal class ProjectResolutionFacade(
private val resolverForProjectDependencies = dependencies + listOf(globalContext.exceptionTracker)
private fun computeModuleResolverProvider(): ResolverForProject<IdeaModuleInfo> {
val delegateResolverForProject: ResolverForProject<IdeaModuleInfo>
if (reuseDataFrom != null) {
delegateResolverForProject = reuseDataFrom.cachedResolverForProject
} else {
delegateResolverForProject = EmptyResolverForProject()
}
val delegateResolverForProject: ResolverForProject<IdeaModuleInfo> =
reuseDataFrom?.cachedResolverForProject ?: EmptyResolverForProject()
val allModuleInfos = (allModules ?: getModuleInfosFromIdeaModel(project, (settings as? PlatformAnalysisSettingsImpl)?.platform))
.toMutableSet()
@@ -154,13 +150,29 @@ internal class ProjectResolutionFacade(
internal fun getAnalysisResultsForElements(elements: Collection<KtElement>): AnalysisResult {
assert(elements.isNotEmpty()) { "elements collection should not be empty" }
val slruCache = analysisResultsSimpleLock.guarded {
val cache = analysisResultsSimpleLock.guarded {
analysisResults.value!!
}
val results = elements.map {
val perFileCache = slruCache[it.containingKtFile]
perFileCache.getAnalysisResults(it)
}
val results =
elements.map {
val containingKtFile = it.containingKtFile
val perFileCache = cache[containingKtFile]
try {
perFileCache.getAnalysisResults(it)
} catch (e: Throwable) {
if (e is ControlFlowException) {
throw e
}
val actualCache = analysisResultsSimpleLock.guarded {
analysisResults.upToDateOrNull?.get()
}
if (cache !== actualCache) {
throw IllegalStateException("Cache has been invalidated during performing analysis for $containingKtFile", e)
}
throw e
}
}
val withError = results.firstOrNull { it.isError() }
val bindingContext = CompositeBindingContext.create(results.map { it.bindingContext })
if (withError != null) {
@@ -8,10 +8,8 @@ package org.jetbrains.kotlin.idea.caches.trackers
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.SimpleModificationTracker
import com.intellij.pom.tree.TreeAspect
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.util.application.getServiceSafe
import org.jetbrains.kotlin.psi.KtFile
/**
* Tested in OutOfBlockModificationTestGenerated
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.caches.trackers
import com.intellij.lang.ASTNode
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.ModificationTracker
@@ -27,6 +28,8 @@ import com.intellij.psi.impl.PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGE
import com.intellij.psi.impl.PsiTreeChangePreprocessor
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.analyzer.ModuleDescriptorListener
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
@@ -39,7 +42,7 @@ val KOTLIN_CONSOLE_KEY = Key.create<Boolean>("kotlin.console")
* Tested in OutOfBlockModificationTestGenerated
*/
// FIX ME WHEN BUNCH 193 REMOVED
abstract class KotlinCodeBlockModificationListenerCompat(protected val project: Project) : PsiTreeChangePreprocessor {
abstract class KotlinCodeBlockModificationListenerCompat(protected val project: Project) : PsiTreeChangePreprocessor, Disposable {
protected val modificationTrackerImpl: PsiModificationTrackerImpl =
PsiModificationTracker.SERVICE.getInstance(project) as PsiModificationTrackerImpl
@@ -62,7 +65,7 @@ abstract class KotlinCodeBlockModificationListenerCompat(protected val project:
kotlinOutOfCodeBlockTrackerImpl = kotlinOutOfCodeBlockTrackerProducer()
kotlinOutOfCodeBlockTracker = kotlinOutOfCodeBlockTrackerImpl
val model = PomManager.getModel(project)
val messageBusConnection = project.messageBus.connect(project)
val messageBusConnection = project.messageBus.connect(this)
model.addModelListener(object : PomModelListener {
override fun isAspectChangeInteresting(aspect: PomModelAspect): Boolean {
return aspect == treeAspect
@@ -125,6 +128,10 @@ abstract class KotlinCodeBlockModificationListenerCompat(protected val project:
}
}
override fun dispose() {
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
}
companion object {
private fun isReplLine(file: VirtualFile): Boolean {
return file.getUserData(KOTLIN_CONSOLE_KEY) == true
@@ -176,7 +183,7 @@ abstract class KotlinCodeBlockModificationListenerCompat(protected val project:
// dirty scope for whitespaces and comments is the element itself
if (element is PsiWhiteSpace || element is PsiComment || element is KDoc) return element
return getInsideCodeBlockModificationScope(element)?.blockDeclaration ?: null
return getInsideCodeBlockModificationScope(element)?.blockDeclaration
}
fun getInsideCodeBlockModificationScope(element: PsiElement): BlockModificationScopeElement? {
@@ -267,7 +274,7 @@ abstract class KotlinCodeBlockModificationListenerCompat(protected val project:
is KtSecondaryConstructor -> {
blockDeclaration
?.takeIf {
.takeIf {
it.bodyExpression?.isAncestor(element) ?: false || it.getDelegationCallOrNull()?.isAncestor(element) ?: false
}?.let { ktConstructor ->
PsiTreeUtil.getParentOfType(blockDeclaration, KtClassOrObject::class.java)?.let {