FIR IDE: reanalyse dependent modules only then they change
This commit is contained in:
+29
-9
@@ -7,26 +7,30 @@ package org.jetbrains.kotlin.idea.fir.low.level.api
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.psi.util.CachedValue
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeDependentModulesSourcesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeLibrariesSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionFactory
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProvider
|
||||
import org.jetbrains.kotlin.idea.util.cachedValue
|
||||
import org.jetbrains.kotlin.idea.util.getValue
|
||||
import org.jetbrains.kotlin.idea.util.psiModificationTrackerBasedCachedValue
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import org.jetbrains.kotlin.idea.util.getValue
|
||||
|
||||
internal class FirIdeResolveStateService(private val project: Project) {
|
||||
private val stateCache by psiModificationTrackerBasedCachedValue(project) {
|
||||
ConcurrentHashMap<IdeaModuleInfo, FirModuleResolveStateImpl>()
|
||||
}
|
||||
|
||||
private val moduleLibraryDependencyStateCache = ConcurrentHashMap<IdeaModuleInfo, CachedValue<FirIdeDependentModulesSourcesSession>>()
|
||||
|
||||
private val librarySessionCache by cachedValue(project, LibraryModificationTracker.getInstance(project)) {
|
||||
ConcurrentHashMap<IdeaModuleInfo, FirIdeLibrariesSession>()
|
||||
}
|
||||
@@ -41,13 +45,28 @@ internal class FirIdeResolveStateService(private val project: Project) {
|
||||
FirIdeSessionFactory.createLibrarySession(moduleInfo, sessionProvider, project)
|
||||
}
|
||||
|
||||
val dependentModulesSession = FirIdeSessionFactory.createDependentModulesSourcesSession(
|
||||
project,
|
||||
moduleInfo,
|
||||
firPhaseRunner,
|
||||
sessionProvider,
|
||||
librariesSession,
|
||||
)
|
||||
val dependentModulesSession = moduleLibraryDependencyStateCache.compute(moduleInfo) { _, cachedIdeaModuleInfo ->
|
||||
if (cachedIdeaModuleInfo?.hasUpToDateValue() == true) cachedIdeaModuleInfo
|
||||
else {
|
||||
CachedValuesManager.getManager(project).createCachedValue {
|
||||
val dependentSession = FirIdeSessionFactory.createDependentModulesSourcesSession(
|
||||
project,
|
||||
moduleInfo,
|
||||
firPhaseRunner,
|
||||
sessionProvider,
|
||||
librariesSession,
|
||||
)
|
||||
CachedValueProvider.Result.create(
|
||||
dependentSession,
|
||||
dependentSession.dependentModules.map { it.createModificationTracker() }
|
||||
.takeUnless { it.isEmpty() }
|
||||
?: listOf(ModificationTracker.NEVER_CHANGED)
|
||||
)
|
||||
}
|
||||
}
|
||||
}?.value ?: error("ModuleLibraryDependencyStateCache should be computed")
|
||||
|
||||
|
||||
val currentModuleSession = FirIdeSessionFactory.createCurrentModuleSourcesSession(
|
||||
project,
|
||||
moduleInfo,
|
||||
@@ -69,6 +88,7 @@ internal class FirIdeResolveStateService(private val project: Project) {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl =
|
||||
stateCache.getOrPut(moduleInfo) { createResolveStateFor(moduleInfo) }
|
||||
|
||||
|
||||
+4
-3
@@ -81,9 +81,10 @@ internal object FirIdeSessionFactory {
|
||||
val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner)
|
||||
val dependentModules = moduleInfo.collectTransitiveDependenciesWithSelf()
|
||||
.filterIsInstance<ModuleSourceInfo>()
|
||||
.filterNot { it === moduleInfo }
|
||||
val searchScope = ModuleWithDependentsScope(project, dependentModules.mapTo(mutableListOf()) { it.module })
|
||||
return FirIdeDependentModulesSourcesSession(moduleInfo, sessionProvider, searchScope, firBuilder).apply {
|
||||
.filterNot { it == moduleInfo }
|
||||
val searchScope = if (dependentModules.isNotEmpty()) GlobalSearchScope.union(dependentModules.map { it.contentScope() })
|
||||
else GlobalSearchScope.EMPTY_SCOPE
|
||||
return FirIdeDependentModulesSourcesSession(moduleInfo, dependentModules, sessionProvider, searchScope, firBuilder).apply {
|
||||
val cache = ModuleFileCacheImpl(this)
|
||||
registerCommonSourceSessionComponents(
|
||||
project,
|
||||
|
||||
+2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
|
||||
|
||||
@@ -37,6 +38,7 @@ internal class FirIdeCurrentModuleSourcesSession @PrivateSessionConstructor cons
|
||||
@OptIn(PrivateSessionConstructor::class)
|
||||
internal class FirIdeDependentModulesSourcesSession @PrivateSessionConstructor constructor(
|
||||
moduleInfo: ModuleInfo,
|
||||
val dependentModules: List<ModuleSourceInfo>,
|
||||
sessionProvider: FirIdeSessionProvider,
|
||||
scope: GlobalSearchScope,
|
||||
firFileBuilder: FirFileBuilder,
|
||||
|
||||
Reference in New Issue
Block a user