[FIR] add memberRequiredPhase to declaredMemberScope

^KT-56551
This commit is contained in:
Dmitrii Gridin
2023-05-15 12:17:07 +02:00
committed by Space Team
parent 01a94624f5
commit 5b3f617378
12 changed files with 105 additions and 60 deletions
@@ -86,7 +86,11 @@ internal class KtFirCallResolver(
) : AbstractKtCallResolver(), KtFirAnalysisSessionComponent {
private val equalsSymbolInAny: FirNamedFunctionSymbol by lazy(LazyThreadSafetyMode.PUBLICATION) {
val session = analysisSession.useSiteSession
val scope = session.declaredMemberScope(session.builtinTypes.anyType.toRegularClassSymbol(session)!!)
val scope = session.declaredMemberScope(
session.builtinTypes.anyType.toRegularClassSymbol(session)!!,
memberRequiredPhase = FirResolvePhase.STATUS,
)
lateinit var result: FirNamedFunctionSymbol
scope.processFunctionsByName(EQUALS) {
result = it
@@ -108,14 +108,14 @@ internal class KtFirScopeProvider(
if (classSymbol is KtFirScriptSymbol) {
return KtFirDelegatingNamesAwareScope(
FirScriptDeclarationsScope(useSiteSession, classSymbol.firSymbol.fir),
builder
builder,
)
}
val firScope = classSymbol.withFirForScope {
when (val regularClass = classSymbol.firSymbol.fir) {
is FirJavaClass -> buildJavaEnhancementDeclaredMemberScope(useSiteSession, regularClass.symbol, getScopeSession())
else -> useSiteSession.declaredMemberScope(it)
else -> useSiteSession.declaredMemberScope(it, memberRequiredPhase = null)
}
} ?: return getEmptyScope()
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -219,7 +219,7 @@ object FirImportsChecker : FirFileChecker() {
predicate: (FirNamedFunctionSymbol) -> Boolean
): Boolean {
var result = false
context.session.declaredMemberScope(this).processFunctionsByName(name) { sym ->
context.session.declaredMemberScope(this, memberRequiredPhase = null).processFunctionsByName(name) { sym ->
if (!result) {
result = predicate(sym)
}
@@ -237,13 +237,13 @@ object FirImportsChecker : FirFileChecker() {
private fun FirRegularClassSymbol.getImportStatusOfCallableMembers(context: CheckerContext, name: Name): ImportStatus {
return if (classKind.isSingleton) {
// Use declaredMemberScope first because it's faster, and it's relatively rare to import members declared from super types.
val scopes = listOf(context.session.declaredMemberScope(this), unsubstitutedScope(context))
val scopes = listOf(context.session.declaredMemberScope(this, memberRequiredPhase = null), unsubstitutedScope(context))
getImportStatus(scopes, context, name) { true }
} else {
val scopes = listOfNotNull(
// We first try resolution with declaredMemberScope because it's faster and typically imported members are not from
// super types.
context.session.declaredMemberScope(this),
context.session.declaredMemberScope(this, memberRequiredPhase = null),
// Next, we try static scope, which can provide static (Java) members from super classes. Note that it's not available
// for pure Kotlin classes.
@@ -74,11 +74,15 @@ object JavaScopeProvider : FirScopeProvider() {
}
private fun buildDeclaredMemberScope(useSiteSession: FirSession, regularClass: FirRegularClass): FirContainingNamesAwareScope {
return if (regularClass is FirJavaClass) useSiteSession.declaredMemberScopeWithLazyNestedScope(
regularClass,
existingNames = regularClass.existingNestedClassifierNames,
symbolProvider = useSiteSession.symbolProvider
) else useSiteSession.declaredMemberScope(regularClass)
return if (regularClass is FirJavaClass) {
useSiteSession.declaredMemberScopeWithLazyNestedScope(
regularClass,
existingNames = regularClass.existingNestedClassifierNames,
symbolProvider = useSiteSession.symbolProvider
)
} else {
useSiteSession.declaredMemberScope(regularClass, memberRequiredPhase = null)
}
}
private fun buildUseSiteMemberScopeWithJavaTypes(
@@ -89,13 +93,12 @@ object JavaScopeProvider : FirScopeProvider() {
): JavaClassUseSiteMemberScope {
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
val declaredScope = buildDeclaredMemberScope(useSiteSession, regularClass)
val superTypes =
if (regularClass.isThereLoopInSupertypes(useSiteSession))
listOf(StandardClassIds.Any.constructClassLikeType(emptyArray(), isNullable = false))
else
lookupSuperTypes(
regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
)
val superTypes = if (regularClass.isThereLoopInSupertypes(useSiteSession))
listOf(StandardClassIds.Any.constructClassLikeType(emptyArray(), isNullable = false))
else
lookupSuperTypes(
regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
)
val superTypeScopes = superTypes.mapNotNull {
it.scopeForSupertype(useSiteSession, scopeSession, regularClass, memberRequiredPhase = memberRequiredPhase)
@@ -161,7 +161,7 @@ private fun FirConstructor.generateNoArgDelegatingConstructorCall() {
}
constructedTypeRef = singleSupertype.toFirResolvedTypeRef()
val superSymbol = singleSupertype.toRegularClassSymbol(session) ?: error("Symbol for supertype $singleSupertype not found")
val superConstructorSymbol = superSymbol.declaredMemberScope(session)
val superConstructorSymbol = superSymbol.declaredMemberScope(session, memberRequiredPhase = null)
.getDeclaredConstructors()
.firstOrNull { it.valueParameterSymbols.isEmpty() }
?: error("No arguments constructor for class $singleSupertype not found")
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
fun FirClass.constructors(session: FirSession): List<FirConstructorSymbol> {
val result = mutableListOf<FirConstructorSymbol>()
session.declaredMemberScope(this).processDeclaredConstructors { result += it }
session.declaredMemberScope(this, memberRequiredPhase = null).processDeclaredConstructors { result += it }
return result
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -86,7 +86,7 @@ inline fun <T, R> Iterable<T>.flatMapToNullableSet(transform: (T) -> Iterable<R>
private fun FirSymbolProvider.getClassDeclaredMemberScope(classId: ClassId): FirScope? {
val classSymbol = getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol ?: return null
return session.declaredMemberScope(classSymbol.fir)
return session.declaredMemberScope(classSymbol.fir, memberRequiredPhase = null)
}
fun FirSymbolProvider.getClassDeclaredConstructors(classId: ClassId): List<FirConstructorSymbol> {
@@ -44,22 +44,27 @@ class FirKotlinScopeProvider(
}
return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
val declaredScope = useSiteSession.declaredMemberScope(klass)
val decoratedDeclaredMemberScope =
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession, memberRequiredPhase).let {
val delegateFields = klass.delegateFields
if (delegateFields.isEmpty())
it
else
FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields)
}
val declaredScope = useSiteSession.declaredMemberScope(klass, memberRequiredPhase)
val decoratedDeclaredMemberScope = declaredMemberScopeDecorator(
klass,
declaredScope,
useSiteSession,
scopeSession,
memberRequiredPhase
).let {
val delegateFields = klass.delegateFields
if (delegateFields.isEmpty())
it
else
FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields)
}
val scopes = lookupSuperTypes(
klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
).mapNotNull { useSiteSuperType ->
useSiteSuperType.scopeForSupertype(useSiteSession, scopeSession, klass, memberRequiredPhase = memberRequiredPhase)
}
FirClassUseSiteMemberScope(
klass,
useSiteSession,
@@ -75,7 +80,14 @@ class FirKotlinScopeProvider(
scopeSession: ScopeSession
): FirContainingNamesAwareScope? {
return when (klass.classKind) {
ClassKind.ENUM_CLASS -> FirNameAwareOnlyCallablesScope(FirStaticScope(useSiteSession.declaredMemberScope(klass)))
ClassKind.ENUM_CLASS -> FirNameAwareOnlyCallablesScope(
FirStaticScope(
useSiteSession.declaredMemberScope(
klass,
memberRequiredPhase = null,
)
)
)
else -> null
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -12,11 +12,13 @@ import org.jetbrains.kotlin.fir.caches.FirCache
import org.jetbrains.kotlin.fir.caches.firCachesFactory
import org.jetbrains.kotlin.fir.caches.getValue
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirNameAwareCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseWithCallableMembers
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -25,7 +27,12 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
class FirDeclaredMemberScopeProvider(val useSiteSession: FirSession) : FirSessionComponent {
private val declaredMemberCache: FirCache<FirClass, FirContainingNamesAwareScope, DeclaredMemberScopeContext> =
useSiteSession.firCachesFactory.createCache { klass, context ->
createDeclaredMemberScope(klass, context.useLazyNestedClassifierScope, context.existingNames, context.symbolProvider)
createDeclaredMemberScope(
klass = klass,
useLazyNestedClassifierScope = context.useLazyNestedClassifierScope,
existingNames = context.existingNames,
symbolProvider = context.symbolProvider,
)
}
private val nestedClassifierCache: FirCache<FirClass, FirNestedClassifierScope?, Nothing?> =
@@ -35,22 +42,34 @@ class FirDeclaredMemberScopeProvider(val useSiteSession: FirSession) : FirSessio
klass: FirClass,
useLazyNestedClassifierScope: Boolean,
existingNames: List<Name>?,
symbolProvider: FirSymbolProvider?
symbolProvider: FirSymbolProvider?,
memberRequiredPhase: FirResolvePhase?,
): FirContainingNamesAwareScope {
return declaredMemberCache.getValue(klass, DeclaredMemberScopeContext(useLazyNestedClassifierScope, existingNames, symbolProvider))
memberRequiredPhase?.let {
klass.lazyResolveToPhaseWithCallableMembers(it)
}
return declaredMemberCache.getValue(
klass,
DeclaredMemberScopeContext(
useLazyNestedClassifierScope,
existingNames,
symbolProvider,
)
)
}
private data class DeclaredMemberScopeContext(
val useLazyNestedClassifierScope: Boolean,
val existingNames: List<Name>?,
val symbolProvider: FirSymbolProvider?
val symbolProvider: FirSymbolProvider?,
)
private fun createDeclaredMemberScope(
klass: FirClass,
useLazyNestedClassifierScope: Boolean,
existingNames: List<Name>?,
symbolProvider: FirSymbolProvider?
symbolProvider: FirSymbolProvider?,
): FirContainingNamesAwareScope {
val origin = klass.origin
return when {
@@ -113,27 +132,35 @@ class FirDeclaredMemberScopeProvider(val useSiteSession: FirSession) : FirSessio
}
}
fun FirSession.declaredMemberScope(klass: FirClass): FirContainingNamesAwareScope {
return declaredMemberScopeProvider
.declaredMemberScope(klass, useLazyNestedClassifierScope = false, existingNames = null, symbolProvider = null)
fun FirSession.declaredMemberScope(klass: FirClass, memberRequiredPhase: FirResolvePhase?): FirContainingNamesAwareScope {
return declaredMemberScopeProvider.declaredMemberScope(
klass = klass,
useLazyNestedClassifierScope = false,
existingNames = null,
symbolProvider = null,
memberRequiredPhase = memberRequiredPhase,
)
}
fun FirSession.declaredMemberScope(klass: FirClassSymbol<*>): FirContainingNamesAwareScope {
return declaredMemberScope(klass.fir)
fun FirSession.declaredMemberScope(klass: FirClassSymbol<*>, memberRequiredPhase: FirResolvePhase?): FirContainingNamesAwareScope {
return declaredMemberScope(klass.fir, memberRequiredPhase)
}
fun FirClassSymbol<*>.declaredMemberScope(session: FirSession): FirContainingNamesAwareScope {
return session.declaredMemberScope(fir)
fun FirClassSymbol<*>.declaredMemberScope(session: FirSession, memberRequiredPhase: FirResolvePhase?): FirContainingNamesAwareScope {
return session.declaredMemberScope(fir, memberRequiredPhase)
}
fun FirSession.declaredMemberScopeWithLazyNestedScope(
klass: FirClass,
existingNames: List<Name>,
symbolProvider: FirSymbolProvider
): FirContainingNamesAwareScope {
return declaredMemberScopeProvider
.declaredMemberScope(klass, useLazyNestedClassifierScope = true, existingNames = existingNames, symbolProvider = symbolProvider)
}
): FirContainingNamesAwareScope = declaredMemberScopeProvider.declaredMemberScope(
klass = klass,
useLazyNestedClassifierScope = true,
existingNames = existingNames,
symbolProvider = symbolProvider,
memberRequiredPhase = null,
)
fun FirSession.nestedClassifierScope(klass: FirClass): FirNestedClassifierScope? {
return declaredMemberScopeProvider
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -9,13 +9,12 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
fun FirClass.generatedNestedClassifiers(session: FirSession): List<FirClassLikeDeclaration> {
val scope = session.declaredMemberScope(this)
val scope = session.declaredMemberScope(this, memberRequiredPhase = null)
val result = mutableListOf<FirClassLikeDeclaration>()
for (name in scope.getClassifierNames()) {
scope.processClassifiersByName(name) {
@@ -30,7 +29,7 @@ fun FirClass.generatedNestedClassifiers(session: FirSession): List<FirClassLikeD
}
fun FirClass.generatedMembers(session: FirSession): List<FirCallableDeclaration> {
val scope = session.declaredMemberScope(this)
val scope = session.declaredMemberScope(this, memberRequiredPhase = null)
val result = mutableListOf<FirCallableDeclaration>()
for (name in scope.getCallableNames()) {
scope.processFunctionsByName(name) {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -517,7 +517,7 @@ abstract class FirDataFlowAnalyzer(
// return true
// }
return session.declaredMemberScope(this)
return session.declaredMemberScope(this, memberRequiredPhase = FirResolvePhase.STATUS)
.getFunctions(OperatorNameConventions.EQUALS)
.any { it.fir.isEquals() }
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -42,7 +42,7 @@ class FirSerializablePropertiesProvider(session: FirSession) : FirExtensionSessi
private fun createSerializableProperties(classSymbol: FirClassSymbol<*>): FirSerializableProperties {
val allPropertySymbols = buildList {
classSymbol
.declaredMemberScope(session)
.declaredMemberScope(session, memberRequiredPhase = null)
.processAllProperties {
addIfNotNull(it as? FirPropertySymbol)
}