Type substitution relocated in DeepCopyIrWithDescriptors
This commit is contained in:
committed by
KonstantinAnisimov
parent
ee3e408dcb
commit
2381e453d8
+209
-82
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.lower.SimpleMemberScope
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
@@ -28,9 +29,12 @@ import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -38,8 +42,12 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val context: Context) {
|
||||
internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val typeSubstitutor: TypeSubstitutor?, val context: Context) {
|
||||
|
||||
private val descriptorSubstituteMap: MutableMap<DeclarationDescriptor, DeclarationDescriptor> = mutableMapOf()
|
||||
private var inlinedFunctionName = ""
|
||||
@@ -48,6 +56,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun copy(irElement: IrElement, functionName: String) {
|
||||
|
||||
inlinedFunctionName = functionName
|
||||
descriptorSubstituteMap.clear()
|
||||
irElement.acceptChildrenVoid(descriptorCollector)
|
||||
@@ -58,30 +67,16 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
|
||||
private val descriptorCollector = object : IrElementVisitorVoid {
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildren(this, null)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitFunction(declaration: IrFunction) {
|
||||
val oldDescriptor = declaration.descriptor
|
||||
val newDescriptor = copyFunctionDescriptor(oldDescriptor)
|
||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||
super.visitFunction(declaration)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
|
||||
val oldDescriptor = declaration.descriptor
|
||||
val newDescriptor = copyClassDescriptor(oldDescriptor)
|
||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||
descriptorSubstituteMap[oldDescriptor.thisAsReceiverParameter] = newDescriptor.thisAsReceiverParameter
|
||||
super.visitClass(declaration)
|
||||
|
||||
val constructors = oldDescriptor.constructors.map {
|
||||
descriptorSubstituteMap[it] as ClassConstructorDescriptor
|
||||
val constructors = oldDescriptor.constructors.map { oldConstructorDescriptor ->
|
||||
descriptorSubstituteMap[oldConstructorDescriptor] as ClassConstructorDescriptor
|
||||
}.toSet()
|
||||
|
||||
var primaryConstructor: ClassConstructorDescriptor? = null
|
||||
@@ -104,9 +99,60 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitFunction(declaration: IrFunction) {
|
||||
|
||||
val oldDescriptor = declaration.descriptor
|
||||
val newDescriptor = copyFunctionDescriptor(oldDescriptor)
|
||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||
super.visitFunction(declaration)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitCall(expression: IrCall) {
|
||||
|
||||
val descriptor = expression.descriptor as FunctionDescriptor
|
||||
if (descriptor.isFunctionInvoke) {
|
||||
val oldDescriptor = descriptor as SimpleFunctionDescriptor
|
||||
val containingDeclaration = targetFunction.descriptor
|
||||
val newReturnType = substituteType(oldDescriptor.returnType)!!
|
||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, containingDeclaration)
|
||||
val newDescriptor = oldDescriptor.newCopyBuilder().apply {
|
||||
setReturnType(newReturnType)
|
||||
setValueParameters(newValueParameters)
|
||||
}.build()
|
||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor!!
|
||||
}
|
||||
|
||||
super.visitCall(expression)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitVariable(declaration: IrVariable) {
|
||||
|
||||
val oldDescriptor = declaration.descriptor
|
||||
val newDescriptor = IrTemporaryVariableDescriptorImpl(
|
||||
targetFunction.descriptor,
|
||||
generateName(oldDescriptor.name),
|
||||
substituteType(oldDescriptor.type)!!,
|
||||
oldDescriptor.isVar)
|
||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||
super.visitVariable(declaration)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildren(this, null)
|
||||
}
|
||||
|
||||
//--- Copy descriptors ------------------------------------------------//
|
||||
|
||||
private fun generateName(name: Name): Name {
|
||||
|
||||
val containingName = targetFunction.descriptor.name.toString() // Name of inline target (function we inline in)
|
||||
val declarationName = name.toString() // Name of declaration
|
||||
val indexStr = (nameIndex++).toString() // Unique for inline target index
|
||||
@@ -115,33 +161,11 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun copyValueParameters(oldValueParameters: List <ValueParameterDescriptor>, owner: CallableDescriptor): List <ValueParameterDescriptor> {
|
||||
return oldValueParameters.map { oldDescriptor ->
|
||||
val newDescriptor = ValueParameterDescriptorImpl(
|
||||
owner,
|
||||
oldDescriptor.original,
|
||||
oldDescriptor.index,
|
||||
oldDescriptor.annotations,
|
||||
oldDescriptor.name,
|
||||
oldDescriptor.type,
|
||||
oldDescriptor.declaresDefaultValue(),
|
||||
oldDescriptor.isCrossinline,
|
||||
oldDescriptor.isNoinline,
|
||||
oldDescriptor.varargElementType,
|
||||
oldDescriptor.source
|
||||
)
|
||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||
newDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun copyFunctionDescriptor(oldDescriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
private fun copyFunctionDescriptor(oldDescriptor: CallableDescriptor): CallableDescriptor {
|
||||
|
||||
return when (oldDescriptor) {
|
||||
is SimpleFunctionDescriptor -> copySimpleFunctionDescriptor(oldDescriptor)
|
||||
is ConstructorDescriptor -> copyConstructorDescriptor(oldDescriptor)
|
||||
is ConstructorDescriptor -> copyConstructorDescriptor(oldDescriptor)
|
||||
is SimpleFunctionDescriptor -> copySimpleFunctionDescriptor(oldDescriptor)
|
||||
else -> TODO("Unsupported FunctionDescriptor subtype")
|
||||
}
|
||||
}
|
||||
@@ -150,30 +174,29 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
|
||||
private fun copySimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor) : FunctionDescriptor {
|
||||
|
||||
val oldContainingDeclaration = oldDescriptor.containingDeclaration
|
||||
val memberOwner = descriptorSubstituteMap[oldContainingDeclaration] ?: targetFunction.descriptor
|
||||
val containingDeclaration = targetFunction.descriptor
|
||||
val newDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
memberOwner,
|
||||
containingDeclaration,
|
||||
oldDescriptor.annotations,
|
||||
generateName(oldDescriptor.name),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
oldDescriptor.source
|
||||
).apply { isTailrec = oldDescriptor.isTailrec }
|
||||
|
||||
val oldDispatchReceiverParameter = oldDescriptor.dispatchReceiverParameter
|
||||
val newDispatchReceiverParameter =
|
||||
if (oldDispatchReceiverParameter == null) null
|
||||
else descriptorSubstituteMap[oldDispatchReceiverParameter]
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, newDescriptor)
|
||||
val newDispatchReceiverParameter = null // TODO
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, containingDeclaration)
|
||||
val receiverParameterType = substituteType(oldDescriptor.extensionReceiverParameter?.type)
|
||||
val returnType = substituteType(oldDescriptor.returnType)
|
||||
assert(newTypeParameters.isEmpty())
|
||||
|
||||
newDescriptor.initialize(
|
||||
oldDescriptor.extensionReceiverParameter?.type,
|
||||
newDispatchReceiverParameter as? ReceiverParameterDescriptor,
|
||||
receiverParameterType,
|
||||
newDispatchReceiverParameter,
|
||||
newTypeParameters,
|
||||
newValueParameters,
|
||||
oldDescriptor.returnType,
|
||||
Modality.FINAL,
|
||||
returnType,
|
||||
oldDescriptor.modality,
|
||||
oldDescriptor.visibility
|
||||
)
|
||||
newDescriptor.overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
||||
@@ -193,14 +216,18 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
oldDescriptor.source
|
||||
)
|
||||
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, newDescriptor)
|
||||
val newTypeParameters = oldDescriptor.typeParameters
|
||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, newDescriptor)
|
||||
val receiverParameterType = substituteType(oldDescriptor.dispatchReceiverParameter?.type)
|
||||
val returnType = substituteType(oldDescriptor.returnType)
|
||||
assert(newTypeParameters.isEmpty())
|
||||
|
||||
newDescriptor.initialize(
|
||||
oldDescriptor.dispatchReceiverParameter?.type,
|
||||
receiverParameterType,
|
||||
null, // TODO @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
|
||||
newTypeParameters,
|
||||
newValueParameters,
|
||||
oldDescriptor.returnType,
|
||||
returnType,
|
||||
oldDescriptor.modality,
|
||||
oldDescriptor.visibility
|
||||
)
|
||||
@@ -252,6 +279,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
|
||||
val oldDeclaration = super.visitFunction(declaration) as IrFunction
|
||||
val newDescriptor = descriptorSubstituteMap[oldDeclaration.descriptor]
|
||||
if (newDescriptor == null) return oldDeclaration
|
||||
@@ -267,29 +295,37 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
|
||||
val irCall = super.visitCall(expression) as IrCall
|
||||
if (irCall !is IrCallImpl) return irCall // TODO what other kinds of call can we meet?
|
||||
val oldExpression = super.visitCall(expression) as IrCall
|
||||
if (oldExpression !is IrCallImpl) return oldExpression // TODO what other kinds of call can we meet?
|
||||
|
||||
val oldDescriptor = irCall.descriptor
|
||||
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor.original,
|
||||
oldDescriptor) as FunctionDescriptor
|
||||
val oldDescriptor = oldExpression.descriptor
|
||||
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor, oldDescriptor)
|
||||
|
||||
val oldSuperQualifier = irCall.superQualifier
|
||||
val oldSuperQualifier = oldExpression.superQualifier
|
||||
var newSuperQualifier: ClassDescriptor? = oldSuperQualifier
|
||||
if (newSuperQualifier != null) {
|
||||
newSuperQualifier = descriptorSubstituteMap.getOrDefault(newSuperQualifier,
|
||||
newSuperQualifier) as ClassDescriptor
|
||||
}
|
||||
|
||||
return IrCallImpl(irCall.startOffset, irCall.endOffset, irCall.type, newDescriptor,
|
||||
irCall.typeArguments, irCall.origin, newSuperQualifier).apply {
|
||||
irCall.descriptor.valueParameters.forEach {
|
||||
val valueArgument = irCall.getValueArgument(it)
|
||||
val newExpression = IrCallImpl(
|
||||
oldExpression.startOffset,
|
||||
oldExpression.endOffset,
|
||||
substituteType(oldExpression.type)!!,
|
||||
newDescriptor as FunctionDescriptor,
|
||||
substituteTypeArguments(oldExpression.typeArguments),
|
||||
oldExpression.origin,
|
||||
newSuperQualifier
|
||||
).apply {
|
||||
oldExpression.descriptor.valueParameters.forEach {
|
||||
val valueArgument = oldExpression.getValueArgument(it)
|
||||
putValueArgument(it.index, valueArgument)
|
||||
}
|
||||
extensionReceiver = irCall.extensionReceiver
|
||||
dispatchReceiver = irCall.dispatchReceiver
|
||||
extensionReceiver = oldExpression.extensionReceiver
|
||||
dispatchReceiver = oldExpression.dispatchReceiver
|
||||
}
|
||||
|
||||
return newExpression
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
@@ -301,11 +337,16 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
val newDescriptor = descriptorSubstituteMap[oldDescriptor]
|
||||
if (newDescriptor == null) return oldReference
|
||||
|
||||
val typeArguments = (oldReference as IrMemberAccessExpressionBase).typeArguments
|
||||
val newReference = IrCallableReferenceImpl(expression.startOffset,
|
||||
oldReference.endOffset, oldReference.type, newDescriptor as CallableDescriptor,
|
||||
typeArguments, oldReference.origin)
|
||||
|
||||
val oldTypeArguments = (oldReference as IrMemberAccessExpressionBase).typeArguments
|
||||
val newTypeArguments = substituteTypeArguments(oldTypeArguments)
|
||||
val newReference = IrCallableReferenceImpl(
|
||||
expression.startOffset,
|
||||
oldReference.endOffset,
|
||||
substituteType(oldReference.type)!!,
|
||||
newDescriptor as CallableDescriptor,
|
||||
newTypeArguments,
|
||||
oldReference.origin
|
||||
)
|
||||
return newReference
|
||||
}
|
||||
|
||||
@@ -318,9 +359,13 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
val newDescriptor = descriptorSubstituteMap[oldDescriptor]
|
||||
if (newDescriptor == null) return oldReturn
|
||||
|
||||
val newReturn = IrReturnImpl(oldReturn.startOffset, oldReturn.endOffset,
|
||||
oldReturn.type, newDescriptor as CallableDescriptor, oldReturn.value)
|
||||
|
||||
val newReturn = IrReturnImpl(
|
||||
oldReturn.startOffset,
|
||||
oldReturn.endOffset,
|
||||
substituteType(oldReturn.type)!!,
|
||||
newDescriptor as CallableDescriptor,
|
||||
oldReturn.value
|
||||
)
|
||||
return newReturn
|
||||
}
|
||||
|
||||
@@ -334,12 +379,48 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
||||
if (newDescriptor == null) return oldExpression
|
||||
|
||||
val newExpression = IrGetValueImpl(
|
||||
oldExpression.startOffset, oldExpression.endOffset,
|
||||
newDescriptor as ValueParameterDescriptor, oldExpression.origin
|
||||
oldExpression.startOffset,
|
||||
oldExpression.endOffset,
|
||||
newDescriptor as ValueDescriptor,
|
||||
oldExpression.origin
|
||||
)
|
||||
return newExpression
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
|
||||
|
||||
val oldExpression = super.visitSetVariable(expression) as IrSetVariable
|
||||
val oldDescriptor = oldExpression.descriptor
|
||||
val newDescriptor = descriptorSubstituteMap[oldDescriptor]
|
||||
if (newDescriptor == null) return oldExpression
|
||||
|
||||
val newExpression = IrSetVariableImpl(
|
||||
oldExpression.startOffset,
|
||||
oldExpression.endOffset,
|
||||
newDescriptor as VariableDescriptor,
|
||||
oldExpression.value,
|
||||
oldExpression.origin
|
||||
)
|
||||
return newExpression
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitVariable(declaration: IrVariable): IrStatement {
|
||||
val oldDeclaration = super.visitVariable(declaration) as IrVariable
|
||||
val newDescriptor = descriptorSubstituteMap[oldDeclaration.descriptor]
|
||||
val newDeclaration = IrVariableImpl(
|
||||
oldDeclaration.startOffset,
|
||||
oldDeclaration.endOffset,
|
||||
oldDeclaration.origin,
|
||||
newDescriptor as VariableDescriptor,
|
||||
oldDeclaration.initializer
|
||||
)
|
||||
return newDeclaration
|
||||
}
|
||||
|
||||
//--- Copy declarations -----------------------------------------------//
|
||||
|
||||
private fun copyIrFunctionImpl(oldDeclaration: IrFunction, newDescriptor: DeclarationDescriptor): IrFunction {
|
||||
@@ -358,4 +439,50 @@ 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
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun substituteTypeArguments(oldTypeArguments: Map <TypeParameterDescriptor, KotlinType>?): Map <TypeParameterDescriptor, KotlinType>? {
|
||||
|
||||
if (oldTypeArguments == null) return null
|
||||
if (typeSubstitutor == null) return oldTypeArguments
|
||||
|
||||
val newTypeArguments = oldTypeArguments.entries.associate {
|
||||
val typeParameterDescriptor = it.key
|
||||
val oldTypeArgument = it.value
|
||||
val newTypeArgument = substituteType(oldTypeArgument)!!
|
||||
typeParameterDescriptor to newTypeArgument
|
||||
}
|
||||
return newTypeArguments
|
||||
}
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun copyValueParameters(oldValueParameters: List <ValueParameterDescriptor>, containingDeclaration: CallableDescriptor): List <ValueParameterDescriptor> {
|
||||
|
||||
return oldValueParameters.map { oldDescriptor ->
|
||||
val newDescriptor = ValueParameterDescriptorImpl(
|
||||
containingDeclaration,
|
||||
oldDescriptor.original,
|
||||
oldDescriptor.index,
|
||||
oldDescriptor.annotations,
|
||||
oldDescriptor.name,
|
||||
substituteType(oldDescriptor.type)!!,
|
||||
oldDescriptor.declaresDefaultValue(),
|
||||
oldDescriptor.isCrossinline,
|
||||
oldDescriptor.isNoinline,
|
||||
substituteType(oldDescriptor.varargElementType),
|
||||
oldDescriptor.source
|
||||
)
|
||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||
newDescriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-43
@@ -77,7 +77,6 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
currentFunction = declaration
|
||||
currentScope = Scope(declaration.descriptor)
|
||||
copyWithDescriptors = DeepCopyIrTreeWithDescriptors(currentFunction!!, context)
|
||||
return super.visitFunction(declaration)
|
||||
}
|
||||
|
||||
@@ -192,8 +191,11 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
val originBlockBody = functionDeclaration.body
|
||||
if (originBlockBody == null) return null // TODO workaround
|
||||
|
||||
val copyBlockBody = originBlockBody.accept(InlineCopyIr(), null) as IrBlockBody // Create copy of original function body.
|
||||
val typeSubstitutor = createTypeSubstitutor(typeArgsMap)
|
||||
copyWithDescriptors = DeepCopyIrTreeWithDescriptors(currentFunction!!, typeSubstitutor, context)
|
||||
val functionName = functionDeclaration.descriptor.name.toString()
|
||||
|
||||
val copyBlockBody = originBlockBody.accept(InlineCopyIr(), null) as IrBlockBody // Create copy of original function body.
|
||||
copyWithDescriptors!!.copy(copyBlockBody, functionName) // TODO merge DeepCopyIrTreeWithDescriptors with InlineCopyIr
|
||||
|
||||
val originalDescriptor = functionDeclaration.descriptor.original
|
||||
@@ -212,7 +214,8 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
if (irDeclaration == null) return irCall
|
||||
|
||||
val functionDeclaration = irDeclaration as IrFunction
|
||||
val inlineBody = createInlineFunctionBody(functionDeclaration)
|
||||
val typeArgsMap = (irCall as IrMemberAccessExpressionBase).typeArguments
|
||||
val inlineBody = createInlineFunctionBody(functionDeclaration, typeArgsMap)
|
||||
if (inlineBody == null) return irCall
|
||||
|
||||
val parametersOld = getArguments(irCall, functionDeclaration) // Create map call_site_argument -> inline_function_parameter.
|
||||
@@ -222,7 +225,6 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
val lambdaInliner = LambdaInliner(parameterToArgument)
|
||||
inlineBody.transformChildrenVoid(lambdaInliner)
|
||||
|
||||
val typeArgsMap = (irCall as IrMemberAccessExpressionBase).typeArguments
|
||||
val transformer = ParametersTransformer(parameterToArgument, typeArgsMap, evaluationStatements)
|
||||
inlineBody.transformChildrenVoid(transformer) // Replace parameters with expression.
|
||||
inlineBody.statements.addAll(0, evaluationStatements)
|
||||
@@ -283,6 +285,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
|
||||
val newExpression = super.visitGetValue(expression) as IrGetValue
|
||||
val descriptor = newExpression.descriptor
|
||||
val argument = substituteMap[descriptor]?.accept(InlineCopyIr(), null) as IrExpression? // Find expression to replace this parameter.
|
||||
@@ -293,44 +296,6 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun newVariable(oldVariable: IrVariable): IrVariable {
|
||||
val initializer = oldVariable.initializer!!
|
||||
val isMutable = oldVariable.descriptor.isVar
|
||||
val varName = currentScope!!.scopeOwner.name.toString() + "_inline"
|
||||
return currentScope!!.createTemporaryVariable(initializer, varName, isMutable) // Create new variable and init it with the parameter expression.
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitVariable(declaration: IrVariable): IrStatement {
|
||||
|
||||
val newDeclaration = super.visitVariable(declaration) as IrVariable // Process variable initializer.
|
||||
val newVariable = newVariable(newDeclaration) // Create new local variable.
|
||||
val getVal = IrGetValueImpl(0, 0, newVariable.descriptor) // Create new IR element representing access the new variable.
|
||||
val descriptor = declaration.descriptor.original as ValueDescriptor
|
||||
substituteMap[descriptor] = getVal
|
||||
return newVariable
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
|
||||
|
||||
val result = super.visitSetVariable(expression)
|
||||
val substitute = substituteMap[expression.descriptor] // Get substitution for this variable.
|
||||
if (substitute == null) return result // If there is no substitution - do nothing.
|
||||
|
||||
val startOffset = expression.startOffset
|
||||
val endOffset = expression.endOffset
|
||||
val descriptor = (substitute as IrGetValue).descriptor as VariableDescriptor
|
||||
val value = expression.value
|
||||
val origin = expression.origin
|
||||
|
||||
return IrSetVariableImpl(startOffset, endOffset, descriptor, value, origin) // Create SetVariable expression for the new descriptor.
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
private fun createTypeSubstitutor(): TypeSubstitutor {
|
||||
|
||||
val substitutionContext = typeArgsMap!!.entries.associate {
|
||||
@@ -467,7 +432,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
||||
|
||||
val copyLambdaFunction = lambdaFunction.accept(InlineCopyIr(), // Create copy of the function.
|
||||
null) as IrFunction
|
||||
copyWithDescriptors!!.copy(copyLambdaFunction, "lambda") // TODO merge DeepCopyIrTreeWithDescriptors with InlineCopyIr
|
||||
copyWithDescriptors!!.copy(copyLambdaFunction, "lambda") // TODO merge DeepCopyIrTreeWithDescriptors with InlineCopyIr
|
||||
|
||||
val lambdaStatements = (copyLambdaFunction.body as IrBlockBody).statements
|
||||
val lambdaReturnType = copyLambdaFunction.descriptor.returnType!!
|
||||
|
||||
Reference in New Issue
Block a user