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