[LL FIR] LLFirStatusLazyResolver: pass correct session during resolution
We should use the declaration-site session to have stable resolution order. The same scheme is applicable during regular lazy resolution calls. Also, this means that we should process 'expect' classes before 'actual' like it was for 'super' and 'sub' classes ^KT-63547
This commit is contained in:
committed by
Space Team
parent
6ca6221be9
commit
d83392a27a
+19
-4
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirSingleRe
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.asResolveTarget
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignationWithFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkDeclarationStatusIsResolved
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.forEachDependentDeclaration
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||
@@ -21,7 +22,11 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.StatusComputationSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -83,7 +88,7 @@ private fun LLFirResolveTarget.resolveMode(): StatusResolveMode = when (this) {
|
||||
else -> StatusResolveMode.AllCallables
|
||||
}
|
||||
|
||||
private class LLStatusComputationSession : StatusComputationSession() {
|
||||
private class LLStatusComputationSession(val useSiteSession: FirSession) : StatusComputationSession() {
|
||||
private var shouldCheckForActualization: Boolean = false
|
||||
|
||||
inline fun withClass(regularClass: FirClass, transformer: (FirClass) -> Unit) {
|
||||
@@ -107,7 +112,7 @@ private class LLFirStatusTargetResolver(
|
||||
lockProvider: LLFirLockProvider,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
private val statusComputationSession: LLStatusComputationSession = LLStatusComputationSession(),
|
||||
private val statusComputationSession: LLStatusComputationSession = LLStatusComputationSession(session),
|
||||
private val resolveMode: StatusResolveMode,
|
||||
) : LLFirTargetResolver(target, lockProvider, FirResolvePhase.STATUS, isJumpingPhase = false) {
|
||||
private val transformer = Transformer(session, scopeSession)
|
||||
@@ -236,6 +241,15 @@ private class LLFirStatusTargetResolver(
|
||||
return klass
|
||||
}
|
||||
|
||||
override fun superTypeToSymbols(typeRef: FirTypeRef): List<FirClassifierSymbol<*>> {
|
||||
val type = typeRef.coneType
|
||||
val originalClassifierSymbol = type.toSymbol(session)
|
||||
val useSiteSymbol = type.toSymbol(computationSession.useSiteSession)
|
||||
|
||||
// Resolve an 'expect' declaration before an 'actual' as it is like 'super' and 'sub' classes
|
||||
return listOfNotNull(originalClassifierSymbol, useSiteSymbol?.takeIf { it != originalClassifierSymbol })
|
||||
}
|
||||
|
||||
override fun resolveClassForSuperType(regularClass: FirRegularClass): Boolean {
|
||||
// We cannot skip supertype resolution when there is a possibility
|
||||
// that some supertypes might need to be actualized in the current context
|
||||
@@ -248,11 +262,12 @@ private class LLFirStatusTargetResolver(
|
||||
}
|
||||
|
||||
val target = regularClass.tryCollectDesignationWithFile()?.asResolveTarget() ?: return false
|
||||
val targetSession = target.target.llFirSession
|
||||
val resolver = LLFirStatusTargetResolver(
|
||||
target,
|
||||
lockProvider,
|
||||
session,
|
||||
scopeSession,
|
||||
targetSession,
|
||||
targetSession.getScopeSession(),
|
||||
computationSession,
|
||||
resolveMode = resolveMode,
|
||||
)
|
||||
|
||||
+18
-18
@@ -270,10 +270,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
STATUS:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? open expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public open expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -315,10 +315,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
EXPECT_ACTUAL_MATCHING:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? open expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public open expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -360,10 +360,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
CONTRACTS:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? open expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public open expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -406,10 +406,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? open expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public open expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -452,10 +452,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
ANNOTATION_ARGUMENTS:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? open expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public open expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -498,10 +498,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
BODY_RESOLVE:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? open expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public open expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
|
||||
Vendored
+18
-18
@@ -282,10 +282,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
STATUS:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? final? expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public final expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -329,10 +329,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
EXPECT_ACTUAL_MATCHING:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? final? expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public final expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -376,10 +376,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
CONTRACTS:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? final? expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public final expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -425,10 +425,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? final? expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public final expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -474,10 +474,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
ANNOTATION_ARGUMENTS:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? final? expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public final expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
@@ -523,10 +523,10 @@ FILE: [ResolvedTo(IMPORTS)] jvm.kt
|
||||
|
||||
BODY_RESOLVE:
|
||||
FILE: [ResolvedTo(IMPORTS)] common.kt
|
||||
public? open expect [ResolvedTo(SUPER_TYPES)] class Base<[ResolvedTo(SUPER_TYPES)] T> : R|kotlin/Any| {
|
||||
public? expect [ResolvedTo(RAW_FIR)] [ContainingClassKey=Base] constructor<[ResolvedTo(SUPER_TYPES)] T>(): R|Base<T>|
|
||||
public open expect [ResolvedTo(STATUS)] class Base<[ResolvedTo(STATUS)] T> : R|kotlin/Any| {
|
||||
public expect [ResolvedTo(STATUS)] [ContainingClassKey=Base] constructor<[ResolvedTo(STATUS)] T>(): R|Base<T>|
|
||||
|
||||
public? final? expect [ResolvedTo(RAW_FIR)] fun existingMethodInBase([ResolvedTo(RAW_FIR)] param: T): R|kotlin/Unit|
|
||||
public final expect [ResolvedTo(STATUS)] fun existingMethodInBase([ResolvedTo(STATUS)] param: R|T|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open [ResolvedTo(STATUS)] class Transitive : R|Base<kotlin/String>| {
|
||||
|
||||
+19
-7
@@ -328,26 +328,38 @@ abstract class AbstractFirStatusResolveTransformer(
|
||||
|
||||
fun forceResolveStatusesOfSupertypes(regularClass: FirClass) {
|
||||
for (superTypeRef in regularClass.superTypeRefs) {
|
||||
forceResolveStatusOfCorrespondingClass(superTypeRef)
|
||||
for (classifierSymbol in superTypeToSymbols(superTypeRef)) {
|
||||
forceResolveStatusOfCorrespondingClass(classifierSymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun forceResolveStatusOfCorrespondingClass(typeRef: FirTypeRef) {
|
||||
val superClassSymbol = typeRef.coneType.toSymbol(session)
|
||||
/**
|
||||
* @return symbols which should be resolved to [FirResolvePhase.STATUS] phase
|
||||
*/
|
||||
protected open fun superTypeToSymbols(typeRef: FirTypeRef): List<FirClassifierSymbol<*>> {
|
||||
return listOfNotNull(typeRef.coneType.toSymbol(session))
|
||||
}
|
||||
|
||||
private fun forceResolveStatusOfCorrespondingClass(superClassSymbol: FirClassifierSymbol<*>) {
|
||||
if (isTransformerForLocalDeclarations) {
|
||||
if (superClassSymbol is FirClassSymbol) {
|
||||
superClassSymbol.lazyResolveToPhaseWithCallableMembers(FirResolvePhase.STATUS)
|
||||
} else {
|
||||
superClassSymbol?.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
superClassSymbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
}
|
||||
} else {
|
||||
superClassSymbol?.lazyResolveToPhase(FirResolvePhase.STATUS.previous)
|
||||
superClassSymbol.lazyResolveToPhase(FirResolvePhase.STATUS.previous)
|
||||
}
|
||||
|
||||
when (superClassSymbol) {
|
||||
is FirRegularClassSymbol -> forceResolveStatusesOfClass(superClassSymbol.fir)
|
||||
is FirTypeAliasSymbol -> forceResolveStatusOfCorrespondingClass(superClassSymbol.fir.expandedTypeRef)
|
||||
is FirTypeParameterSymbol, is FirAnonymousObjectSymbol, null -> {}
|
||||
is FirTypeAliasSymbol -> {
|
||||
for (classifierSymbol in superTypeToSymbols(superClassSymbol.fir.expandedTypeRef)) {
|
||||
forceResolveStatusOfCorrespondingClass(classifierSymbol)
|
||||
}
|
||||
}
|
||||
is FirTypeParameterSymbol, is FirAnonymousObjectSymbol -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user