[FIR] Store enhanced functions and properties in session component

Previously enhanced symbols were cached inside SignatureEnhancement,
  which is created independently for each enhancement scope. This may
  cause creation of multiple enhanced symbols for same java declaration
  in presence of multiple scope sessions (mutithread compiler, IDE,
  separate scope session for checkers)

^KT-50858 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-01-19 12:11:55 +03:00
parent 4f967ce102
commit 345fdc214b
4 changed files with 43 additions and 19 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.extensions.FirRegisteredPluginAnnotations
import org.jetbrains.kotlin.fir.java.FirJavaVisibilityChecker import org.jetbrains.kotlin.fir.java.FirJavaVisibilityChecker
import org.jetbrains.kotlin.fir.java.FirJvmDefaultModeComponent import org.jetbrains.kotlin.fir.java.FirJvmDefaultModeComponent
import org.jetbrains.kotlin.fir.java.enhancement.FirAnnotationTypeQualifierResolver import org.jetbrains.kotlin.fir.java.enhancement.FirAnnotationTypeQualifierResolver
import org.jetbrains.kotlin.fir.java.enhancement.FirEnhancedSymbolsStorage
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticNamesProvider
@@ -77,6 +78,7 @@ fun FirSession.registerCliCompilerOnlyComponents() {
fun FirSession.registerCommonJavaComponents(javaModuleResolver: JavaModuleResolver) { fun FirSession.registerCommonJavaComponents(javaModuleResolver: JavaModuleResolver) {
val jsr305State = languageVersionSettings.getFlag(JvmAnalysisFlags.javaTypeEnhancementState) val jsr305State = languageVersionSettings.getFlag(JvmAnalysisFlags.javaTypeEnhancementState)
register(FirAnnotationTypeQualifierResolver::class, FirAnnotationTypeQualifierResolver(this, jsr305State, javaModuleResolver)) register(FirAnnotationTypeQualifierResolver::class, FirAnnotationTypeQualifierResolver(this, jsr305State, javaModuleResolver))
register(FirEnhancedSymbolsStorage::class, FirEnhancedSymbolsStorage(this))
register( register(
FirJvmDefaultModeComponent::class, FirJvmDefaultModeComponent::class,
FirJvmDefaultModeComponent(languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)) FirJvmDefaultModeComponent(languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode))
@@ -8,6 +8,10 @@ package org.jetbrains.kotlin.fir.java.enhancement
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.caches.FirCache
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.caches.createCache
import org.jetbrains.kotlin.fir.caches.firCachesFactory
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirPrimaryConstructorBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirPrimaryConstructorBuilder
@@ -68,30 +72,21 @@ class FirSignatureEnhancement(
private val contextQualifiers: JavaTypeQualifiersByElementType? = private val contextQualifiers: JavaTypeQualifiersByElementType? =
typeQualifierResolver.extractDefaultQualifiers(owner) typeQualifierResolver.extractDefaultQualifiers(owner)
private val enhancements = mutableMapOf<FirCallableSymbol<*>, FirCallableSymbol<*>>() private val enhancementsCache = session.enhancedSymbolStorage.cacheByOwner.getValue(owner.symbol, null)
fun enhancedFunction( fun enhancedFunction(function: FirFunctionSymbol<*>, name: Name?): FirFunctionSymbol<*> {
function: FirFunctionSymbol<*>, return enhancementsCache.enhancedFunctions.getValue(function, this to name)
name: Name?
): FirFunctionSymbol<*> {
return enhancements.getOrPut(function) {
enhance(function, name).also { enhancedVersion ->
val enhancedVersionFir = enhancedVersion.fir
(enhancedVersionFir.initialSignatureAttr as? FirSimpleFunction)?.let {
enhancedVersionFir.initialSignatureAttr = enhancedFunction(it.symbol, it.name).fir
}
}
} as FirFunctionSymbol<*>
} }
fun enhancedProperty(property: FirVariableSymbol<*>, name: Name): FirVariableSymbol<*> { fun enhancedProperty(property: FirVariableSymbol<*>, name: Name): FirVariableSymbol<*> {
return enhancements.getOrPut(property) { enhance(property, name) } as FirVariableSymbol<*> return enhancementsCache.enhancedVariables.getValue(property, this to name)
} }
private fun FirDeclaration.computeDefaultQualifiers() = private fun FirDeclaration.computeDefaultQualifiers() =
typeQualifierResolver.extractAndMergeDefaultQualifiers(contextQualifiers, annotations) typeQualifierResolver.extractAndMergeDefaultQualifiers(contextQualifiers, annotations)
private fun enhance( @PrivateForInline
internal fun enhance(
original: FirVariableSymbol<*>, original: FirVariableSymbol<*>,
name: Name name: Name
): FirVariableSymbol<*> { ): FirVariableSymbol<*> {
@@ -182,7 +177,8 @@ class FirSignatureEnhancement(
} }
} }
private fun enhance( @PrivateForInline
internal fun enhance(
original: FirFunctionSymbol<*>, original: FirFunctionSymbol<*>,
name: Name? name: Name?
): FirFunctionSymbol<*> { ): FirFunctionSymbol<*> {
@@ -192,7 +188,12 @@ class FirSignatureEnhancement(
return original return original
} }
enhanceTypeParameterBounds(firMethod.typeParameters) enhanceTypeParameterBounds(firMethod.typeParameters)
return enhanceMethod(firMethod, original.callableId, name) return enhanceMethod(firMethod, original.callableId, name).also { enhancedVersion ->
val enhancedVersionFir = enhancedVersion.fir
(enhancedVersionFir.initialSignatureAttr as? FirSimpleFunction)?.let {
enhancedVersionFir.initialSignatureAttr = enhancedFunction(it.symbol, it.name).fir
}
}
} }
private fun enhanceMethod( private fun enhanceMethod(
@@ -551,3 +552,26 @@ private class EnhancementSignatureParts(
override val TypeParameterMarker.isFromJava: Boolean override val TypeParameterMarker.isFromJava: Boolean
get() = (this as ConeTypeParameterLookupTag).symbol.fir.origin == FirDeclarationOrigin.Java get() = (this as ConeTypeParameterLookupTag).symbol.fir.origin == FirDeclarationOrigin.Java
} }
class FirEnhancedSymbolsStorage(val session: FirSession) : FirSessionComponent {
private val cachesFactory = session.firCachesFactory
val cacheByOwner: FirCache<FirRegularClassSymbol, EnhancementSymbolsCache, Nothing?> =
cachesFactory.createCache { _ -> EnhancementSymbolsCache(cachesFactory) }
class EnhancementSymbolsCache(cachesFactory: FirCachesFactory) {
@OptIn(PrivateForInline::class)
val enhancedFunctions: FirCache<FirFunctionSymbol<*>, FirFunctionSymbol<*>, Pair<FirSignatureEnhancement, Name?>> =
cachesFactory.createCache { original, (enhancement, name) ->
enhancement.enhance(original, name)
}
@OptIn(PrivateForInline::class)
val enhancedVariables: FirCache<FirVariableSymbol<*>, FirVariableSymbol<*>, Pair<FirSignatureEnhancement, Name>> =
cachesFactory.createCache { original, (enhancement, name) ->
enhancement.enhance(original, name)
}
}
}
private val FirSession.enhancedSymbolStorage: FirEnhancedSymbolsStorage by FirSession.sessionComponentAccessor()
@@ -1,5 +1,4 @@
// !LANGUAGE: -ProhibitConcurrentHashMapContains // !LANGUAGE: -ProhibitConcurrentHashMapContains
// FIR_IDE_IGNORE
// FULL_JDK // FULL_JDK
class A : java.util.concurrent.ConcurrentHashMap<String, Int>() { class A : java.util.concurrent.ConcurrentHashMap<String, Int>() {
@@ -1,5 +1,4 @@
// !LANGUAGE: -ProhibitConcurrentHashMapContains // !LANGUAGE: -ProhibitConcurrentHashMapContains
// FIR_IDE_IGNORE
// FULL_JDK // FULL_JDK
class A : java.util.concurrent.ConcurrentHashMap<String, Int>() { class A : java.util.concurrent.ConcurrentHashMap<String, Int>() {