[K2] Don't crash compiler if receiver on property wasn't evaluated

Compilation crash must be handled separately in
`convertToConstantValues` method because we still want successfully
compile common code. All constants will be evaluated later on
fir2ir phase.

#KT-59362 Fixed
This commit is contained in:
Ivan Kylchik
2023-06-23 18:54:27 +02:00
committed by Space Team
parent 8dab53f58a
commit fba0bd79ad
4 changed files with 24 additions and 17 deletions
@@ -48,6 +48,8 @@ internal data class FirToConstantValueTransformerData(
val constValueProvider: ConstValueProvider?,
)
private val constantIntrinsicCalls = setOf("toByte", "toLong", "toShort", "toFloat", "toDouble", "toChar", "unaryMinus")
internal abstract class FirToConstantValueTransformer(
private val failOnNonConst: Boolean,
) : FirDefaultVisitor<ConstantValue<*>?, FirToConstantValueTransformerData>() {
@@ -162,22 +164,25 @@ internal abstract class FirToConstantValueTransformer(
}
symbol.callableId.packageName.asString() == "kotlin" -> {
val callableName = symbol.callableId.callableName.asString()
if (callableName !in constantIntrinsicCalls) return null
val dispatchReceiver = qualifiedAccessExpression.dispatchReceiver
val dispatchReceiverValue by lazy { dispatchReceiver.toConstantValue(data) }
when (symbol.callableId.callableName.asString()) {
"toByte" -> ByteValue((dispatchReceiverValue!!.value as Number).toByte())
"toLong" -> LongValue((dispatchReceiverValue!!.value as Number).toLong())
"toShort" -> ShortValue((dispatchReceiverValue!!.value as Number).toShort())
"toFloat" -> FloatValue((dispatchReceiverValue!!.value as Number).toFloat())
"toDouble" -> DoubleValue((dispatchReceiverValue!!.value as Number).toDouble())
"toChar" -> CharValue((dispatchReceiverValue!!.value as Number).toInt().toChar())
val dispatchReceiverValue = dispatchReceiver.toConstantValue(data) ?: return null
when (callableName) {
"toByte" -> ByteValue((dispatchReceiverValue.value as Number).toByte())
"toLong" -> LongValue((dispatchReceiverValue.value as Number).toLong())
"toShort" -> ShortValue((dispatchReceiverValue.value as Number).toShort())
"toFloat" -> FloatValue((dispatchReceiverValue.value as Number).toFloat())
"toDouble" -> DoubleValue((dispatchReceiverValue.value as Number).toDouble())
"toChar" -> CharValue((dispatchReceiverValue.value as Number).toInt().toChar())
"unaryMinus" -> {
when (val receiverValue = dispatchReceiverValue) {
is ByteValue -> ByteValue((-receiverValue.value).toByte())
is LongValue -> LongValue(-receiverValue.value)
is ShortValue -> ShortValue((-receiverValue.value).toShort())
is FloatValue -> FloatValue(-receiverValue.value)
is DoubleValue -> DoubleValue(-receiverValue.value)
when (dispatchReceiverValue) {
is ByteValue -> ByteValue((-dispatchReceiverValue.value).toByte())
is LongValue -> LongValue(-dispatchReceiverValue.value)
is ShortValue -> ShortValue((-dispatchReceiverValue.value).toShort())
is FloatValue -> FloatValue(-dispatchReceiverValue.value)
is DoubleValue -> DoubleValue(-dispatchReceiverValue.value)
else -> null
}
}
@@ -235,8 +240,6 @@ internal object FirToConstantValueChecker : FirDefaultVisitor<Boolean, FirSessio
ConstantValueKind.Int, ConstantValueKind.UnsignedInt, ConstantValueKind.Long, ConstantValueKind.UnsignedLong,
)
private val constantIntrinsicCalls = setOf("toByte", "toLong", "toShort", "toFloat", "toDouble", "toChar", "unaryMinus")
override fun visitElement(element: FirElement, data: FirSession): Boolean {
return false
}