[LL FIR] KT-58257 Invalidate library sessions depending on anchor modules on global source modification

- Any time an anchor module's session is invalidated, we need to make
  sure that all its dependents are also invalidated. Because those
  dependents may include libraries, invalidation after global source
  modification needs to invalidate such libraries, even if other stable
  module sessions should remain untouched.
This commit is contained in:
Marco Pennekamp
2023-07-12 22:01:23 +02:00
committed by Space Team
parent 24045067bf
commit 42c879a53c
2 changed files with 22 additions and 5 deletions
@@ -10,17 +10,22 @@ import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
/**
* Provide module which contains dependencies of the library.
* [KotlinAnchorModuleProvider] provides modules which contain dependencies of libraries.
*
* Is required for navigation in IJ monorepo from kotlin compiler library sources to IJ platform sources.
* Kotlin compiler depends on platform but this dependency is not represented as jars in monorepo
* but should be replaced with given sources.
* In the IJ monorepo, anchor modules are required for navigation from Kotlin compiler library sources to IJ platform sources. The Kotlin
* compiler depends on the IJ platform, but this dependency is not represented as JARs in the monorepo, but rather by certain monorepo
* source modules, which are made visible to the Kotlin compiler library sources as dependencies via an anchor module.
*/
public interface KotlinAnchorModuleProvider {
public fun getAnchorModule(libraryModule: KtLibraryModule): KtSourceModule?
/**
* Returns all anchor modules configured in the project.
*/
public fun getAllAnchorModules(): Collection<KtSourceModule>
public companion object {
public fun getInstance(project: Project): KotlinAnchorModuleProvider? =
project.getService(KotlinAnchorModuleProvider::class.java)
}
}
}
@@ -9,6 +9,7 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.providers.KotlinAnchorModuleProvider
import org.jetbrains.kotlin.analysis.providers.analysisMessageBus
import org.jetbrains.kotlin.analysis.providers.topics.*
@@ -87,6 +88,17 @@ class LLFirSessionInvalidationService(private val project: Project) : Disposable
private fun invalidateAll(includeStableModules: Boolean) {
ApplicationManager.getApplication().assertWriteAccessAllowed()
// When anchor modules are configured and `includeStableModules` is `false`, we get a situation where the anchor module session will
// be invalidated (because it is a source session), while its library dependents won't be invalidated (because they are sessions of
// stable modules). But such library sessions also need to be invalidated because they depend on the anchor module.
//
// Invalidating anchor modules before all source sessions has the advantage that `invalidate`'s session existence check will work,
// so we do not have to invalidate dependent sessions if the anchor module does not exist in the first place.
if (!includeStableModules) {
val anchorModules = KotlinAnchorModuleProvider.getInstance(project)?.getAllAnchorModules()
anchorModules?.forEach(::invalidate)
}
LLFirSessionCache.getInstance(project).removeAllSessions(includeStableModules)
}