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.common.lower.SimpleMemberScope
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
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.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
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.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
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.IrClassImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
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.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
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.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
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 val descriptorSubstituteMap: MutableMap<DeclarationDescriptor, DeclarationDescriptor> = mutableMapOf()
|
||||||
private var inlinedFunctionName = ""
|
private var inlinedFunctionName = ""
|
||||||
@@ -48,6 +56,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
fun copy(irElement: IrElement, functionName: String) {
|
fun copy(irElement: IrElement, functionName: String) {
|
||||||
|
|
||||||
inlinedFunctionName = functionName
|
inlinedFunctionName = functionName
|
||||||
descriptorSubstituteMap.clear()
|
descriptorSubstituteMap.clear()
|
||||||
irElement.acceptChildrenVoid(descriptorCollector)
|
irElement.acceptChildrenVoid(descriptorCollector)
|
||||||
@@ -58,30 +67,16 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
|
|
||||||
private val descriptorCollector = object : IrElementVisitorVoid {
|
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) {
|
override fun visitClass(declaration: IrClass) {
|
||||||
|
|
||||||
val oldDescriptor = declaration.descriptor
|
val oldDescriptor = declaration.descriptor
|
||||||
val newDescriptor = copyClassDescriptor(oldDescriptor)
|
val newDescriptor = copyClassDescriptor(oldDescriptor)
|
||||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||||
descriptorSubstituteMap[oldDescriptor.thisAsReceiverParameter] = newDescriptor.thisAsReceiverParameter
|
descriptorSubstituteMap[oldDescriptor.thisAsReceiverParameter] = newDescriptor.thisAsReceiverParameter
|
||||||
super.visitClass(declaration)
|
super.visitClass(declaration)
|
||||||
|
|
||||||
val constructors = oldDescriptor.constructors.map {
|
val constructors = oldDescriptor.constructors.map { oldConstructorDescriptor ->
|
||||||
descriptorSubstituteMap[it] as ClassConstructorDescriptor
|
descriptorSubstituteMap[oldConstructorDescriptor] as ClassConstructorDescriptor
|
||||||
}.toSet()
|
}.toSet()
|
||||||
|
|
||||||
var primaryConstructor: ClassConstructorDescriptor? = null
|
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 ------------------------------------------------//
|
//--- Copy descriptors ------------------------------------------------//
|
||||||
|
|
||||||
private fun generateName(name: Name): Name {
|
private fun generateName(name: Name): Name {
|
||||||
|
|
||||||
val containingName = targetFunction.descriptor.name.toString() // Name of inline target (function we inline in)
|
val containingName = targetFunction.descriptor.name.toString() // Name of inline target (function we inline in)
|
||||||
val declarationName = name.toString() // Name of declaration
|
val declarationName = name.toString() // Name of declaration
|
||||||
val indexStr = (nameIndex++).toString() // Unique for inline target index
|
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> {
|
private fun copyFunctionDescriptor(oldDescriptor: CallableDescriptor): CallableDescriptor {
|
||||||
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 {
|
|
||||||
|
|
||||||
return when (oldDescriptor) {
|
return when (oldDescriptor) {
|
||||||
is SimpleFunctionDescriptor -> copySimpleFunctionDescriptor(oldDescriptor)
|
is ConstructorDescriptor -> copyConstructorDescriptor(oldDescriptor)
|
||||||
is ConstructorDescriptor -> copyConstructorDescriptor(oldDescriptor)
|
is SimpleFunctionDescriptor -> copySimpleFunctionDescriptor(oldDescriptor)
|
||||||
else -> TODO("Unsupported FunctionDescriptor subtype")
|
else -> TODO("Unsupported FunctionDescriptor subtype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,30 +174,29 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
|
|
||||||
private fun copySimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor) : FunctionDescriptor {
|
private fun copySimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor) : FunctionDescriptor {
|
||||||
|
|
||||||
val oldContainingDeclaration = oldDescriptor.containingDeclaration
|
val containingDeclaration = targetFunction.descriptor
|
||||||
val memberOwner = descriptorSubstituteMap[oldContainingDeclaration] ?: targetFunction.descriptor
|
|
||||||
val newDescriptor = SimpleFunctionDescriptorImpl.create(
|
val newDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||||
memberOwner,
|
containingDeclaration,
|
||||||
oldDescriptor.annotations,
|
oldDescriptor.annotations,
|
||||||
generateName(oldDescriptor.name),
|
generateName(oldDescriptor.name),
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
oldDescriptor.source
|
oldDescriptor.source
|
||||||
).apply { isTailrec = oldDescriptor.isTailrec }
|
).apply { isTailrec = oldDescriptor.isTailrec }
|
||||||
|
|
||||||
val oldDispatchReceiverParameter = oldDescriptor.dispatchReceiverParameter
|
val newDispatchReceiverParameter = null // TODO
|
||||||
val newDispatchReceiverParameter =
|
val newTypeParameters = oldDescriptor.typeParameters
|
||||||
if (oldDispatchReceiverParameter == null) null
|
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, containingDeclaration)
|
||||||
else descriptorSubstituteMap[oldDispatchReceiverParameter]
|
val receiverParameterType = substituteType(oldDescriptor.extensionReceiverParameter?.type)
|
||||||
val newTypeParameters = oldDescriptor.typeParameters
|
val returnType = substituteType(oldDescriptor.returnType)
|
||||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, newDescriptor)
|
assert(newTypeParameters.isEmpty())
|
||||||
|
|
||||||
newDescriptor.initialize(
|
newDescriptor.initialize(
|
||||||
oldDescriptor.extensionReceiverParameter?.type,
|
receiverParameterType,
|
||||||
newDispatchReceiverParameter as? ReceiverParameterDescriptor,
|
newDispatchReceiverParameter,
|
||||||
newTypeParameters,
|
newTypeParameters,
|
||||||
newValueParameters,
|
newValueParameters,
|
||||||
oldDescriptor.returnType,
|
returnType,
|
||||||
Modality.FINAL,
|
oldDescriptor.modality,
|
||||||
oldDescriptor.visibility
|
oldDescriptor.visibility
|
||||||
)
|
)
|
||||||
newDescriptor.overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
newDescriptor.overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
||||||
@@ -193,14 +216,18 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
oldDescriptor.source
|
oldDescriptor.source
|
||||||
)
|
)
|
||||||
|
|
||||||
val newTypeParameters = oldDescriptor.typeParameters
|
val newTypeParameters = oldDescriptor.typeParameters
|
||||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, newDescriptor)
|
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, newDescriptor)
|
||||||
|
val receiverParameterType = substituteType(oldDescriptor.dispatchReceiverParameter?.type)
|
||||||
|
val returnType = substituteType(oldDescriptor.returnType)
|
||||||
|
assert(newTypeParameters.isEmpty())
|
||||||
|
|
||||||
newDescriptor.initialize(
|
newDescriptor.initialize(
|
||||||
oldDescriptor.dispatchReceiverParameter?.type,
|
receiverParameterType,
|
||||||
null, // TODO @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
|
null, // TODO @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
|
||||||
newTypeParameters,
|
newTypeParameters,
|
||||||
newValueParameters,
|
newValueParameters,
|
||||||
oldDescriptor.returnType,
|
returnType,
|
||||||
oldDescriptor.modality,
|
oldDescriptor.modality,
|
||||||
oldDescriptor.visibility
|
oldDescriptor.visibility
|
||||||
)
|
)
|
||||||
@@ -252,6 +279,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
//---------------------------------------------------------------------//
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||||
|
|
||||||
val oldDeclaration = super.visitFunction(declaration) as IrFunction
|
val oldDeclaration = super.visitFunction(declaration) as IrFunction
|
||||||
val newDescriptor = descriptorSubstituteMap[oldDeclaration.descriptor]
|
val newDescriptor = descriptorSubstituteMap[oldDeclaration.descriptor]
|
||||||
if (newDescriptor == null) return oldDeclaration
|
if (newDescriptor == null) return oldDeclaration
|
||||||
@@ -267,29 +295,37 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
|
||||||
val irCall = super.visitCall(expression) as IrCall
|
val oldExpression = super.visitCall(expression) as IrCall
|
||||||
if (irCall !is IrCallImpl) return irCall // TODO what other kinds of call can we meet?
|
if (oldExpression !is IrCallImpl) return oldExpression // TODO what other kinds of call can we meet?
|
||||||
|
|
||||||
val oldDescriptor = irCall.descriptor
|
val oldDescriptor = oldExpression.descriptor
|
||||||
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor.original,
|
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor, oldDescriptor)
|
||||||
oldDescriptor) as FunctionDescriptor
|
|
||||||
|
|
||||||
val oldSuperQualifier = irCall.superQualifier
|
val oldSuperQualifier = oldExpression.superQualifier
|
||||||
var newSuperQualifier: ClassDescriptor? = oldSuperQualifier
|
var newSuperQualifier: ClassDescriptor? = oldSuperQualifier
|
||||||
if (newSuperQualifier != null) {
|
if (newSuperQualifier != null) {
|
||||||
newSuperQualifier = descriptorSubstituteMap.getOrDefault(newSuperQualifier,
|
newSuperQualifier = descriptorSubstituteMap.getOrDefault(newSuperQualifier,
|
||||||
newSuperQualifier) as ClassDescriptor
|
newSuperQualifier) as ClassDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
return IrCallImpl(irCall.startOffset, irCall.endOffset, irCall.type, newDescriptor,
|
val newExpression = IrCallImpl(
|
||||||
irCall.typeArguments, irCall.origin, newSuperQualifier).apply {
|
oldExpression.startOffset,
|
||||||
irCall.descriptor.valueParameters.forEach {
|
oldExpression.endOffset,
|
||||||
val valueArgument = irCall.getValueArgument(it)
|
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)
|
putValueArgument(it.index, valueArgument)
|
||||||
}
|
}
|
||||||
extensionReceiver = irCall.extensionReceiver
|
extensionReceiver = oldExpression.extensionReceiver
|
||||||
dispatchReceiver = irCall.dispatchReceiver
|
dispatchReceiver = oldExpression.dispatchReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return newExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
//---------------------------------------------------------------------//
|
||||||
@@ -301,11 +337,16 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
val newDescriptor = descriptorSubstituteMap[oldDescriptor]
|
val newDescriptor = descriptorSubstituteMap[oldDescriptor]
|
||||||
if (newDescriptor == null) return oldReference
|
if (newDescriptor == null) return oldReference
|
||||||
|
|
||||||
val typeArguments = (oldReference as IrMemberAccessExpressionBase).typeArguments
|
val oldTypeArguments = (oldReference as IrMemberAccessExpressionBase).typeArguments
|
||||||
val newReference = IrCallableReferenceImpl(expression.startOffset,
|
val newTypeArguments = substituteTypeArguments(oldTypeArguments)
|
||||||
oldReference.endOffset, oldReference.type, newDescriptor as CallableDescriptor,
|
val newReference = IrCallableReferenceImpl(
|
||||||
typeArguments, oldReference.origin)
|
expression.startOffset,
|
||||||
|
oldReference.endOffset,
|
||||||
|
substituteType(oldReference.type)!!,
|
||||||
|
newDescriptor as CallableDescriptor,
|
||||||
|
newTypeArguments,
|
||||||
|
oldReference.origin
|
||||||
|
)
|
||||||
return newReference
|
return newReference
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,9 +359,13 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
val newDescriptor = descriptorSubstituteMap[oldDescriptor]
|
val newDescriptor = descriptorSubstituteMap[oldDescriptor]
|
||||||
if (newDescriptor == null) return oldReturn
|
if (newDescriptor == null) return oldReturn
|
||||||
|
|
||||||
val newReturn = IrReturnImpl(oldReturn.startOffset, oldReturn.endOffset,
|
val newReturn = IrReturnImpl(
|
||||||
oldReturn.type, newDescriptor as CallableDescriptor, oldReturn.value)
|
oldReturn.startOffset,
|
||||||
|
oldReturn.endOffset,
|
||||||
|
substituteType(oldReturn.type)!!,
|
||||||
|
newDescriptor as CallableDescriptor,
|
||||||
|
oldReturn.value
|
||||||
|
)
|
||||||
return newReturn
|
return newReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,12 +379,48 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, val
|
|||||||
if (newDescriptor == null) return oldExpression
|
if (newDescriptor == null) return oldExpression
|
||||||
|
|
||||||
val newExpression = IrGetValueImpl(
|
val newExpression = IrGetValueImpl(
|
||||||
oldExpression.startOffset, oldExpression.endOffset,
|
oldExpression.startOffset,
|
||||||
newDescriptor as ValueParameterDescriptor, oldExpression.origin
|
oldExpression.endOffset,
|
||||||
|
newDescriptor as ValueDescriptor,
|
||||||
|
oldExpression.origin
|
||||||
)
|
)
|
||||||
return newExpression
|
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 -----------------------------------------------//
|
//--- Copy declarations -----------------------------------------------//
|
||||||
|
|
||||||
private fun copyIrFunctionImpl(oldDeclaration: IrFunction, newDescriptor: DeclarationDescriptor): IrFunction {
|
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 {
|
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||||
currentFunction = declaration
|
currentFunction = declaration
|
||||||
currentScope = Scope(declaration.descriptor)
|
currentScope = Scope(declaration.descriptor)
|
||||||
copyWithDescriptors = DeepCopyIrTreeWithDescriptors(currentFunction!!, context)
|
|
||||||
return super.visitFunction(declaration)
|
return super.visitFunction(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +191,11 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
val originBlockBody = functionDeclaration.body
|
val originBlockBody = functionDeclaration.body
|
||||||
if (originBlockBody == null) return null // TODO workaround
|
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 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
|
copyWithDescriptors!!.copy(copyBlockBody, functionName) // TODO merge DeepCopyIrTreeWithDescriptors with InlineCopyIr
|
||||||
|
|
||||||
val originalDescriptor = functionDeclaration.descriptor.original
|
val originalDescriptor = functionDeclaration.descriptor.original
|
||||||
@@ -212,7 +214,8 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
if (irDeclaration == null) return irCall
|
if (irDeclaration == null) return irCall
|
||||||
|
|
||||||
val functionDeclaration = irDeclaration as IrFunction
|
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
|
if (inlineBody == null) return irCall
|
||||||
|
|
||||||
val parametersOld = getArguments(irCall, functionDeclaration) // Create map call_site_argument -> inline_function_parameter.
|
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)
|
val lambdaInliner = LambdaInliner(parameterToArgument)
|
||||||
inlineBody.transformChildrenVoid(lambdaInliner)
|
inlineBody.transformChildrenVoid(lambdaInliner)
|
||||||
|
|
||||||
val typeArgsMap = (irCall as IrMemberAccessExpressionBase).typeArguments
|
|
||||||
val transformer = ParametersTransformer(parameterToArgument, typeArgsMap, evaluationStatements)
|
val transformer = ParametersTransformer(parameterToArgument, typeArgsMap, evaluationStatements)
|
||||||
inlineBody.transformChildrenVoid(transformer) // Replace parameters with expression.
|
inlineBody.transformChildrenVoid(transformer) // Replace parameters with expression.
|
||||||
inlineBody.statements.addAll(0, evaluationStatements)
|
inlineBody.statements.addAll(0, evaluationStatements)
|
||||||
@@ -283,6 +285,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
//---------------------------------------------------------------------//
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
|
|
||||||
val newExpression = super.visitGetValue(expression) as IrGetValue
|
val newExpression = super.visitGetValue(expression) as IrGetValue
|
||||||
val descriptor = newExpression.descriptor
|
val descriptor = newExpression.descriptor
|
||||||
val argument = substituteMap[descriptor]?.accept(InlineCopyIr(), null) as IrExpression? // Find expression to replace this parameter.
|
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 {
|
private fun createTypeSubstitutor(): TypeSubstitutor {
|
||||||
|
|
||||||
val substitutionContext = typeArgsMap!!.entries.associate {
|
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.
|
val copyLambdaFunction = lambdaFunction.accept(InlineCopyIr(), // Create copy of the function.
|
||||||
null) as IrFunction
|
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 lambdaStatements = (copyLambdaFunction.body as IrBlockBody).statements
|
||||||
val lambdaReturnType = copyLambdaFunction.descriptor.returnType!!
|
val lambdaReturnType = copyLambdaFunction.descriptor.returnType!!
|
||||||
|
|||||||
Reference in New Issue
Block a user