[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:
@@ -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
|
||||
|
||||
+11
-2
@@ -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
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ fun ObjectWithExtension?.nullableExtensionFun(): String =
|
||||
"Not null"
|
||||
|
||||
fun ObjectWithExtension.extensionFun(): String =
|
||||
if(<!EVALUATED("false")!>this == null<!>)
|
||||
"Null" // unreachable branch, will be optimized by interpreter
|
||||
if(this == null)
|
||||
"Null"
|
||||
else
|
||||
"Not null"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
object Test {
|
||||
fun foo(): String = "foo " + this
|
||||
|
||||
fun bar(): String = "bar $this"
|
||||
fun bar(): String = "<!EVALUATED("bar ")!>bar <!>$this"
|
||||
|
||||
fun baz(): String = "baz " + this.toString()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user