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
|
val boundReceiver = boundDispatchReceiver ?: boundExtensionReceiver
|
||||||
if (boundReceiver == null) {
|
if (boundReceiver == null) {
|
||||||
IrFunctionExpressionImpl(startOffset, endOffset, type, irAdapterFunction, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE)
|
IrFunctionExpressionImpl(startOffset, endOffset, type, irAdapterFunction, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE)
|
||||||
@@ -306,6 +305,7 @@ class CallAndReferenceGenerator(
|
|||||||
error("unknown callee kind: ${adapteeFunction.render()}")
|
error("unknown callee kind: ${adapteeFunction.render()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var shift = 0
|
||||||
if (boundDispatchReceiver != null || boundExtensionReceiver != null) {
|
if (boundDispatchReceiver != null || boundExtensionReceiver != null) {
|
||||||
val receiverValue = IrGetValueImpl(
|
val receiverValue = IrGetValueImpl(
|
||||||
startOffset, endOffset, adapterFunction.extensionReceiverParameter!!.symbol, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE
|
startOffset, endOffset, adapterFunction.extensionReceiverParameter!!.symbol, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE
|
||||||
@@ -314,20 +314,34 @@ class CallAndReferenceGenerator(
|
|||||||
boundDispatchReceiver != null -> irCall.dispatchReceiver = receiverValue
|
boundDispatchReceiver != null -> irCall.dispatchReceiver = receiverValue
|
||||||
boundExtensionReceiver != null -> irCall.extensionReceiver = 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 ->
|
adapteeFunction.valueParameters.mapIndexed { index, valueParameter ->
|
||||||
when {
|
when {
|
||||||
valueParameter.hasDefaultValue() -> {
|
valueParameter.hasDefaultValue() -> {
|
||||||
irCall.putValueArgument(index, null)
|
irCall.putValueArgument(shift + index, null)
|
||||||
}
|
}
|
||||||
valueParameter.isVararg -> {
|
valueParameter.isVararg -> {
|
||||||
// TODO: handle vararg and spread
|
// TODO: handle vararg and spread
|
||||||
irCall.putValueArgument(index, null)
|
irCall.putValueArgument(shift + index, null)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val irValueArgument = adapterFunction.valueParameters[index]
|
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, JS_IR, NATIVE
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND: JS_IR_ES6
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
|
|
||||||
fun checkEqual(x: Any, y: Any) {
|
fun checkEqual(x: Any, y: Any) {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_REFLECT
|
// 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
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL 'public open fun foo (vararg xs: kotlin.Int): kotlin.Int declared in <root>.A' type=kotlin.Int origin=null
|
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
|
FUN name:testBound visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Unit
|
||||||
VALUE_PARAMETER name:a index:0 type:<root>.A
|
VALUE_PARAMETER name:a index:0 type:<root>.A
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
|
|||||||
Reference in New Issue
Block a user