KT-56154 Fix PropertyReferenceLowering for Java synthetic properties

Co-authored-by: Alexander Udalov <Alexander.Udalov@jetbrains.com>
This commit is contained in:
Pavel Mikhailovskii
2023-01-28 10:38:09 +00:00
committed by Space Team
parent debbfa8397
commit f308f33f9f
4 changed files with 49 additions and 7 deletions
@@ -49597,6 +49597,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/syntheticExtensions/implicitReceiver.kt");
}
@Test
@TestMetadata("kt56154.kt")
public void testKt56154() throws Exception {
runTest("compiler/testData/codegen/box/syntheticExtensions/kt56154.kt");
}
@Test
@TestMetadata("overrideKotlinPropertyByJavaMethod.kt")
public void testOverrideKotlinPropertyByJavaMethod() throws Exception {
@@ -352,15 +352,18 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle
call.putValueArgument(index++, computeSignatureString(expression))
if (useOptimizedSuperClass) {
val isPackage = (container is IrClass && container.isFileClass) || container is IrPackageFragment
val isJavaSynthetic = (expression.symbol.owner as? IrProperty)?.let {
it.backingField == null &&
(it.origin == IrDeclarationOrigin.SYNTHETIC_JAVA_PROPERTY_DELEGATE
|| it.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB)
} ?: false
call.putValueArgument(index, irInt((if (isPackage) 1 else 0) or (if (isJavaSynthetic) 2 else 0)))
call.putValueArgument(index, irInt((if (isPackage) 1 else 0) or (if (expression.isJavaSyntheticPropertyReference) 2 else 0)))
}
}
private val IrCallableReference<*>.isJavaSyntheticPropertyReference: Boolean
get() =
symbol.owner.let {
it is IrProperty && it.backingField == null &&
(it.origin == IrDeclarationOrigin.SYNTHETIC_JAVA_PROPERTY_DELEGATE
|| it.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB)
}
// Create an instance of KProperty that overrides the get() and set() methods to directly call getX() and setX() on the object.
// This is (relatively) fast, but space-inefficient. Also, the instances can store bound receivers in their fields. Example:
//
@@ -419,7 +422,11 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle
if (field == null) {
fun IrBuilderWithScope.setCallArguments(call: IrCall, arguments: List<IrValueParameter>) {
val receiverFromField = boundReceiver?.let { irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type) }
call.copyTypeArgumentsFrom(expression)
if (expression.isJavaSyntheticPropertyReference) {
assert(call.typeArgumentsCount == 0) { "Unexpected type arguments: ${call.typeArgumentsCount}" }
} else {
call.copyTypeArgumentsFrom(expression)
}
call.dispatchReceiver = call.symbol.owner.dispatchReceiverParameter?.let {
receiverFromField ?: irImplicitCast(irGet(arguments[1]), expression.receiverType)
}
@@ -0,0 +1,23 @@
// TARGET_BACKEND: JVM_IR
// !LANGUAGE: +ReferencesToSyntheticJavaProperties
// FILE: Generic.java
public class Generic<T> {
public String getStringVal() { return null; }
public void setStringVal(String value) {}
public T getGenericVal() { return null; }
public void setGenericVal(T value) {}
}
// FILE: main.kt
fun box(): String {
Generic<Number>::stringVal
Generic<Number>::genericVal
val o = Generic<Number>()
o::stringVal
o::genericVal
return "OK"
}
@@ -49597,6 +49597,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/syntheticExtensions/implicitReceiver.kt");
}
@Test
@TestMetadata("kt56154.kt")
public void testKt56154() throws Exception {
runTest("compiler/testData/codegen/box/syntheticExtensions/kt56154.kt");
}
@Test
@TestMetadata("overrideKotlinPropertyByJavaMethod.kt")
public void testOverrideKotlinPropertyByJavaMethod() throws Exception {