[AA] Resolve isSubClassOf from the context of a use-site session again
`isSubClassOf` was changed in an earlier commit to use the session of `subClass` instead, but that approach comes with multiple problems: - We need to resolve classes from the use-site to take actualization of `expect` types into account. - If `superClass` is a builtin and we resolve supertypes from `subClass`'s session, we may get multiple instances of symbols for the same builtin from different sessions (i.e. one from a stdlib session via the use-site session and another from the fallback builtins provider for binary libraries if `subClass` is from a binary library). ^KT-66013
This commit is contained in:
committed by
Space Team
parent
53f2dfec41
commit
9d2298b326
+1
@@ -182,6 +182,7 @@ internal class KtFirSymbolDeclarationOverridesProvider(
|
||||
return isSubClassOf(
|
||||
subClass = subClass.firSymbol.fir as FirClass,
|
||||
superClass = superClass.firSymbol.fir as FirClass,
|
||||
rootModuleSession,
|
||||
allowIndirectSubtyping,
|
||||
)
|
||||
}
|
||||
|
||||
+5
-5
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.utils
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
||||
@@ -14,16 +15,15 @@ import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
||||
/**
|
||||
* Returns whether [subClass] is a strict subtype of [superClass]. Resolves [subClass] to [FirResolvePhase.SUPER_TYPES].
|
||||
*/
|
||||
fun isSubClassOf(subClass: FirClass, superClass: FirClass, allowIndirectSubtyping: Boolean = true): Boolean {
|
||||
fun isSubClassOf(subClass: FirClass, superClass: FirClass, useSiteSession: FirSession, allowIndirectSubtyping: Boolean = true): Boolean {
|
||||
subClass.lazyResolveToPhase(FirResolvePhase.SUPER_TYPES)
|
||||
|
||||
val session = subClass.moduleData.session
|
||||
if (subClass.superConeTypes.any { it.toRegularClassSymbol(session) == superClass.symbol }) return true
|
||||
if (subClass.superConeTypes.any { it.toRegularClassSymbol(useSiteSession) == superClass.symbol }) return true
|
||||
if (!allowIndirectSubtyping) return false
|
||||
|
||||
subClass.superConeTypes.forEach { superType ->
|
||||
val superOfSub = superType.toRegularClassSymbol(session) ?: return@forEach
|
||||
if (isSubClassOf(superOfSub.fir, superClass, allowIndirectSubtyping = true)) return true
|
||||
val superOfSub = superType.toRegularClassSymbol(useSiteSession) ?: return@forEach
|
||||
if (isSubClassOf(superOfSub.fir, superClass, useSiteSession, allowIndirectSubtyping = true)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ class KotlinStandaloneDirectInheritorsProvider(private val project: Project) : K
|
||||
|
||||
// `KotlinDirectInheritorsProvider`'s interface guarantees that `getDirectKotlinInheritors` is only called from lazy resolution to
|
||||
// `SEALED_CLASS_INHERITORS` or later, so `isSubClassOf` resolving to `SUPER_TYPES` is legal.
|
||||
return isSubClassOf(candidateFirClass, baseFirClass, allowIndirectSubtyping = false)
|
||||
return isSubClassOf(candidateFirClass, baseFirClass, candidateFirClass.moduleData.session, allowIndirectSubtyping = false)
|
||||
}
|
||||
|
||||
private fun KtClassOrObject.toFirSymbol(classId: ClassId, ktModule: KtModule): FirClassLikeSymbol<*>? {
|
||||
|
||||
Reference in New Issue
Block a user