FIR2IR: handle unbound reference with adapted arguments

This commit is contained in:
Jinseong Jeon
2020-08-05 11:30:26 -07:00
committed by Mikhail Glukhikh
parent a26eeb6ee8
commit 1b6c4329d2
4 changed files with 19 additions and 6 deletions
@@ -166,7 +166,6 @@ class CallAndReferenceGenerator(
}
}
// TODO: handle transient receiver, such as class symbol, like A::foo
val boundReceiver = boundDispatchReceiver ?: boundExtensionReceiver
if (boundReceiver == null) {
IrFunctionExpressionImpl(startOffset, endOffset, type, irAdapterFunction, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE)
@@ -306,6 +305,7 @@ class CallAndReferenceGenerator(
error("unknown callee kind: ${adapteeFunction.render()}")
}
var shift = 0
if (boundDispatchReceiver != null || boundExtensionReceiver != null) {
val receiverValue = IrGetValueImpl(
startOffset, endOffset, adapterFunction.extensionReceiverParameter!!.symbol, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE
@@ -314,20 +314,34 @@ class CallAndReferenceGenerator(
boundDispatchReceiver != null -> irCall.dispatchReceiver = receiverValue
boundExtensionReceiver != null -> irCall.extensionReceiver = receiverValue
}
} else if (callableReferenceAccess.explicitReceiver is FirResolvedQualifier) {
// Unbound callable reference 'A::foo'
val adaptedReceiverParameter = adapterFunction.valueParameters[0]
val adaptedReceiverValue = IrGetValueImpl(
startOffset, endOffset, adaptedReceiverParameter.type, adaptedReceiverParameter.symbol
)
if (adapteeFunction.extensionReceiverParameter != null) {
irCall.extensionReceiver = adaptedReceiverValue
shift = 1
} else {
irCall.dispatchReceiver = adaptedReceiverValue
}
}
adapteeFunction.valueParameters.mapIndexed { index, valueParameter ->
when {
valueParameter.hasDefaultValue() -> {
irCall.putValueArgument(index, null)
irCall.putValueArgument(shift + index, null)
}
valueParameter.isVararg -> {
// TODO: handle vararg and spread
irCall.putValueArgument(index, null)
irCall.putValueArgument(shift + index, null)
}
else -> {
val irValueArgument = adapterFunction.valueParameters[index]
irCall.putValueArgument(index, IrGetValueImpl(startOffset, endOffset, irValueArgument.type, irValueArgument.symbol))
irCall.putValueArgument(
shift + index, IrGetValueImpl(startOffset, endOffset, irValueArgument.type, irValueArgument.symbol)
)
}
}
}
@@ -1,6 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: test.kt
fun checkEqual(x: Any, y: Any) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_REFLECT
@@ -66,6 +66,7 @@ FILE fqName:<root> fileName:/unboundMemberReferenceWithAdaptedArguments.kt
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
BLOCK_BODY
CALL 'public open fun foo (vararg xs: kotlin.Int): kotlin.Int declared in <root>.A' type=kotlin.Int origin=null
$this: GET_VAR 'p0: <root>.A declared in <root>.testUnbound.foo' type=<root>.A origin=null
FUN name:testBound visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:<root>.A
BLOCK_BODY