FIR: uniquify scopes to avoid ambiguity on diamond inheritance

This commit is contained in:
Simon Ogorodnik
2019-04-15 16:47:35 +03:00
committed by Mikhail Glukhikh
parent 8d4cbd84e3
commit 4cb8faf666
20 changed files with 180 additions and 101 deletions
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.references.FirPropertyFromParameterCallableReference
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
@@ -196,7 +197,7 @@ internal class Fir2IrVisitor(
private fun IrClass.addFakeOverrides(klass: FirClass, processedFunctionNames: MutableList<Name>) {
if (fakeOverrideMode == FakeOverrideMode.NONE) return
val superTypesFunctionNames = klass.collectFunctionNamesFromSupertypes()
val useSiteScope = (klass as? FirRegularClass)?.buildUseSiteScope(session) ?: return
val useSiteScope = (klass as? FirRegularClass)?.buildUseSiteScope(session, ScopeSession()) ?: return
for (name in superTypesFunctionNames) {
if (name in processedFunctionNames) continue
processedFunctionNames += name
@@ -393,7 +394,7 @@ internal class Fir2IrVisitor(
val classId = constructedClassSymbol.classId
val provider = this@Fir2IrVisitor.session.service<FirSymbolProvider>()
var constructorSymbol: FirCallableSymbol? = null
provider.getClassUseSiteMemberScope(classId, this@Fir2IrVisitor.session)!!.processFunctionsByName(
provider.getClassUseSiteMemberScope(classId, this@Fir2IrVisitor.session, ScopeSession())!!.processFunctionsByName(
classId.shortClassName
) {
if (arguments.size <= ((it as FirFunctionSymbol).fir as FirFunction).valueParameters.size) {
@@ -13,18 +13,20 @@ import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteScope
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
@@ -52,9 +54,47 @@ class JavaSymbolProvider(
return FirClassDeclaredMemberScope(classSymbol.fir)
}
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope? {
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return symbol.firUnsafe<FirRegularClass>().buildUseSiteScope(useSiteSession)
val javaClass = symbol.firUnsafe<FirJavaClass>()
return buildJavaEnhancementScope(useSiteSession, javaClass.symbol, scopeSession)
}
private fun buildJavaEnhancementScope(
useSiteSession: FirSession,
symbol: FirClassSymbol,
scopeSession: ScopeSession
): JavaClassEnhancementScope {
return scopeSession.getOrBuild(symbol, JAVA_ENHANCEMENT) {
JavaClassEnhancementScope(useSiteSession, buildJavaUseSiteScope(symbol.fir, useSiteSession, scopeSession))
}
}
private fun buildJavaUseSiteScope(
regularClass: FirRegularClass,
useSiteSession: FirSession,
scopeSession: ScopeSession
): JavaClassUseSiteScope {
return scopeSession.getOrBuild(regularClass.symbol, JAVA_USE_SITE) {
val superTypeEnhancementScope = FirCompositeScope(mutableListOf())
val declaredScope = scopeSession.getOrBuild(regularClass.symbol, DECLARED) { FirClassDeclaredMemberScope(regularClass) }
lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNullTo(superTypeEnhancementScope.scopes) { useSiteSuperType ->
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
if (symbol is FirClassSymbol) {
// We need JavaClassEnhancementScope here to have already enhanced signatures from supertypes
buildJavaEnhancementScope(useSiteSession, symbol, scopeSession)
} else {
null
}
}
JavaClassUseSiteScope(regularClass, useSiteSession, superTypeEnhancementScope, declaredScope)
}
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
@@ -175,3 +215,5 @@ fun FqName.topLevelName() =
asString().substringBefore(".")
private val JAVA_ENHANCEMENT = scopeSessionKey<JavaClassEnhancementScope>()
private val JAVA_USE_SITE = scopeSessionKey<JavaClassUseSiteScope>()
@@ -13,15 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirAbstractMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableClass
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteScope
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.name.Name
@@ -49,29 +41,8 @@ class FirJavaClass(
override val superTypeRefs = mutableListOf<FirTypeRef>()
override fun buildClassSpecificUseSiteScope(useSiteSession: FirSession): FirScope? {
return JavaClassEnhancementScope(useSiteSession, buildJavaUseSiteScope(this, useSiteSession))
}
override val declarations = mutableListOf<FirDeclaration>()
private fun buildJavaUseSiteScope(regularClass: FirRegularClass, useSiteSession: FirSession): JavaClassUseSiteScope {
val superTypeEnhancementScope = FirCompositeScope(mutableListOf())
val declaredScope = FirClassDeclaredMemberScope(regularClass)
lookupSuperTypes(regularClass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNullTo(superTypeEnhancementScope.scopes) { useSiteSuperType ->
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
if (symbol is FirClassSymbol) {
// We need JavaClassEnhancementScope here to have already enhanced signatures from supertypes
JavaClassEnhancementScope(useSiteSession, buildJavaUseSiteScope(symbol.fir, useSiteSession))
} else {
null
}
}
return JavaClassUseSiteScope(regularClass, useSiteSession, superTypeEnhancementScope, declaredScope)
}
override fun replaceSupertypes(newSupertypes: List<FirTypeRef>): FirRegularClass {
superTypeRefs.clear()
superTypeRefs.addAll(newSupertypes)
@@ -60,9 +60,14 @@ class KotlinDeserializedJvmSymbolsProvider(
}
}
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope? {
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return symbol.firUnsafe<FirRegularClass>().buildUseSiteScope(session)
return symbol.firUnsafe<FirRegularClass>().buildDefaultUseSiteScope(session, scopeSession)
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
@@ -30,7 +30,11 @@ interface FirSymbolProvider {
fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<ConeCallableSymbol>
fun getClassDeclaredMemberScope(classId: ClassId): FirScope?
fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope?
fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope?
fun getAllCallableNamesInPackage(fqName: FqName): Set<Name> = emptySet()
fun getClassNamesInPackage(fqName: FqName): Set<Name> = emptySet()
@@ -17,24 +17,24 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
fun ConeKotlinType.scope(useSiteSession: FirSession): FirScope? {
fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
return when (this) {
is ConeKotlinErrorType -> null
is ConeClassErrorType -> null
is ConeAbbreviatedType -> directExpansionType(useSiteSession)?.scope(useSiteSession)
is ConeAbbreviatedType -> directExpansionType(useSiteSession)?.scope(useSiteSession, scopeSession)
is ConeClassLikeType -> {
// For ConeClassLikeType they might be a type alias instead of a regular class
// TODO: support that case and switch back to `firUnsafe` instead of `firSafeNullable`
val fir = this.lookupTag.toSymbol(useSiteSession)?.firSafeNullable<FirRegularClass>() ?: return null
fir.buildUseSiteScope(useSiteSession)
fir.buildUseSiteScope(useSiteSession, scopeSession)
}
is ConeTypeParameterType -> {
// TODO: support LibraryTypeParameterSymbol or get rid of it
val toSymbol = this.lookupTag.toSymbol(useSiteSession)?.takeIf { it is FirBasedSymbol<*> } ?: return null
val fir = toSymbol.firUnsafe<FirTypeParameter>()
FirCompositeScope(fir.bounds.mapNotNullTo(mutableListOf()) { it.coneTypeUnsafe<ConeKotlinType>().scope(useSiteSession) })
FirCompositeScope(fir.bounds.mapNotNullTo(mutableListOf()) { it.coneTypeUnsafe().scope(useSiteSession, scopeSession) })
}
is ConeFlexibleType -> lowerBound.scope(useSiteSession)
is ConeFlexibleType -> lowerBound.scope(useSiteSession, scopeSession)
else -> error("Failed type ${this}")
}
}
@@ -8,10 +8,12 @@ package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.declarations.superConeTypes
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.ConeClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
@@ -30,40 +32,67 @@ fun lookupSuperTypes(
}
}
fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession): FirScope {
return buildClassSpecificUseSiteScope(useSiteSession) ?: buildDefaultUseSiteScope(useSiteSession)
class ScopeSession {
private val scopes = mutableMapOf<ConeClassifierSymbol, MutableMap<ScopeSessionKey<*>, FirScope>>()
fun <T : FirScope> getOrBuild(symbol: ConeClassifierSymbol, key: ScopeSessionKey<T>, build: () -> T): T {
return scopes.getOrPut(symbol) {
mutableMapOf()
}.getOrPut(key) {
build()
} as T
}
}
private fun FirRegularClass.buildDefaultUseSiteScope(useSiteSession: FirSession): FirScope {
val superTypeScope = FirCompositeScope(mutableListOf())
val declaredScope = FirClassDeclaredMemberScope(this)
lookupSuperTypes(this, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNullTo(superTypeScope.scopes) { useSiteSuperType ->
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
if (symbol is FirClassSymbol) {
val useSiteScope = symbol.fir.buildUseSiteScope(useSiteSession)
useSiteSuperType.buildSubstitutionScope(useSiteSession, useSiteScope, symbol.fir) ?: useSiteScope
} else {
null
abstract class ScopeSessionKey<T : FirScope>()
inline fun <reified T : FirScope> scopeSessionKey(): ScopeSessionKey<T> {
return object : ScopeSessionKey<T>() {}
}
val USE_SITE = scopeSessionKey()
val DECLARED = scopeSessionKey()
data class SubstitutionScopeKey<T : FirClassSubstitutionScope>(val type: ConeClassLikeType) : ScopeSessionKey<T>() {}
fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession, builder: ScopeSession): FirScope {
val symbolProvider = useSiteSession.service<FirSymbolProvider>()
return symbolProvider.getClassUseSiteMemberScope(this.classId, useSiteSession, builder)!!
}
fun FirRegularClass.buildDefaultUseSiteScope(useSiteSession: FirSession, builder: ScopeSession): FirScope {
return builder.getOrBuild(symbol, USE_SITE) {
val superTypeScope = FirCompositeScope(mutableListOf())
val declaredScope = builder.getOrBuild(this.symbol, DECLARED) { FirClassDeclaredMemberScope(this) }
lookupSuperTypes(this, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession)
.mapNotNullTo(superTypeScope.scopes) { useSiteSuperType ->
if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null
val symbol = useSiteSuperType.lookupTag.toSymbol(useSiteSession)
if (symbol is FirClassSymbol) {
val useSiteScope = symbol.fir.buildUseSiteScope(useSiteSession, builder)
useSiteSuperType.wrapSubstitutionScopeIfNeed(useSiteSession, useSiteScope, symbol.fir, builder)
} else {
null
}
}
}
return FirClassUseSiteScope(useSiteSession, superTypeScope, declaredScope)
FirClassUseSiteScope(useSiteSession, superTypeScope, declaredScope)
}
}
private fun ConeClassLikeType.buildSubstitutionScope(
private fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
session: FirSession,
useSiteScope: FirScope,
regularClass: FirRegularClass
): FirClassSubstitutionScope? {
if (this.typeArguments.isEmpty()) return null
regularClass: FirRegularClass,
builder: ScopeSession
): FirScope {
if (this.typeArguments.isEmpty()) return useSiteScope
return builder.getOrBuild(regularClass.symbol, SubstitutionScopeKey(this)) {
@Suppress("UNCHECKED_CAST")
val substitution = regularClass.typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type
}.filter { (_, type) -> type != null }.toMap() as Map<ConeTypeParameterSymbol, ConeKotlinType>
@Suppress("UNCHECKED_CAST")
val substitution = regularClass.typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type
}.filter { (_, type) -> type != null }.toMap() as Map<ConeTypeParameterSymbol, ConeKotlinType>
return FirClassSubstitutionScope(session, useSiteScope, substitution)
FirClassSubstitutionScope(session, useSiteScope, substitution)
}
}
private tailrec fun ConeClassLikeType.computePartialExpansion(useSiteSession: FirSession): ConeClassLikeType? {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
@@ -143,7 +144,7 @@ class MemberScopeTowerLevel(
output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
processScopeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction
): ProcessorAction {
val scope = dispatchReceiver.type.scope(session) ?: return ProcessorAction.NEXT
val scope = dispatchReceiver.type.scope(session, ScopeSession()) ?: return ProcessorAction.NEXT
if (scope.processScopeMembers { output.consumeCandidate(it, dispatchReceiver) }.stop()) return ProcessorAction.STOP
val withSynthetic = FirSyntheticPropertiesScope(session, scope, ReturnTypeCalculatorWithJump(session))
return withSynthetic.processScopeMembers { output.consumeCandidate(it, dispatchReceiver) }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
@@ -16,8 +17,12 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
class FirCompositeSymbolProvider(val providers: List<FirSymbolProvider>) : FirSymbolProvider {
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope? {
return providers.firstNotNullResult { it.getClassUseSiteMemberScope(classId, useSiteSession) }
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
return providers.firstNotNullResult { it.getClassUseSiteMemberScope(classId, useSiteSession, scopeSession) }
}
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<ConeCallableSymbol> {
@@ -6,12 +6,10 @@
package org.jetbrains.kotlin.fir.resolve.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.CallableId
@@ -50,9 +48,12 @@ class FirDependenciesSymbolProviderImpl(val session: FirSession) : AbstractFirSy
}
}
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return symbol.firUnsafe<FirRegularClass>().buildUseSiteScope(useSiteSession)
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
return dependencyProviders.firstNotNullResult { it.getClassUseSiteMemberScope(classId, useSiteSession, scopeSession) }
}
override fun getPackage(fqName: FqName): FqName? {
@@ -18,9 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.resolve.getOrPut
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
@@ -106,9 +104,13 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider
}
}
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope? {
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return symbol.firUnsafe<FirRegularClass>().buildUseSiteScope(useSiteSession)
return symbol.firUnsafe<FirRegularClass>().buildDefaultUseSiteScope(useSiteSession, scopeSession)
}
override fun getPackage(fqName: FqName): FqName? {
@@ -10,7 +10,8 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.buildDefaultUseSiteScope
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
@@ -193,9 +194,13 @@ class FirProviderImpl(val session: FirSession) : FirProvider {
}
}
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope? {
override fun getClassUseSiteMemberScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return symbol.firUnsafe<FirRegularClass>().buildUseSiteScope(useSiteSession)
return symbol.firUnsafe<FirRegularClass>().buildDefaultUseSiteScope(useSiteSession, scopeSession)
}
}
@@ -86,7 +86,7 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirDeclaration> {
return withScopeCleanup(scopes) {
val type = regularClass.defaultType()
scopes.addIfNotNull(type.scope(session))
scopes.addIfNotNull(type.scope(session, ScopeSession()))
withLabel(regularClass.name, type) {
super.transformRegularClass(regularClass, data)
}
@@ -484,7 +484,7 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
fun transform(): CompositeTransformResult<FirDeclaration> {
localScopes.lastOrNull()?.storeDeclaration(namedFunction)
return withScopeCleanup(scopes) {
scopes.addIfNotNull(receiverTypeRef?.coneTypeSafe<ConeKotlinType>()?.scope(session))
scopes.addIfNotNull(receiverTypeRef?.coneTypeSafe()?.scope(session, ScopeSession()))
val result = super.transformNamedFunction(namedFunction, namedFunction.returnTypeRef).single as FirNamedFunction
@@ -7,8 +7,9 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.resolve.calls.TowerScopeLevel
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
@@ -21,7 +22,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast
abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boolean) : FirAbstractProviderBasedScope(session, lookupInFir) {
protected val scopeCache = mutableMapOf<ClassId, FirScope>()
protected val scopeCache = ScopeSession()
fun <T : ConeCallableSymbol> processCallables(
import: FirResolvedImport,
@@ -34,9 +35,9 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
val classId = import.resolvedClassId
if (classId != null) {
val scope = scopeCache.getOrPut(classId) {
provider.getClassUseSiteMemberScope(classId, session) ?: error("No scope for $classId")
}
val scope =
provider.getClassUseSiteMemberScope(classId, session, scopeCache) ?: error("No scope for $classId")
val action = when (token) {
TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(
callableId.callableName,
@@ -40,9 +40,17 @@ class FirCompositeScope(
name: Name,
noinline processor: (T) -> ProcessorAction
): ProcessorAction {
val unique = mutableSetOf<T>()
val scopes = if (reversedPriority) scopes.asReversed() else scopes
for (scope in scopes) {
if (!scope.process(name, processor)) {
if (!scope.process(name) {
if (unique.add(it)) {
processor(it)
} else {
NEXT
}
}
) {
return STOP
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
@@ -30,7 +31,7 @@ class FirTopLevelDeclaredMemberScope(
if (matchedClass != null && matchedClass is FirClassSymbol) {
// TODO: why don't we use declared member scope at this point?
if (matchedClass.fir.buildUseSiteScope(session).processFunctionsByName(name, processor) == STOP) {
if (matchedClass.fir.buildUseSiteScope(session, ScopeSession()).processFunctionsByName(name, processor) == STOP) {
return STOP
}
}
@@ -22,12 +22,14 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
@@ -170,7 +172,7 @@ abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
val processedJavaClasses = mutableSetOf<FirJavaClass>()
for (javaClass in javaProvider.getJavaTopLevelClasses().sortedBy { it.name }) {
if (javaClass !is FirJavaClass || javaClass in processedJavaClasses) continue
val enhancementScope = javaClass.buildClassSpecificUseSiteScope(session).let {
val enhancementScope = javaProvider.getClassUseSiteMemberScope(javaClass.classId, session, ScopeSession()).let {
when (it) {
is FirCompositeScope -> it.scopes.filterIsInstance<JavaClassEnhancementScope>().first()
is JavaClassEnhancementScope -> it
@@ -21,8 +21,6 @@ interface FirClass : FirDeclarationContainer, FirStatement, FirAnnotationContain
val classKind: ClassKind
fun buildClassSpecificUseSiteScope(useSiteSession: FirSession): FirScope? = null
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.service
@@ -64,7 +65,7 @@ class IdeFirDependenciesSymbolProvider(
}
}
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession): FirScope? {
override fun getClassUseSiteMemberScope(classId: ClassId, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
TODO("not implemented")
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
import org.jetbrains.kotlin.fir.java.FirLibrarySession
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
@@ -135,7 +137,7 @@ abstract class AbstractFirMultiModuleResolveTest : AbstractMultiModuleTest() {
val javaProvider = symbolProvider.providers.filterIsInstance<JavaSymbolProvider>().first()
for (javaClass in javaProvider.getJavaTopLevelClasses().sortedBy { it.name }) {
if (javaClass !is FirJavaClass || javaClass in processedJavaClasses) continue
val enhancementScope = javaClass.buildClassSpecificUseSiteScope(session).let {
val enhancementScope = javaProvider.getClassUseSiteMemberScope(javaClass.classId, session, ScopeSession()).let {
when (it) {
is FirCompositeScope -> it.scopes.filterIsInstance<JavaClassEnhancementScope>().first()
is JavaClassEnhancementScope -> it