[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(
|
return isSubClassOf(
|
||||||
subClass = subClass.firSymbol.fir as FirClass,
|
subClass = subClass.firSymbol.fir as FirClass,
|
||||||
superClass = superClass.firSymbol.fir as FirClass,
|
superClass = superClass.firSymbol.fir as FirClass,
|
||||||
|
rootModuleSession,
|
||||||
allowIndirectSubtyping,
|
allowIndirectSubtyping,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.fir.utils
|
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.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
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].
|
* 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)
|
subClass.lazyResolveToPhase(FirResolvePhase.SUPER_TYPES)
|
||||||
|
|
||||||
val session = subClass.moduleData.session
|
if (subClass.superConeTypes.any { it.toRegularClassSymbol(useSiteSession) == superClass.symbol }) return true
|
||||||
if (subClass.superConeTypes.any { it.toRegularClassSymbol(session) == superClass.symbol }) return true
|
|
||||||
if (!allowIndirectSubtyping) return false
|
if (!allowIndirectSubtyping) return false
|
||||||
|
|
||||||
subClass.superConeTypes.forEach { superType ->
|
subClass.superConeTypes.forEach { superType ->
|
||||||
val superOfSub = superType.toRegularClassSymbol(session) ?: return@forEach
|
val superOfSub = superType.toRegularClassSymbol(useSiteSession) ?: return@forEach
|
||||||
if (isSubClassOf(superOfSub.fir, superClass, allowIndirectSubtyping = true)) return true
|
if (isSubClassOf(superOfSub.fir, superClass, useSiteSession, allowIndirectSubtyping = true)) return true
|
||||||
}
|
}
|
||||||
return false
|
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
|
// `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.
|
// `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<*>? {
|
private fun KtClassOrObject.toFirSymbol(classId: ClassId, ktModule: KtModule): FirClassLikeSymbol<*>? {
|
||||||
|
|||||||
Reference in New Issue
Block a user