FIR2IR: handle unbound reference with adapted arguments
This commit is contained in:
committed by
Mikhail Glukhikh
parent
a26eeb6ee8
commit
1b6c4329d2
+18
-4
@@ -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
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user