FIR IDE: reuse up-to-date fir sessions
This commit is contained in:
+2
-2
@@ -16,8 +16,8 @@ import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
|||||||
*/
|
*/
|
||||||
@OptIn(PrivateSessionConstructor::class)
|
@OptIn(PrivateSessionConstructor::class)
|
||||||
internal class FirIdeLibrariesSession @PrivateSessionConstructor constructor(
|
internal class FirIdeLibrariesSession @PrivateSessionConstructor constructor(
|
||||||
moduleInfo: ModuleInfo,
|
override val moduleInfo: ModuleInfo,
|
||||||
override val project: Project,
|
override val project: Project,
|
||||||
override val scope: GlobalSearchScope,
|
override val scope: GlobalSearchScope,
|
||||||
builtinTypes: BuiltinTypes,
|
builtinTypes: BuiltinTypes,
|
||||||
) : FirIdeModuleSession(moduleInfo, builtinTypes)
|
) : FirIdeModuleSession(builtinTypes)
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@ abstract class FirIdeSession(override val builtinTypes: BuiltinTypes) : FirSessi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PrivateSessionConstructor::class)
|
@OptIn(PrivateSessionConstructor::class)
|
||||||
abstract class FirIdeModuleSession(override val moduleInfo: ModuleInfo, builtinTypes: BuiltinTypes) : FirIdeSession(builtinTypes) {
|
abstract class FirIdeModuleSession(builtinTypes: BuiltinTypes) : FirIdeSession(builtinTypes) {
|
||||||
|
abstract override val moduleInfo: ModuleInfo
|
||||||
abstract val scope: GlobalSearchScope
|
abstract val scope: GlobalSearchScope
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -57,10 +57,11 @@ internal object FirIdeSessionFactory {
|
|||||||
val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||||
val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner)
|
val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner)
|
||||||
val searchScope = ModuleProductionSourceScope(moduleInfo.module)
|
val searchScope = ModuleProductionSourceScope(moduleInfo.module)
|
||||||
val session = FirIdeSourcesSession(moduleInfo, project, searchScope, firBuilder, builtinTypes)
|
|
||||||
sessionsCache[moduleInfo] = session
|
|
||||||
val dependentModules = moduleInfo.dependenciesWithoutSelf()
|
val dependentModules = moduleInfo.dependenciesWithoutSelf()
|
||||||
.filterIsInstanceTo<ModuleSourceInfo, MutableList<ModuleSourceInfo>>(mutableListOf())
|
.filterIsInstanceTo<ModuleSourceInfo, MutableList<ModuleSourceInfo>>(mutableListOf())
|
||||||
|
val session = FirIdeSourcesSession(moduleInfo, dependentModules, project, searchScope, firBuilder, builtinTypes)
|
||||||
|
sessionsCache[moduleInfo] = session
|
||||||
|
|
||||||
|
|
||||||
return session.apply {
|
return session.apply {
|
||||||
val cache = ModuleFileCacheImpl(this)
|
val cache = ModuleFileCacheImpl(this)
|
||||||
|
|||||||
+49
-11
@@ -8,29 +8,67 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.trackers.KotlinModuleOutOfCodeBlockModificationTracker
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner
|
import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.FirTransformerProvider
|
import org.jetbrains.kotlin.idea.fir.low.level.api.FirTransformerProvider
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
internal class FirIdeSessionProviderStorage(private val project: Project) {
|
internal class FirIdeSessionProviderStorage(private val project: Project) {
|
||||||
|
private val sessionsCache = ConcurrentHashMap<ModuleSourceInfo, FromModuleViewSessionCache>()
|
||||||
|
|
||||||
fun getSessionProvider(rootModule: ModuleSourceInfo): FirIdeSessionProvider {
|
fun getSessionProvider(rootModule: ModuleSourceInfo): FirIdeSessionProvider {
|
||||||
val transformerProvider = FirTransformerProvider()
|
val transformerProvider = FirTransformerProvider()
|
||||||
val firPhaseRunner = FirPhaseRunner(transformerProvider)
|
val firPhaseRunner = FirPhaseRunner(transformerProvider)
|
||||||
|
|
||||||
val builtinTypes = BuiltinTypes()
|
val builtinTypes = BuiltinTypes()
|
||||||
val builtinsAndCloneableSession = FirIdeSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes)
|
val builtinsAndCloneableSession = FirIdeSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes)
|
||||||
val sessions = mutableMapOf<ModuleSourceInfo, FirIdeSourcesSession>()
|
val cache = sessionsCache.getOrPut(rootModule) { FromModuleViewSessionCache(rootModule) }
|
||||||
val session = executeWithoutPCE {
|
val (sessions, session) = cache.withMappings { mappings ->
|
||||||
FirIdeSessionFactory.createSourcesSession(
|
val sessions = mutableMapOf<ModuleSourceInfo, FirIdeSourcesSession>().apply { putAll(mappings) }
|
||||||
project,
|
val session = executeWithoutPCE {
|
||||||
rootModule,
|
FirIdeSessionFactory.createSourcesSession(
|
||||||
builtinsAndCloneableSession,
|
project,
|
||||||
firPhaseRunner,
|
rootModule,
|
||||||
builtinTypes,
|
builtinsAndCloneableSession,
|
||||||
sessions,
|
firPhaseRunner,
|
||||||
isRootModule = true
|
builtinTypes,
|
||||||
)
|
sessions,
|
||||||
|
isRootModule = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sessions to session
|
||||||
}
|
}
|
||||||
|
|
||||||
return FirIdeSessionProvider(project, session, sessions)
|
return FirIdeSessionProvider(project, session, sessions)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FromModuleViewSessionCache(
|
||||||
|
val root: ModuleSourceInfo
|
||||||
|
) {
|
||||||
|
@Volatile
|
||||||
|
private var mappings: Map<ModuleSourceInfo, FirSessionWithModificationTracker> = emptyMap()
|
||||||
|
|
||||||
|
inline fun <R> withMappings(
|
||||||
|
action: (Map<ModuleSourceInfo, FirIdeSourcesSession>) -> Pair<Map<ModuleSourceInfo, FirIdeSourcesSession>, R>
|
||||||
|
): Pair<Map<ModuleSourceInfo, FirIdeSourcesSession>, R> {
|
||||||
|
val (newMappings, result) = action(getSessions().mapValues { it.value })
|
||||||
|
mappings = newMappings.mapValues { FirSessionWithModificationTracker(it.value) }
|
||||||
|
return newMappings to result
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
private fun getSessions(): Map<ModuleSourceInfo, FirIdeSourcesSession> = buildMap {
|
||||||
|
mappings.forEach { (module, session) -> if (session.isValid) put(module, session.firSession) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FirSessionWithModificationTracker(
|
||||||
|
val firSession: FirIdeSourcesSession,
|
||||||
|
) {
|
||||||
|
private val modificationTracker = KotlinModuleOutOfCodeBlockModificationTracker(firSession.moduleInfo.module)
|
||||||
|
private val timeStamp = modificationTracker.modificationCount
|
||||||
|
|
||||||
|
val isValid: Boolean get() = modificationTracker.modificationCount == timeStamp
|
||||||
}
|
}
|
||||||
+5
-2
@@ -10,17 +10,20 @@ import com.intellij.psi.search.GlobalSearchScope
|
|||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||||
|
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.file.builder.FirFileBuilder
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
|
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
|
||||||
|
|
||||||
@OptIn(PrivateSessionConstructor::class)
|
@OptIn(PrivateSessionConstructor::class)
|
||||||
internal class FirIdeSourcesSession @PrivateSessionConstructor constructor(
|
internal class FirIdeSourcesSession @PrivateSessionConstructor constructor(
|
||||||
moduleInfo: ModuleInfo,
|
override val moduleInfo: ModuleSourceInfo,
|
||||||
|
val dependencies: List<ModuleSourceInfo>,
|
||||||
override val project: Project,
|
override val project: Project,
|
||||||
override val scope: GlobalSearchScope,
|
override val scope: GlobalSearchScope,
|
||||||
val firFileBuilder: FirFileBuilder,
|
val firFileBuilder: FirFileBuilder,
|
||||||
builtinTypes: BuiltinTypes,
|
builtinTypes: BuiltinTypes,
|
||||||
) : FirIdeModuleSession(moduleInfo, builtinTypes) {
|
) : FirIdeModuleSession( builtinTypes) {
|
||||||
val cache get() = firIdeProvider.cache
|
val cache get() = firIdeProvider.cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user