[IR] Rewrite logic around object interpretation

Basically we want to allow object interpretation only when we try
to access some const val property.

#KT-57810 Fixed
This commit is contained in:
Ivan Kylchik
2023-04-07 23:50:57 +02:00
committed by Space Team
parent 5956e9b500
commit 1ddcdcfc39
4 changed files with 16 additions and 6 deletions
@@ -297,7 +297,8 @@ internal fun IrClass.getSingleAbstractMethod(): IrFunction {
return declarations.filterIsInstance<IrSimpleFunction>().single { it.modality == Modality.ABSTRACT }
}
internal fun IrGetValue.isAccessToNotNullableObject(): Boolean {
internal fun IrExpression?.isAccessToNotNullableObject(): Boolean {
if (this !is IrGetValue) return false
val owner = this.symbol.owner
val expectedClass = this.type.classOrNull?.owner
if (expectedClass == null || !expectedClass.isObject || this.type.isNullable()) return false
@@ -66,6 +66,10 @@ class IrCompileTimeChecker(
return this.asVisited { !mode.mustCheckBodyOf(this) || (this.body?.accept(this@IrCompileTimeChecker, null) ?: true) }
}
private fun IrCall.isGetterToConstVal(): Boolean {
return symbol.owner.correspondingPropertySymbol?.owner?.isConst == true
}
override fun visitCall(expression: IrCall, data: Nothing?): Boolean {
val owner = expression.symbol.owner
if (!mode.canEvaluateFunction(owner, expression)) return false
@@ -78,6 +82,10 @@ class IrCompileTimeChecker(
}
return expression.saveContext {
if (expression.dispatchReceiver.isAccessToNotNullableObject()) {
return@saveContext expression.isGetterToConstVal()
}
val dispatchReceiverComputable = expression.dispatchReceiver?.accept(this, null) ?: true
val extensionReceiverComputable = expression.extensionReceiver?.accept(this, null) ?: true
if (!visitValueArguments(expression, null)) return@saveContext false
@@ -177,7 +185,7 @@ class IrCompileTimeChecker(
}
override fun visitGetValue(expression: IrGetValue, data: Nothing?): Boolean {
return visitedStack.contains(expression.symbol.owner.parent) || expression.isAccessToNotNullableObject()
return visitedStack.contains(expression.symbol.owner.parent)
}
override fun visitSetValue(expression: IrSetValue, data: Nothing?): Boolean {
@@ -199,7 +207,8 @@ class IrCompileTimeChecker(
isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true
expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, null) == true
owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> {
val receiverComputable = expression.receiver?.accept(this, null) ?: true
val receiverComputable = (expression.receiver?.accept(this, null) ?: true)
|| expression.isAccessToNotNullableObject()
val initializerComputable = owner.initializer?.accept(this, null) ?: false
receiverComputable && initializerComputable
}