[LL FIR] KT-58257 Invalidate script sessions globally (as a workaround)
- Until the IDE module dependents provider has been implemented for script dependents (see KTIJ-25620), we must assume that any script modification may lead to any other script session being out of date. Hence, script modification now leads to the removal of all script sessions. - Because the IDE module dependents provider doesn't provide script dependents for libraries yet, library modification must also lead to global script session invalidation.
This commit is contained in:
committed by
Space Team
parent
efabd55646
commit
bb92d19b47
+20
@@ -109,6 +109,26 @@ class LLFirSessionCache(private val project: Project) {
|
|||||||
storage.clear()
|
storage.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removing script sessions is only needed temporarily until KTIJ-25620 has been implemented.
|
||||||
|
fun removeAllScriptSessions() {
|
||||||
|
ApplicationManager.getApplication().assertWriteAccessAllowed()
|
||||||
|
|
||||||
|
removeAllScriptSessionsFrom(sourceCache)
|
||||||
|
removeAllScriptSessionsFrom(binaryCache)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeAllScriptSessionsFrom(storage: SessionStorage) {
|
||||||
|
// `ConcurrentSoftValueHashMap` (the implementation used by `storage`) does not back its entry set but rather creates a copy, which
|
||||||
|
// is in violation of the contract of `Map.entrySet`, and thus changes to the entry set are not reflected in `storage`. Because this
|
||||||
|
// function is executed in a write action, we do not need the weak consistency guarantees made by `ConcurrentMap`'s iterator, so a
|
||||||
|
// "collect and remove" approach also works.
|
||||||
|
val scriptEntries = storage.entries.filter { (module, _) -> module is KtScriptModule || module is KtScriptDependencyModule }
|
||||||
|
for ((module, session) in scriptEntries) {
|
||||||
|
session.isValid = false
|
||||||
|
storage.remove(module)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createSession(module: KtModule): LLFirSession {
|
private fun createSession(module: KtModule): LLFirSession {
|
||||||
val sessionFactory = createPlatformAwareSessionFactory(module)
|
val sessionFactory = createPlatformAwareSessionFactory(module)
|
||||||
return when (module) {
|
return when (module) {
|
||||||
|
|||||||
+10
-9
@@ -8,16 +8,9 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
|||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KotlinModuleDependentsProvider
|
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.analysisMessageBus
|
import org.jetbrains.kotlin.analysis.providers.analysisMessageBus
|
||||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinGlobalModuleStateModificationListener
|
import org.jetbrains.kotlin.analysis.providers.topics.*
|
||||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinGlobalOutOfBlockModificationListener
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinGlobalSourceModuleStateModificationListener
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinGlobalSourceOutOfBlockModificationListener
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinTopics
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinModuleOutOfBlockModificationListener
|
|
||||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinModuleStateModificationListener
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [LLFirSessionInvalidationService] listens to [modification events][KotlinTopics] and invalidates [LLFirSession]s which depend on the
|
* [LLFirSessionInvalidationService] listens to [modification events][KotlinTopics] and invalidates [LLFirSession]s which depend on the
|
||||||
@@ -81,6 +74,14 @@ class LLFirSessionInvalidationService(private val project: Project) : Disposable
|
|||||||
if (!didSessionExist) return
|
if (!didSessionExist) return
|
||||||
|
|
||||||
KotlinModuleDependentsProvider.getInstance(project).getTransitiveDependents(module).forEach(sessionCache::removeSession)
|
KotlinModuleDependentsProvider.getInstance(project).getTransitiveDependents(module).forEach(sessionCache::removeSession)
|
||||||
|
|
||||||
|
// Due to a missing IDE implementation for script dependents (see KTIJ-25620), script sessions need to be invalidated globally:
|
||||||
|
// - A script may include other scripts, so a script modification may affect any other script.
|
||||||
|
// - Script dependencies are also not linked via dependents yet, so any script dependency modification may affect any script.
|
||||||
|
// - Scripts may depend on libraries, and the IDE module dependents provider doesn't provide script dependents for libraries yet.
|
||||||
|
if (module is KtScriptModule || module is KtScriptDependencyModule || module is KtLibraryModule) {
|
||||||
|
sessionCache.removeAllScriptSessions()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun invalidateAll(includeBinaryModules: Boolean) {
|
private fun invalidateAll(includeBinaryModules: Boolean) {
|
||||||
|
|||||||
Reference in New Issue
Block a user