From 9d2298b326c6ecb1dc97a5a88c394a5b1ed2dced Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Wed, 13 Mar 2024 20:34:51 +0100 Subject: [PATCH] [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 --- .../KtFirSymbolDeclarationOverridesProvider.kt | 1 + .../kotlin/analysis/api/fir/utils/typeUtils.kt | 10 +++++----- .../KotlinStandaloneDirectInheritorsProvider.kt | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt index 10518578e67..06198d3ce69 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolDeclarationOverridesProvider.kt @@ -182,6 +182,7 @@ internal class KtFirSymbolDeclarationOverridesProvider( return isSubClassOf( subClass = subClass.firSymbol.fir as FirClass, superClass = superClass.firSymbol.fir as FirClass, + rootModuleSession, allowIndirectSubtyping, ) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/typeUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/typeUtils.kt index 7438fdc3198..046472fe1f3 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/typeUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/typeUtils.kt @@ -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 } diff --git a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/providers/KotlinStandaloneDirectInheritorsProvider.kt b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/providers/KotlinStandaloneDirectInheritorsProvider.kt index ae3f87cc660..c7741a14720 100644 --- a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/providers/KotlinStandaloneDirectInheritorsProvider.kt +++ b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/providers/KotlinStandaloneDirectInheritorsProvider.kt @@ -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<*>? {