JVM_IR: handle property references in SAM conversions

This commit is contained in:
Georgy Bronnikov
2019-10-03 13:52:46 +03:00
parent 74c9120d9d
commit cd78e6ec50
6 changed files with 47 additions and 1 deletions
@@ -316,6 +316,13 @@ class JvmSymbols(
}
}
// invoke redirects to get
klass.addFunction("invoke", irBuiltIns.anyNType, Modality.FINAL).apply {
for (i in 0 until n) {
addValueParameter("receiver$i", irBuiltIns.anyNType)
}
}
if (mutable) {
klass.addFunction("set", irBuiltIns.unitType, Modality.ABSTRACT).apply {
for (i in 0 until n) {
@@ -137,4 +137,4 @@ fun JvmBackendContext.createJvmIrBuilder(
fun IrDeclaration.isInCurrentModule(): Boolean =
getPackageFragment() is IrFile
getPackageFragment() is IrFile
@@ -113,6 +113,19 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
}
}
private fun IrClass.addFakeOverride(method: IrSimpleFunction) =
addFunction {
name = method.name
returnType = method.returnType
visibility = method.visibility
origin = IrDeclarationOrigin.FAKE_OVERRIDE
}.apply {
overriddenSymbols.add(method.symbol)
dispatchReceiverParameter = thisReceiver!!.copyTo(this)
for (parameter in method.valueParameters)
valueParameters.add(parameter.copyTo(this))
}
private class PropertyReferenceKind(
val interfaceSymbol: IrClassSymbol,
val reflectedSymbol: IrClassSymbol,
@@ -246,6 +259,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
val getSignature = superClass.functions.single { it.name.asString() == "getSignature" }
val get = superClass.functions.find { it.name.asString() == "get" }
val set = superClass.functions.find { it.name.asString() == "set" }
val invoke = superClass.functions.find { it.name.asString() == "invoke" }
referenceClass.addSimpleDelegatingConstructor(superConstructor, context.irBuiltIns, isPrimary = true)
referenceClass.addOverride(getName) { irString(expression.descriptor.name.asString()) }
@@ -277,6 +291,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
setCallArguments(this, arguments)
}
}
referenceClass.addFakeOverride(invoke!!)
}
expression.setter?.owner?.let { setter ->
@@ -0,0 +1,14 @@
// FILE: Base.java
interface Interface {
String call(String t);
}
// FILE: 1.kt
val String.property: String
get() = this
fun box(): String {
return Interface(String::property).call("OK")
}
@@ -675,6 +675,11 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga
runTest("compiler/testData/codegen/boxAgainstJava/sam/kt4753_2.kt");
}
@TestMetadata("propertyReference.kt")
public void testPropertyReference() throws Exception {
runTest("compiler/testData/codegen/boxAgainstJava/sam/propertyReference.kt");
}
@TestMetadata("samConstructorGenericSignature.kt")
public void testSamConstructorGenericSignature() throws Exception {
runTest("compiler/testData/codegen/boxAgainstJava/sam/samConstructorGenericSignature.kt");
@@ -676,6 +676,11 @@ public class IrBlackBoxAgainstJavaCodegenTestGenerated extends AbstractIrBlackBo
runTest("compiler/testData/codegen/boxAgainstJava/sam/kt4753_2.kt");
}
@TestMetadata("propertyReference.kt")
public void testPropertyReference() throws Exception {
runTest("compiler/testData/codegen/boxAgainstJava/sam/propertyReference.kt");
}
@TestMetadata("samConstructorGenericSignature.kt")
public void testSamConstructorGenericSignature() throws Exception {
runTest("compiler/testData/codegen/boxAgainstJava/sam/samConstructorGenericSignature.kt");