diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt index 0b2f9b51c0b..1ae8fa87cfb 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/FirIdeResolveStateService.kt @@ -7,24 +7,38 @@ package org.jetbrains.kotlin.idea.fir.low.level.api import com.intellij.openapi.components.service import com.intellij.openapi.project.Project +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.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.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() } + private val librarySessionCache by cachedValue(project, LibraryModificationTracker.getInstance(project)) { + ConcurrentHashMap() + } + private fun createResolveStateFor(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl { + require(moduleInfo is ModuleSourceInfo) val firPhaseRunner = FirPhaseRunner() val sessionProvider = FirIdeSessionProvider(project) - val librariesSession = FirIdeSessionFactory.createLibrarySession(moduleInfo as ModuleSourceInfo, sessionProvider, project) + val librariesSession = librarySessionCache.computeIfAbsent(moduleInfo) { + FirIdeSessionFactory.createLibrarySession(moduleInfo, sessionProvider, project) + } val sourcesSession = FirIdeSessionFactory.createSourcesSession( project, moduleInfo, diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/trackerUtils.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/trackerUtils.kt new file mode 100644 index 00000000000..f8c0c750b00 --- /dev/null +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/util/trackerUtils.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.util + +import com.intellij.openapi.project.Project +import com.intellij.psi.util.CachedValue +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import kotlin.reflect.KProperty + +@Suppress("NOTHING_TO_INLINE") +inline operator fun CachedValue.getValue(thisRef: Any?, property: KProperty<*>): T = value + +inline fun cachedValue(project: Project, vararg dependencies: Any, crossinline createValue: () -> T) = + CachedValuesManager.getManager(project).createCachedValue { + CachedValueProvider.Result( + createValue(), + dependencies + ) + }