getArguments now work with original descriptor

Extension receiver is included in parameter -> argument substitution for lambda
This commit is contained in:
Konstantin Anisimov
2017-03-16 16:39:15 +07:00
committed by KonstantinAnisimov
parent 1e5d34bc85
commit 0ba37d9ac0
@@ -4,6 +4,7 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueDescriptor import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
@@ -93,9 +94,33 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
fun getArguments(irCall: IrCall): List<Pair<ParameterDescriptor, IrExpression>> {
val result = mutableListOf<Pair<ParameterDescriptor, IrExpression>>()
val descriptor = irCall.descriptor.original
irCall.dispatchReceiver?.let {
result += (descriptor.dispatchReceiverParameter!! to it)
}
irCall.extensionReceiver?.let {
result += (descriptor.extensionReceiverParameter!! to it)
}
descriptor.valueParameters.forEach {
val arg = irCall.getValueArgument(it.index)
if (arg != null) {
result += (it to arg)
}
}
return result
}
//-------------------------------------------------------------------------//
fun evaluateParameters(irCall: IrCall, statements: MutableList<IrStatement>): MutableMap<ValueDescriptor, IrExpression> { fun evaluateParameters(irCall: IrCall, statements: MutableList<IrStatement>): MutableMap<ValueDescriptor, IrExpression> {
val parametersOld = irCall.getArguments() // Create map call_site_argument -> inline_function_parameter. val parametersOld = getArguments(irCall) // Create map call_site_argument -> inline_function_parameter.
val parametersNew = mutableMapOf<ValueDescriptor, IrExpression> () val parametersNew = mutableMapOf<ValueDescriptor, IrExpression> ()
parametersOld.forEach { parametersOld.forEach {
@@ -161,24 +186,24 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
override fun visitTypeOperator(oldExpression: IrTypeOperatorCall): IrExpression { override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
val expression = super.visitTypeOperator(oldExpression) as IrTypeOperatorCall val newExpression = super.visitTypeOperator(expression) as IrTypeOperatorCall
if (expression.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) { // Nothing to do for IMPLICIT_COERCION_TO_UNIT if (newExpression.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) { // Nothing to do for IMPLICIT_COERCION_TO_UNIT
return expression return newExpression
} }
if (typeArgsMap == null) return expression if (typeArgsMap == null) return newExpression
val operandTypeDescriptor = expression.typeOperand.constructor.declarationDescriptor val operandTypeDescriptor = newExpression.typeOperand.constructor.declarationDescriptor
if (operandTypeDescriptor !is TypeParameterDescriptor) return expression // It is not TypeParameter - do nothing if (operandTypeDescriptor !is TypeParameterDescriptor) return newExpression // It is not TypeParameter - do nothing
val typeNew = typeArgsMap[operandTypeDescriptor]!! val typeNew = typeArgsMap[operandTypeDescriptor]!!
val startOffset = expression.startOffset val startOffset = newExpression.startOffset
val endOffset = expression.endOffset val endOffset = newExpression.endOffset
val type = expression.type // TODO val type = newExpression.type // TODO
val operator = expression.operator val operator = newExpression.operator
val argument = expression.argument val argument = newExpression.argument
return IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeNew, argument) return IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeNew, argument)
} }
@@ -261,8 +286,16 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
fun buildParameterToArgument(lambdaFunction: IrFunction, irCall: IrCall): MutableMap<ValueDescriptor, IrExpression> { fun buildParameterToArgument(lambdaFunction: IrFunction, irCall: IrCall): MutableMap<ValueDescriptor, IrExpression> {
val parameters = lambdaFunction.descriptor.valueParameters // Get lambda function parameters. val descriptor = lambdaFunction.descriptor
val parameterToArgument = mutableMapOf<ValueDescriptor, IrExpression>() val parameterToArgument = mutableMapOf<ValueDescriptor, IrExpression>()
irCall.extensionReceiver?.let {
val parameter = descriptor.extensionReceiverParameter!!
val argument = it
parameterToArgument[parameter] = argument
}
val parameters = descriptor.valueParameters // Get lambda function parameters.
parameters.forEach { // Iterate parameters. parameters.forEach { // Iterate parameters.
val parameter = it val parameter = it
val argument = irCall.getValueArgument(it.index) // Get corresponding argument. val argument = irCall.getValueArgument(it.index) // Get corresponding argument.