FIR IDE: do not read declaration phase without read lock hold

This commit is contained in:
Ilya Kirillov
2021-04-14 12:51:49 +02:00
committed by TeamCityServer
parent 0cf00d0f72
commit 0a80fbb078
6 changed files with 39 additions and 8 deletions
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.fir.resolve.calls.jvm.JvmCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirQualifierResolverImpl
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirTypeResolverImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManager
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseManager
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.GeneratedClassIndex
import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
@@ -58,6 +60,10 @@ fun FirSession.registerSealedClassInheritorsProvider() {
register(SealedClassInheritorsProvider::class, SealedClassInheritorsProviderImpl)
}
@OptIn(SessionConfiguration::class)
fun FirSession.registerFirCliPhaseManager() {
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
}
// -------------------------- Resolve components --------------------------
@@ -74,6 +74,7 @@ object FirSessionFactory {
): FirJavaModuleBasedSession {
return FirJavaModuleBasedSession(moduleInfo, sessionProvider).apply {
registerThreadUnsafeCaches()
registerFirCliPhaseManager()
registerCommonComponents(languageVersionSettings)
registerResolveComponents(lookupTracker)
registerJavaSpecificResolveComponents()
@@ -127,6 +128,7 @@ object FirSessionFactory {
): FirLibrarySession {
return FirLibrarySession(moduleInfo, sessionProvider).apply {
registerThreadUnsafeCaches()
registerFirCliPhaseManager()
registerCommonComponents(languageVersionSettings)
registerSealedClassInheritorsProvider()
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2021 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.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
object FirPhaseCheckingPhaseManager : FirPhaseManager() {
override fun ensureResolved(symbol: AbstractFirBasedSymbol<*>, requiredPhase: FirResolvePhase) {
val fir = symbol.fir as FirDeclaration
val availablePhase = fir.resolvePhase
require(availablePhase >= requiredPhase) {
"Expected at least $requiredPhase for $symbol but was $availablePhase\n{${fir.render(renderMode)}"
}
}
private val renderMode = FirRenderer.RenderMode.WithResolvePhases.copy(renderDeclarationOrigin = true)
}
@@ -17,4 +17,4 @@ abstract class FirPhaseManager : FirSessionComponent {
)
}
internal val FirSession.phaseManager: FirPhaseManager? by FirSession.nullableSessionComponentAccessor()
internal val FirSession.phaseManager: FirPhaseManager by FirSession.sessionComponentAccessor()
@@ -23,13 +23,9 @@ fun AbstractFirBasedSymbol<*>.ensureResolved(
// TODO: Decide which one session should be used and probably get rid of the parameter if use-site session is not needed
@Suppress("UNUSED_PARAMETER") useSiteSession: FirSession,
) {
val fir = fir as FirDeclaration
val availablePhase = fir.resolvePhase
if (availablePhase >= requiredPhase) return
val resolver = fir.session.phaseManager
?: error("phaseManager should be defined when working with FIR in phased mode")
resolver.ensureResolved(this, requiredPhase)
val session = (fir as FirDeclaration).session
val phaseManager = session.phaseManager
phaseManager.ensureResolved(this, requiredPhase)
}
fun FirSymbolOwner<*>.ensureResolved(
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManager
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseManager
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.session.*
@@ -170,6 +171,7 @@ internal object FirIdeSessionFactory {
val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope)
FirIdeLibrariesSession(moduleInfo, project, searchScope, builtinTypes).apply {
registerIdeComponents()
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
registerCommonComponents(languageVersionSettings)
registerJavaSpecificResolveComponents()
@@ -213,6 +215,7 @@ internal object FirIdeSessionFactory {
): FirIdeBuiltinsAndCloneableSession {
return FirIdeBuiltinsAndCloneableSession(project, builtinTypes).apply {
registerIdeComponents()
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
registerCommonComponents(languageVersionSettings)
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)