FIR IDE: reanalyse dependent modules only then they change

This commit is contained in:
Ilya Kirillov
2020-09-05 16:28:48 +03:00
parent 07be30c5db
commit fc64d8d5e8
3 changed files with 35 additions and 12 deletions
@@ -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) }
@@ -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,
@@ -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,