Fix optimization of property delegates of platform types

The old code didn't replace the delegate field access because it was
wrapped into a TYPE_OP IMPLICIT_NOTNULL.

 #KT-54463 Fixed
This commit is contained in:
Alexander Udalov
2022-10-18 15:00:54 +02:00
committed by Space Team
parent ac74ce5f27
commit 8812f632cc
6 changed files with 51 additions and 17 deletions
@@ -15016,6 +15016,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/initializeContainerOfTopLevelProperties.kt");
}
@Test
@TestMetadata("kt54463_platformType.kt")
public void testKt54463_platformType() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/kt54463_platformType.kt");
}
@Test
@TestMetadata("memberExtensionPropertyAndImportFromObject.kt")
public void testMemberExtensionPropertyAndImportFromObject() throws Exception {
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions
internal val singletonOrConstantDelegationPhase = makeIrFilePhase(
::SingletonOrConstantDelegationLowering,
@@ -47,22 +44,14 @@ private class SingletonOrConstantDelegationTransformer(val context: JvmBackendCo
if (!isDelegated || isFakeOverride || backingField == null) return null
val delegate = backingField?.initializer?.expression?.takeIf { it.isInlineable() } ?: return null
val originalThis = parentAsClass.thisReceiver
val receiverMapper = object : IrElementTransformer<Pair<Name, IrExpression>> {
override fun visitCall(expression: IrCall, data: Pair<Name, IrExpression>): IrExpression {
val (name, newReceiver) = data
if (expression.symbol.owner.name == name) {
if ((expression.dispatchReceiver as? IrGetField)?.symbol == backingField?.symbol) {
expression.dispatchReceiver = newReceiver
} else if ((expression.extensionReceiver as? IrGetField)?.symbol == backingField?.symbol) {
expression.extensionReceiver = newReceiver
}
}
return expression
}
class DelegateFieldAccessTransformer(val newReceiver: IrExpression) : IrElementTransformerVoid() {
override fun visitGetField(expression: IrGetField): IrExpression =
if (expression.symbol == backingField?.symbol) newReceiver else super.visitGetField(expression)
}
getter?.transform(receiverMapper,OperatorNameConventions.GET_VALUE to delegate.remapReceiver(originalThis, getter?.dispatchReceiverParameter))
setter?.transform(receiverMapper,OperatorNameConventions.SET_VALUE to delegate.remapReceiver(originalThis, setter?.dispatchReceiverParameter))
getter?.transform(DelegateFieldAccessTransformer(delegate.remapReceiver(originalThis, getter?.dispatchReceiverParameter)), null)
setter?.transform(DelegateFieldAccessTransformer(delegate.remapReceiver(originalThis, setter?.dispatchReceiverParameter)), null)
backingField = null
@@ -0,0 +1,22 @@
// TARGET_BACKEND: JVM
// FILE: A.java
public class A {
public static A create() { return new A(); }
}
// FILE: box.kt
import kotlin.reflect.KProperty
class C {
private val valueState = A.create()
private val value by valueState
fun get(): String = value
}
operator fun A.getValue(thisRef: Any?, property: KProperty<*>): String = "OK"
fun box(): String =
C().get()
@@ -14782,6 +14782,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/initializeContainerOfTopLevelProperties.kt");
}
@Test
@TestMetadata("kt54463_platformType.kt")
public void testKt54463_platformType() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/kt54463_platformType.kt");
}
@Test
@TestMetadata("memberExtensionPropertyAndImportFromObject.kt")
public void testMemberExtensionPropertyAndImportFromObject() throws Exception {
@@ -15016,6 +15016,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/initializeContainerOfTopLevelProperties.kt");
}
@Test
@TestMetadata("kt54463_platformType.kt")
public void testKt54463_platformType() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/kt54463_platformType.kt");
}
@Test
@TestMetadata("memberExtensionPropertyAndImportFromObject.kt")
public void testMemberExtensionPropertyAndImportFromObject() throws Exception {
@@ -12091,6 +12091,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/initializeContainerOfTopLevelProperties.kt");
}
@TestMetadata("kt54463_platformType.kt")
public void testKt54463_platformType() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/kt54463_platformType.kt");
}
@TestMetadata("memberExtensionPropertyAndImportFromObject.kt")
public void testMemberExtensionPropertyAndImportFromObject() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/delegateToFinalProperty/memberExtensionPropertyAndImportFromObject.kt");