[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()
|
||||
}
|
||||
|
||||
// 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 {
|
||||
val sessionFactory = createPlatformAwareSessionFactory(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.application.ApplicationManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KotlinModuleDependentsProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.analysis.providers.analysisMessageBus
|
||||
import org.jetbrains.kotlin.analysis.providers.topics.KotlinGlobalModuleStateModificationListener
|
||||
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
|
||||
import org.jetbrains.kotlin.analysis.providers.topics.*
|
||||
|
||||
/**
|
||||
* [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
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user