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
|
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.base.KtConstantValue
|
||||||
import org.jetbrains.kotlin.analysis.api.components.KtCompileTimeConstantProvider
|
import org.jetbrains.kotlin.analysis.api.components.KtCompileTimeConstantProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirCompileTimeConstantEvaluator
|
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.tokens.ValidityToken
|
||||||
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
|
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.getOrBuildFir
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
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.declarations.utils.referredPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
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.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolvedSymbol
|
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.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
|
||||||
internal class KtFirCompileTimeConstantProvider(
|
internal class KtFirCompileTimeConstantProvider(
|
||||||
@@ -34,20 +31,24 @@ internal class KtFirCompileTimeConstantProvider(
|
|||||||
) : KtCompileTimeConstantProvider(), KtFirAnalysisSessionComponent {
|
) : KtCompileTimeConstantProvider(), KtFirAnalysisSessionComponent {
|
||||||
|
|
||||||
override fun evaluate(expression: KtExpression): KtConstantValue? = withValidityAssertion {
|
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 -> {
|
is FirPropertyAccessExpression -> {
|
||||||
fir.referredPropertySymbol?.toKtConstantValue()
|
fir.referredPropertySymbol?.toKtConstantValue(context)
|
||||||
}
|
}
|
||||||
is FirExpression -> {
|
is FirExpression -> {
|
||||||
try {
|
try {
|
||||||
FirCompileTimeConstantEvaluator.evaluateAsKtConstantExpression(fir)
|
FirCompileTimeConstantEvaluator.evaluateAsKtConstantExpression(fir)
|
||||||
} catch (e: ArithmeticException) {
|
} catch (e: ArithmeticException) {
|
||||||
KtConstantValue.KtErrorConstantValue(e.localizedMessage, fir.psi as? KtElement)
|
KtConstantValue.KtErrorConstantValue(e.localizedMessage, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FirNamedReference -> {
|
is FirNamedReference -> {
|
||||||
when (val resolvedSymbol = fir.resolvedSymbol) {
|
when (val resolvedSymbol = fir.resolvedSymbol) {
|
||||||
is FirPropertySymbol -> resolvedSymbol.toKtConstantValue()
|
is FirPropertySymbol -> resolvedSymbol.toKtConstantValue(context)
|
||||||
else -> null
|
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
|
// `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.
|
// case, we simply report null since FIR does not know about it.
|
||||||
is FirWhenBranch -> null
|
is FirWhenBranch -> null
|
||||||
else -> throwUnexpectedFirElementError(fir, expression)
|
else -> throwUnexpectedFirElementError(fir, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirPropertySymbol.toKtConstantValue(): KtConstantValue? = withValidityAssertion {
|
private fun FirPropertySymbol.toKtConstantValue(context: KtExpression): KtConstantValue? = withValidityAssertion {
|
||||||
if (isVal) {
|
if (isVal && hasInitializer) {
|
||||||
getKtConstantInitializer()?.toKtConstantValue()
|
// 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
|
} 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