Move type operations in DeepCopyIrTreeWithDescriptors
This commit is contained in:
committed by
KonstantinAnisimov
parent
276c14a896
commit
c7de1d452f
+63
-2
@@ -43,12 +43,15 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val typeSubstitutor: TypeSubstitutor?, val context: Context) {
|
||||
internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typeArgsMap: Map <TypeParameterDescriptor, KotlinType>?, val context: Context) {
|
||||
|
||||
private val descriptorSubstituteMap: MutableMap<DeclarationDescriptor, DeclarationDescriptor> = mutableMapOf()
|
||||
private var typeSubstitutor = createTypeSubstitutor(typeArgsMap)
|
||||
private var inlinedFunctionName = ""
|
||||
private var nameIndex = 0
|
||||
|
||||
@@ -425,6 +428,51 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
return newDeclaration
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
fun getTypeOperatorReturnType(operator: IrTypeOperator, type: KotlinType) : KotlinType {
|
||||
return when (operator) {
|
||||
IrTypeOperator.CAST,
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> type
|
||||
IrTypeOperator.SAFE_CAST -> type.makeNullable()
|
||||
IrTypeOperator.INSTANCEOF,
|
||||
IrTypeOperator.NOT_INSTANCEOF -> context.builtIns.booleanType
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
|
||||
|
||||
val oldExpression = super.visitTypeOperator(expression) as IrTypeOperatorCall
|
||||
if (typeArgsMap == null) return oldExpression
|
||||
|
||||
if (oldExpression.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) { // Nothing to do for IMPLICIT_COERCION_TO_UNIT
|
||||
return oldExpression
|
||||
}
|
||||
|
||||
val typeOperand = oldExpression.typeOperand
|
||||
val operandTypeDescriptor = typeOperand.constructor.declarationDescriptor
|
||||
if (operandTypeDescriptor !is TypeParameterDescriptor) return oldExpression // It is not TypeParameter - do nothing
|
||||
|
||||
var newType = typeArgsMap[operandTypeDescriptor] ?: return expression
|
||||
if (typeOperand.isMarkedNullable) newType = newType.makeNullable()
|
||||
val operator = oldExpression.operator
|
||||
val returnType = getTypeOperatorReturnType(operator, newType)
|
||||
|
||||
return IrTypeOperatorCallImpl(
|
||||
oldExpression.startOffset,
|
||||
oldExpression.endOffset,
|
||||
returnType,
|
||||
oldExpression.operator,
|
||||
newType,
|
||||
oldExpression.argument
|
||||
)
|
||||
}
|
||||
|
||||
//--- Copy declarations -----------------------------------------------//
|
||||
|
||||
private fun copyIrFunctionImpl(oldDeclaration: IrFunction, newDescriptor: DeclarationDescriptor): IrFunction {
|
||||
@@ -449,7 +497,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
private fun substituteType(oldType: KotlinType?): KotlinType? {
|
||||
if (typeSubstitutor == null) return oldType
|
||||
if (oldType == null) return oldType
|
||||
return typeSubstitutor.substitute(oldType, Variance.INVARIANT) ?: oldType
|
||||
return typeSubstitutor!!.substitute(oldType, Variance.INVARIANT) ?: oldType
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
@@ -467,6 +515,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
}
|
||||
return newTypeArguments
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun copyValueParameters(oldValueParameters: List <ValueParameterDescriptor>, containingDeclaration: CallableDescriptor): List <ValueParameterDescriptor> {
|
||||
@@ -489,4 +538,16 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
newDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun createTypeSubstitutor(typeArgsMap: Map <TypeParameterDescriptor, KotlinType>?): TypeSubstitutor? {
|
||||
|
||||
if (typeArgsMap == null) return null
|
||||
val substitutionContext = typeArgsMap.entries.associate {
|
||||
(typeParameter, typeArgument) ->
|
||||
typeParameter.typeConstructor to TypeProjectionImpl(typeArgument)
|
||||
}
|
||||
return TypeSubstitutor.create(substitutionContext)
|
||||
}
|
||||
}
|
||||
+6
-104
@@ -185,14 +185,13 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun createInlineFunctionBody(functionDeclaration: IrFunction): IrInlineFunctionBody? {
|
||||
functionDeclaration.transformChildrenVoid(this) // Inline recursively.
|
||||
private fun createInlineFunctionBody(functionDeclaration: IrFunction, typeArgsMap: Map <TypeParameterDescriptor, KotlinType>?): IrInlineFunctionBody? {
|
||||
functionDeclaration.transformChildrenVoid(this) // TODO recursive inline is already processed in visitCall. Check
|
||||
|
||||
val originBlockBody = functionDeclaration.body
|
||||
if (originBlockBody == null) return null // TODO workaround
|
||||
|
||||
val typeSubstitutor = createTypeSubstitutor(typeArgsMap)
|
||||
copyWithDescriptors = DeepCopyIrTreeWithDescriptors(currentFunction!!, typeSubstitutor, context)
|
||||
copyWithDescriptors = DeepCopyIrTreeWithDescriptors(currentFunction!!, typeArgsMap, context)
|
||||
val functionName = functionDeclaration.descriptor.name.toString()
|
||||
|
||||
val copyBlockBody = originBlockBody.accept(InlineCopyIr(), null) as IrBlockBody // Create copy of original function body.
|
||||
@@ -225,7 +224,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
val lambdaInliner = LambdaInliner(parameterToArgument)
|
||||
inlineBody.transformChildrenVoid(lambdaInliner)
|
||||
|
||||
val transformer = ParametersTransformer(parameterToArgument, typeArgsMap, evaluationStatements)
|
||||
val transformer = ParametersTransformer(parameterToArgument)
|
||||
inlineBody.transformChildrenVoid(transformer) // Replace parameters with expression.
|
||||
inlineBody.statements.addAll(0, evaluationStatements)
|
||||
|
||||
@@ -234,56 +233,12 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private inner class ParametersTransformer(val substituteMap: MutableMap <ValueDescriptor, IrExpression>,
|
||||
val typeArgsMap: Map <TypeParameterDescriptor, KotlinType>?,
|
||||
val statements: MutableList<IrStatement>): IrElementTransformerVoid() {
|
||||
private inner class ParametersTransformer(val substituteMap: MutableMap <ValueDescriptor, IrExpression>): IrElementTransformerVoid() {
|
||||
|
||||
override fun visitElement(element: IrElement) = element.accept(this, null)
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
fun getTypeOperatorReturnType(operator: IrTypeOperator, type: KotlinType) : KotlinType {
|
||||
return when (operator) {
|
||||
IrTypeOperator.CAST,
|
||||
IrTypeOperator.IMPLICIT_CAST,
|
||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> type
|
||||
IrTypeOperator.SAFE_CAST -> type.makeNullable()
|
||||
IrTypeOperator.INSTANCEOF,
|
||||
IrTypeOperator.NOT_INSTANCEOF -> context.builtIns.booleanType
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
|
||||
|
||||
val newExpression = super.visitTypeOperator(expression) as IrTypeOperatorCall
|
||||
if (typeArgsMap == null) return newExpression
|
||||
|
||||
if (newExpression.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) { // Nothing to do for IMPLICIT_COERCION_TO_UNIT
|
||||
return newExpression
|
||||
}
|
||||
|
||||
val operandTypeDescriptor = newExpression.typeOperand.constructor.declarationDescriptor
|
||||
if (operandTypeDescriptor !is TypeParameterDescriptor) return newExpression // It is not TypeParameter - do nothing
|
||||
|
||||
var typeNew = typeArgsMap[operandTypeDescriptor]
|
||||
?: return expression
|
||||
if (newExpression.typeOperand.isMarkedNullable)
|
||||
typeNew = typeNew.makeNullable()
|
||||
val startOffset = newExpression.startOffset
|
||||
val endOffset = newExpression.endOffset
|
||||
val operator = newExpression.operator
|
||||
val argument = newExpression.argument
|
||||
val type = getTypeOperatorReturnType(operator, typeNew)
|
||||
|
||||
return IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeNew, argument)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
|
||||
val newExpression = super.visitGetValue(expression) as IrGetValue
|
||||
@@ -293,59 +248,6 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
|
||||
return argument
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun createTypeSubstitutor(): TypeSubstitutor {
|
||||
|
||||
val substitutionContext = typeArgsMap!!.entries.associate {
|
||||
(typeParameter, typeArgument) ->
|
||||
typeParameter.typeConstructor to TypeProjectionImpl(typeArgument)
|
||||
}
|
||||
return TypeSubstitutor.create(substitutionContext)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun substituteTypeArguments(irCall: IrCall, typeSubstitutor: TypeSubstitutor): Map <TypeParameterDescriptor, KotlinType>? {
|
||||
|
||||
val oldTypeArguments = (irCall as IrMemberAccessExpressionBase).typeArguments
|
||||
if (oldTypeArguments == null) return null
|
||||
|
||||
val newTypeArguments = oldTypeArguments.map {
|
||||
val typeParameterDescriptor = it.key
|
||||
val oldTypeArgument = it.value
|
||||
val newTypeArgument = typeSubstitutor.substitute(oldTypeArgument, Variance.INVARIANT) ?: oldTypeArgument
|
||||
typeParameterDescriptor to newTypeArgument
|
||||
}.toMap()
|
||||
|
||||
return newTypeArguments
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
|
||||
val irCall = super.visitCall(expression) as IrCall
|
||||
if (irCall !is IrCallImpl) return irCall
|
||||
if (typeArgsMap == null) return irCall
|
||||
|
||||
val typeSubstitutor = createTypeSubstitutor()
|
||||
val typeArguments = substituteTypeArguments(irCall, typeSubstitutor)
|
||||
val returnType = typeSubstitutor.substitute(irCall.type, Variance.INVARIANT) ?: irCall.type
|
||||
val descriptor = irCall.descriptor.substitute(typeSubstitutor)!!
|
||||
val superQualifier = irCall.superQualifier?.substitute(typeSubstitutor)
|
||||
|
||||
return IrCallImpl(irCall.startOffset, irCall.endOffset, returnType, descriptor,
|
||||
typeArguments, irCall.origin, superQualifier).apply {
|
||||
irCall.descriptor.valueParameters.forEach {
|
||||
val valueArgument = irCall.getValueArgument(it)
|
||||
putValueArgument(it.index, valueArgument)
|
||||
}
|
||||
extensionReceiver = irCall.extensionReceiver
|
||||
dispatchReceiver = irCall.dispatchReceiver
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -438,7 +340,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
val lambdaReturnType = copyLambdaFunction.descriptor.returnType!!
|
||||
val inlineBody = IrInlineFunctionBody(0, 0, lambdaReturnType, lambdaFunction.descriptor, null, lambdaStatements)
|
||||
|
||||
val transformer = ParametersTransformer(parameterToArgument, null, lambdaStatements)
|
||||
val transformer = ParametersTransformer(parameterToArgument)
|
||||
inlineBody.accept(transformer, null) // Replace parameters with expression.
|
||||
inlineBody.statements.addAll(0, evaluationStatements)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user