AA: avoid conversions to KtInitializerValue in constant evaluator
This commit is contained in:
committed by
Ilya Kirillov
parent
1f93630a9c
commit
ee23a52e54
+17
-22
@@ -5,27 +5,24 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.components
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
|
||||
import org.jetbrains.kotlin.analysis.api.KtInitializerValue
|
||||
import org.jetbrains.kotlin.analysis.api.KtNonConstantInitializerValue
|
||||
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtCompileTimeConstantProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirCompileTimeConstantEvaluator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.getKtConstantInitializer
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.referredPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolvedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
|
||||
internal class KtFirCompileTimeConstantProvider(
|
||||
@@ -34,20 +31,24 @@ internal class KtFirCompileTimeConstantProvider(
|
||||
) : KtCompileTimeConstantProvider(), KtFirAnalysisSessionComponent {
|
||||
|
||||
override fun evaluate(expression: KtExpression): KtConstantValue? = withValidityAssertion {
|
||||
when (val fir = expression.getOrBuildFir(firResolveState)) {
|
||||
evaluateFir(expression.getOrBuildFir(firResolveState), expression)
|
||||
}
|
||||
|
||||
private fun evaluateFir(fir: FirElement?, context: KtExpression): KtConstantValue? = withValidityAssertion {
|
||||
when (fir) {
|
||||
is FirPropertyAccessExpression -> {
|
||||
fir.referredPropertySymbol?.toKtConstantValue()
|
||||
fir.referredPropertySymbol?.toKtConstantValue(context)
|
||||
}
|
||||
is FirExpression -> {
|
||||
try {
|
||||
FirCompileTimeConstantEvaluator.evaluateAsKtConstantExpression(fir)
|
||||
} catch (e: ArithmeticException) {
|
||||
KtConstantValue.KtErrorConstantValue(e.localizedMessage, fir.psi as? KtElement)
|
||||
KtConstantValue.KtErrorConstantValue(e.localizedMessage, context)
|
||||
}
|
||||
}
|
||||
is FirNamedReference -> {
|
||||
when (val resolvedSymbol = fir.resolvedSymbol) {
|
||||
is FirPropertySymbol -> resolvedSymbol.toKtConstantValue()
|
||||
is FirPropertySymbol -> resolvedSymbol.toKtConstantValue(context)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -60,21 +61,15 @@ internal class KtFirCompileTimeConstantProvider(
|
||||
// `false` does not have a corresponding elements on the FIR side and hence the containing `FirWhenBranch` is returned. In this
|
||||
// case, we simply report null since FIR does not know about it.
|
||||
is FirWhenBranch -> null
|
||||
else -> throwUnexpectedFirElementError(fir, expression)
|
||||
else -> throwUnexpectedFirElementError(fir, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirPropertySymbol.toKtConstantValue(): KtConstantValue? = withValidityAssertion {
|
||||
if (isVal) {
|
||||
getKtConstantInitializer()?.toKtConstantValue()
|
||||
private fun FirPropertySymbol.toKtConstantValue(context: KtExpression): KtConstantValue? = withValidityAssertion {
|
||||
if (isVal && hasInitializer) {
|
||||
// NB: the initializer could be [FirLazyExpression] in [BodyBuildingMode.LAZY_BODIES].
|
||||
this.ensureResolved(FirResolvePhase.BODY_RESOLVE) // to unwrap lazy body
|
||||
evaluateFir(fir.initializer, context)
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun KtInitializerValue?.toKtConstantValue(): KtConstantValue? = withValidityAssertion {
|
||||
when (this) {
|
||||
null -> null
|
||||
is KtConstantInitializerValue -> constant
|
||||
is KtNonConstantInitializerValue -> initializerPsi?.let { evaluate(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user