[LL FIR] add ability to suppress contract violation exception
^KT-56543
This commit is contained in:
committed by
Space Team
parent
8387ea8a39
commit
2463b904f7
+12
-6
@@ -5,7 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.symbols.FirLazyResolveContractViolationException
|
||||
|
||||
internal class LLFirLazyResolveContractChecker {
|
||||
private val currentTransformerPhase = ThreadLocal.withInitial<FirResolvePhase?> { null }
|
||||
@@ -26,12 +28,16 @@ internal class LLFirLazyResolveContractChecker {
|
||||
val currentPhase = currentTransformerPhase.get() ?: return
|
||||
|
||||
if (requestedPhase >= currentPhase) {
|
||||
error(
|
||||
"""`lazyResolveToPhase($requestedPhase)` cannot be called from a transformer with a phase $currentPhase.
|
||||
`lazyResolveToPhase` can be called only from a transformer with a phase which is strictly greater than a requested phase;
|
||||
i.e., `lazyResolveToPhase(A)` may be only called from a lazy transformer with a phase B, where A < B. This is a contract of lazy resolve""".trimIndent()
|
||||
)
|
||||
val exception = FirLazyResolveContractViolationException(currentPhase = currentPhase, requestedPhase = requestedPhase)
|
||||
if (System.getProperty("kotlin.suppress.lazy.resolve.contract.violation") != null) {
|
||||
LoggerHolder.LOG.warn(exception)
|
||||
} else {
|
||||
throw exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object LoggerHolder {
|
||||
val LOG = Logger.getInstance(LLFirLazyResolveContractChecker::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,17 @@ abstract class FirLazyDeclarationResolver : FirSessionComponent {
|
||||
abstract fun lazyResolveToPhaseWithCallableMembers(symbol: FirClassSymbol<*>, toPhase: FirResolvePhase)
|
||||
}
|
||||
|
||||
class FirLazyResolveContractViolationException(
|
||||
currentPhase: FirResolvePhase,
|
||||
requestedPhase: FirResolvePhase,
|
||||
) : IllegalStateException(
|
||||
"""
|
||||
`lazyResolveToPhase($requestedPhase)` cannot be called from a transformer with a phase $currentPhase.
|
||||
`lazyResolveToPhase` can be called only from a transformer with a phase which is strictly greater than a requested phase;
|
||||
i.e., `lazyResolveToPhase(A)` may be only called from a lazy transformer with a phase B, where A < B. This is a contract of lazy resolve
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val FirSession.lazyDeclarationResolver: FirLazyDeclarationResolver by FirSession.sessionComponentAccessor()
|
||||
|
||||
private val FirDeclaration.lazyDeclarationResolver get() = moduleData.session.lazyDeclarationResolver
|
||||
|
||||
+6
-9
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.test.frontend.fir.handlers
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.fir.symbols.FirLazyResolveContractViolationException
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
|
||||
|
||||
@@ -20,11 +21,11 @@ class FirCompilerLazyDeclarationResolverWithPhaseChecking : FirLazyDeclarationRe
|
||||
exceptions
|
||||
|
||||
override fun lazyResolveToPhase(symbol: FirBasedSymbol<*>, toPhase: FirResolvePhase) {
|
||||
checkIfCanLazyResolveToPhase(symbol, toPhase)
|
||||
checkIfCanLazyResolveToPhase(toPhase)
|
||||
}
|
||||
|
||||
override fun lazyResolveToPhaseWithCallableMembers(symbol: FirClassSymbol<*>, toPhase: FirResolvePhase) {
|
||||
checkIfCanLazyResolveToPhase(symbol, toPhase)
|
||||
checkIfCanLazyResolveToPhase(toPhase)
|
||||
}
|
||||
|
||||
override fun startResolvingPhase(phase: FirResolvePhase) {
|
||||
@@ -37,7 +38,7 @@ class FirCompilerLazyDeclarationResolverWithPhaseChecking : FirLazyDeclarationRe
|
||||
currentTransformerPhase = null
|
||||
}
|
||||
|
||||
private fun checkIfCanLazyResolveToPhase(symbol: FirBasedSymbol<*>, requestedPhase: FirResolvePhase) {
|
||||
private fun checkIfCanLazyResolveToPhase(requestedPhase: FirResolvePhase) {
|
||||
if (!lazyResolveContractChecksEnabled) return
|
||||
|
||||
val currentPhase = currentTransformerPhase
|
||||
@@ -50,13 +51,9 @@ class FirCompilerLazyDeclarationResolverWithPhaseChecking : FirLazyDeclarationRe
|
||||
// but due to usage of already resolved stdlib classes we don't see it
|
||||
if (requestedPhase >= currentPhase) {
|
||||
exceptions += FirLazyResolveContractViolationException(
|
||||
"""`lazyResolveToPhase($requestedPhase)` cannot be called from a transformer with a phase $currentPhase.
|
||||
lazyResolveToPhase was called on a $symbol.
|
||||
`lazyResolveToPhase` can be called only from a transformer with a phase which is strictly greater than a requested phase;
|
||||
i.e., `lazyResolveToPhase(A)` may be only called from a lazy transformer with a phase B, where A < B. This is a contract of lazy resolve""".trimIndent()
|
||||
currentPhase = currentPhase,
|
||||
requestedPhase = requestedPhase,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FirLazyResolveContractViolationException(message: String) : IllegalStateException(message)
|
||||
|
||||
Reference in New Issue
Block a user