From 6ca6221be91668e386a077557dc83a5e61dfc12f Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Tue, 19 Dec 2023 17:43:22 +0100 Subject: [PATCH] [LL FIR] LLFirStatusLazyResolver: more conservative optimization for actual classes We cannot skip resolution in the case of type actualization as we cannot guaranty that there are no any classes in super types which can be actualized in the current context ^KT-62832 Fixed ^KT-63547 --- .../transformers/LLFirStatusLazyResolver.kt | 31 ++++++++++++++++--- .../FirStatusResolveTransformer.kt | 4 +-- .../codegen/box/multiplatform/kt61166.kt | 1 - 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirStatusLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirStatusLazyResolver.kt index e50728e7af8..9b6d1325d05 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirStatusLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirStatusLazyResolver.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.forEachDependentDecl import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isActual import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolveTransformer @@ -82,12 +83,31 @@ private fun LLFirResolveTarget.resolveMode(): StatusResolveMode = when (this) { else -> StatusResolveMode.AllCallables } +private class LLStatusComputationSession : StatusComputationSession() { + private var shouldCheckForActualization: Boolean = false + + inline fun withClass(regularClass: FirClass, transformer: (FirClass) -> Unit) { + val oldValue = shouldCheckForActualization + if (regularClass.isActual) { + shouldCheckForActualization = true + } + + try { + transformer(regularClass) + } finally { + shouldCheckForActualization = oldValue + } + } + + val canHaveActualization: Boolean get() = shouldCheckForActualization +} + private class LLFirStatusTargetResolver( target: LLFirResolveTarget, lockProvider: LLFirLockProvider, session: FirSession, scopeSession: ScopeSession, - private val statusComputationSession: StatusComputationSession = StatusComputationSession(), + private val statusComputationSession: LLStatusComputationSession = LLStatusComputationSession(), private val resolveMode: StatusResolveMode, ) : LLFirTargetResolver(target, lockProvider, FirResolvePhase.STATUS, isJumpingPhase = false) { private val transformer = Transformer(session, scopeSession) @@ -176,7 +196,7 @@ private class LLFirStatusTargetResolver( transformer.statusComputationSession.startComputing(firClass) if (resolveMode.resolveSupertypes) { - transformer.forceResolveStatusesOfSupertypes(firClass) + statusComputationSession.withClass(firClass, transformer::forceResolveStatusesOfSupertypes) } performCustomResolveUnderLock(firClass) { @@ -207,6 +227,7 @@ private class LLFirStatusTargetResolver( session: FirSession, scopeSession: ScopeSession, ) : FirStatusResolveTransformer(session, scopeSession, statusComputationSession) { + val computationSession: LLStatusComputationSession get() = this@LLFirStatusTargetResolver.statusComputationSession override fun FirDeclaration.needResolveMembers(): Boolean = false override fun FirDeclaration.needResolveNestedClassifiers(): Boolean = false @@ -216,7 +237,9 @@ private class LLFirStatusTargetResolver( } override fun resolveClassForSuperType(regularClass: FirRegularClass): Boolean { - if (regularClass.resolvePhase >= resolverPhase) { + // We cannot skip supertype resolution when there is a possibility + // that some supertypes might need to be actualized in the current context + if (!computationSession.canHaveActualization && regularClass.resolvePhase >= resolverPhase) { // We can avoid resolve in the case of all declarations in super class are already resolved val declarations = regularClass.declarations if (declarations.isNotEmpty() && declarations.all { it.resolvePhase >= resolverPhase }) { @@ -230,7 +253,7 @@ private class LLFirStatusTargetResolver( lockProvider, session, scopeSession, - statusComputationSession, + computationSession, resolveMode = resolveMode, ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt index 7be1b779ca8..825c1e8af60 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt @@ -25,8 +25,8 @@ import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.toSymbol import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry import org.jetbrains.kotlin.fir.visitors.transformSingle -import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import org.jetbrains.kotlin.util.PrivateForInline +import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment class FirStatusResolveProcessor( session: FirSession, @@ -155,7 +155,7 @@ open class FirDesignatedStatusResolveTransformer( } } -class StatusComputationSession { +open class StatusComputationSession { private val statusMap = mutableMapOf() .withDefault { StatusComputationStatus.NotComputed } diff --git a/compiler/testData/codegen/box/multiplatform/kt61166.kt b/compiler/testData/codegen/box/multiplatform/kt61166.kt index 33076861cae..b75c48736c0 100644 --- a/compiler/testData/codegen/box/multiplatform/kt61166.kt +++ b/compiler/testData/codegen/box/multiplatform/kt61166.kt @@ -4,7 +4,6 @@ // ISSUE: KT-60854 // WITH_STDLIB // FULL_JDK -// MUTE_LL_FIR: KT-62832 // MODULE: common // FILE: common.kt