diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt index 471ebe89001..d46aebc89c1 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.impl.FirTypeResolverImpl import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManager import org.jetbrains.kotlin.fir.symbols.FirPhaseManager import org.jetbrains.kotlin.fir.resolve.transformers.plugin.GeneratedClassIndex +import org.jetbrains.kotlin.fir.scopes.FirFakeOverrideStorage import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache import org.jetbrains.kotlin.incremental.components.LookupTracker @@ -52,6 +53,8 @@ fun FirSession.registerCommonComponents(languageVersionSettings: LanguageVersion register(FirRegisteredPluginAnnotations::class, FirRegisteredPluginAnnotations.create(this)) register(FirPredicateBasedProvider::class, FirPredicateBasedProvider.create(this)) register(GeneratedClassIndex::class, GeneratedClassIndex.create()) + + register(FirFakeOverrideStorage::class, FirFakeOverrideStorage(this)) } @OptIn(SessionConfiguration::class) diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt index 013147d4f9f..7263bfd826b 100644 --- a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt @@ -77,7 +77,7 @@ private fun wrapSubstitutionScopeIfNeed( val platformSubstitution = createSubstitution(platformTypeParameters, declaration.defaultType(), session) val substitutor = substitutorByMap(platformSubstitution, session) FirClassSubstitutionScope( - session, useSiteMemberScope, substitutor, + session, useSiteMemberScope, PLATFORM_TYPE_PARAMETERS_SUBSTITUTION_SCOPE_KEY, substitutor, dispatchReceiverTypeForSubstitutedMembers = derivedClass.defaultType(), skipPrivateMembers = true, ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirFakeOverrideStorage.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirFakeOverrideStorage.kt new file mode 100644 index 00000000000..10b35614b2a --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirFakeOverrideStorage.kt @@ -0,0 +1,42 @@ +/* + * 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.scopes + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent +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.resolve.ScopeSessionKey +import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope +import org.jetbrains.kotlin.fir.symbols.impl.* + +class FirFakeOverrideStorage(val session: FirSession) : FirSessionComponent { + private val cachesFactory = session.firCachesFactory + + val substitutionOverrideCacheByScope: FirCache, SubstitutionOverrideCache, Nothing?> = + cachesFactory.createCache { _ -> SubstitutionOverrideCache(session.firCachesFactory) } + + class SubstitutionOverrideCache(cachesFactory: FirCachesFactory) { + val overridesForFunctions: FirCache = + cachesFactory.createCache { original, scope -> scope.createSubstitutionOverrideFunction(original) } + val overridesForConstructors: FirCache = + cachesFactory.createCache { original, scope -> scope.createSubstitutionOverrideConstructor(original) } + val overridesForVariables: FirCache, FirVariableSymbol<*>, FirClassSubstitutionScope> = + cachesFactory.createCache { original, scope -> + when (original) { + is FirPropertySymbol -> scope.createSubstitutionOverrideProperty(original) + is FirFieldSymbol -> scope.createSubstitutionOverrideField(original) + is FirAccessorSymbol -> scope.createSubstitutionOverrideAccessor(original) + else -> error("symbol $original is not overridable") + } + } + } +} + + +val FirSession.fakeOverrideStorage: FirFakeOverrideStorage by FirSession.sessionComponentAccessor() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt index d731aa15606..593ff7479e2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt @@ -153,11 +153,12 @@ private fun FirClass.scopeForClassImpl( val basicScope = unsubstitutedScope(useSiteSession, scopeSession, withForcedTypeCalculator = false) if (substitutor == ConeSubstitutor.Empty) return basicScope + val key = ConeSubstitutionScopeKey(classFirDispatchReceiver.symbol.toLookupTag(), isFromExpectClass, substitutor) return scopeSession.getOrBuild( - this, ConeSubstitutionScopeKey(classFirDispatchReceiver.symbol.toLookupTag(), isFromExpectClass, substitutor) + this, key ) { FirClassSubstitutionScope( - useSiteSession, basicScope, substitutor, classFirDispatchReceiver.defaultType(), + useSiteSession, basicScope, key, substitutor, classFirDispatchReceiver.defaultType(), skipPrivateMembers, makeExpect = isFromExpectClass ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index 2022d8660d7..dd42b6080fc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -7,20 +7,16 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirTypeParameter -import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef -import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner +import org.jetbrains.kotlin.fir.caches.contains import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull import org.jetbrains.kotlin.fir.originalForSubstitutionOverride +import org.jetbrains.kotlin.fir.resolve.ScopeSessionKey import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.chain -import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution -import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeClassLikeType @@ -33,21 +29,28 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf class FirClassSubstitutionScope( private val session: FirSession, private val useSiteMemberScope: FirTypeScope, + key: ScopeSessionKey<*, *>, private val substitutor: ConeSubstitutor, private val dispatchReceiverTypeForSubstitutedMembers: ConeClassLikeType, private val skipPrivateMembers: Boolean, private val makeExpect: Boolean = false ) : FirTypeScope() { + companion object { + private val FirVariableSymbol<*>.isOverridable: Boolean + get() = when (this) { + is FirPropertySymbol, + is FirFieldSymbol, + is FirAccessorSymbol -> true + else -> false + } + } - private val substitutionOverrideFunctions = mutableMapOf() - private val substitutionOverrideConstructors = mutableMapOf() - private val substitutionOverrideVariables = mutableMapOf, FirVariableSymbol<*>>() - + private val substitutionOverrideCache = session.fakeOverrideStorage.substitutionOverrideCacheByScope.getValue(key, null) private val newOwnerClassId = dispatchReceiverTypeForSubstitutedMembers.lookupTag.classId override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { useSiteMemberScope.processFunctionsByName(name) process@{ original -> - val function = substitutionOverrideFunctions.getOrPut(original) { createSubstitutionOverrideFunction(original) } + val function = substitutionOverrideCache.overridesForFunctions.getValue(original, this) processor(function) } @@ -59,16 +62,18 @@ class FirClassSubstitutionScope( processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction ): ProcessorAction = processDirectOverriddenWithBaseScope( - functionSymbol, processor, FirTypeScope::processDirectOverriddenFunctionsWithBaseScope, substitutionOverrideFunctions - ) + functionSymbol, + processor, + FirTypeScope::processDirectOverriddenFunctionsWithBaseScope, + ) { it in substitutionOverrideCache.overridesForFunctions } private inline fun > processDirectOverriddenWithBaseScope( callableSymbol: D, noinline processor: (D, FirTypeScope) -> ProcessorAction, processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(D, ((D, FirTypeScope) -> ProcessorAction)) -> ProcessorAction, - fakeOverridesMap: Map, FirCallableSymbol<*>> + originalInCache: (D) -> Boolean ): ProcessorAction { - val original = callableSymbol.originalForSubstitutionOverride?.takeIf { it in fakeOverridesMap } + val original = callableSymbol.originalForSubstitutionOverride?.takeIf { originalInCache(it) } ?: return useSiteMemberScope.processDirectOverriddenCallablesWithBaseScope(callableSymbol, processor) if (!processor(original, useSiteMemberScope)) return ProcessorAction.STOP @@ -78,23 +83,12 @@ class FirClassSubstitutionScope( override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { return useSiteMemberScope.processPropertiesByName(name) process@{ original -> - when (original) { - is FirPropertySymbol -> { - val property = substitutionOverrideVariables.getOrPut(original) { createSubstitutionOverrideProperty(original) } - processor(property) - } - is FirFieldSymbol -> { - val field = substitutionOverrideVariables.getOrPut(original) { createSubstitutionOverrideField(original) } - processor(field) - } - is FirAccessorSymbol -> { - val accessor = substitutionOverrideVariables.getOrPut(original) { createSubstitutionOverrideAccessor(original) } - processor(accessor) - } - else -> { - processor(original) - } + val symbol = if (original.isOverridable) { + substitutionOverrideCache.overridesForVariables.getValue(original, this) + } else { + original } + processor(symbol) } } @@ -104,8 +98,7 @@ class FirClassSubstitutionScope( ): ProcessorAction = processDirectOverriddenWithBaseScope( propertySymbol, processor, FirTypeScope::processDirectOverriddenPropertiesWithBaseScope, - substitutionOverrideVariables - ) + ) { it in substitutionOverrideCache.overridesForVariables } override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { useSiteMemberScope.processClassifiersByNameWithSubstitution(name) { symbol, substitutor -> @@ -121,7 +114,7 @@ class FirClassSubstitutionScope( return substitutor.substituteOrNull(this) } - private fun createSubstitutionOverrideFunction(original: FirNamedFunctionSymbol): FirNamedFunctionSymbol { + fun createSubstitutionOverrideFunction(original: FirNamedFunctionSymbol): FirNamedFunctionSymbol { if (substitutor == ConeSubstitutor.Empty) return original val member = original.fir if (skipPrivateMembers && member.visibility == Visibilities.Private) return original @@ -157,7 +150,7 @@ class FirClassSubstitutionScope( ) } - private fun createSubstitutionOverrideConstructor(original: FirConstructorSymbol): FirConstructorSymbol { + fun createSubstitutionOverrideConstructor(original: FirConstructorSymbol): FirConstructorSymbol { if (substitutor == ConeSubstitutor.Empty) return original val constructor = original.fir @@ -177,7 +170,7 @@ class FirClassSubstitutionScope( ).symbol } - private fun createSubstitutionOverrideProperty(original: FirPropertySymbol): FirPropertySymbol { + fun createSubstitutionOverrideProperty(original: FirPropertySymbol): FirPropertySymbol { if (substitutor == ConeSubstitutor.Empty) return original val member = original.fir if (skipPrivateMembers && member.visibility == Visibilities.Private) return original @@ -231,7 +224,7 @@ class FirClassSubstitutionScope( return SubstitutedData(newTypeParameters, newReceiverType, newReturnType, substitutor, fakeOverrideSubstitution) } - private fun createSubstitutionOverrideField(original: FirFieldSymbol): FirFieldSymbol { + fun createSubstitutionOverrideField(original: FirFieldSymbol): FirFieldSymbol { if (substitutor == ConeSubstitutor.Empty) return original val member = original.fir if (skipPrivateMembers && member.visibility == Visibilities.Private) return original @@ -244,7 +237,7 @@ class FirClassSubstitutionScope( return FirFakeOverrideGenerator.createSubstitutionOverrideField(session, member, original, newReturnType, newOwnerClassId) } - private fun createSubstitutionOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol { + fun createSubstitutionOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol { if (substitutor == ConeSubstitutor.Empty) return original val member = original.fir as FirSyntheticProperty if (skipPrivateMembers && member.visibility == Visibilities.Private) return original @@ -282,7 +275,7 @@ class FirClassSubstitutionScope( override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) { useSiteMemberScope.processDeclaredConstructors process@{ original -> - val constructor = substitutionOverrideConstructors.getOrPut(original) { createSubstitutionOverrideConstructor(original) } + val constructor = substitutionOverrideCache.overridesForConstructors.getValue(original, this) processor(constructor) } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt index 328c748da70..18e73cd9043 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt @@ -13,3 +13,7 @@ abstract class FirCache { @Suppress("NOTHING_TO_INLINE") inline fun FirCache.getValue(key: K): V = getValue(key, null) + +operator fun FirCache.contains(key: K): Boolean { + return getValueIfComputed(key) != null +}