Type substitution relocated in DeepCopyIrWithDescriptors

This commit is contained in:
Konstantin Anisimov
2017-04-03 09:43:33 +07:00
committed by KonstantinAnisimov
parent ee3e408dcb
commit 2381e453d8
2 changed files with 217 additions and 125 deletions
@@ -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
}
}
} }
@@ -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!!