Inline: implemented properties copying
This commit is contained in:
+235
-29
@@ -20,20 +20,11 @@ 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.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.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
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.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.*
|
||||||
@@ -104,11 +95,40 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ
|
|||||||
|
|
||||||
//---------------------------------------------------------------------//
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun copyPropertyOrField(oldDescriptor: PropertyDescriptor) {
|
||||||
|
val newDescriptor = copyPropertyDescriptor(oldDescriptor)
|
||||||
|
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||||
|
oldDescriptor.getter?.let {
|
||||||
|
descriptorSubstituteMap[it] = newDescriptor.getter!!
|
||||||
|
}
|
||||||
|
oldDescriptor.setter?.let {
|
||||||
|
descriptorSubstituteMap[it] = newDescriptor.setter!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(declaration: IrProperty) {
|
||||||
|
copyPropertyOrField(declaration.descriptor)
|
||||||
|
super.visitProperty(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitField(declaration: IrField) {
|
||||||
|
val oldDescriptor = declaration.descriptor
|
||||||
|
if (descriptorSubstituteMap[oldDescriptor] == null) {
|
||||||
|
// A field without a property or a field of a delegated property.
|
||||||
|
copyPropertyOrField(oldDescriptor)
|
||||||
|
}
|
||||||
|
super.visitField(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction) {
|
override fun visitFunction(declaration: IrFunction) {
|
||||||
|
|
||||||
val oldDescriptor = declaration.descriptor
|
val oldDescriptor = declaration.descriptor
|
||||||
val newDescriptor = copyFunctionDescriptor(oldDescriptor)
|
if (oldDescriptor !is PropertyAccessorDescriptor) { // Property accessors are copied along with their property.
|
||||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
val newDescriptor = copyFunctionDescriptor(oldDescriptor)
|
||||||
|
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
||||||
|
}
|
||||||
super.visitFunction(declaration)
|
super.visitFunction(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,6 +261,83 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ
|
|||||||
return newDescriptor
|
return newDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun copyPropertyDescriptor(oldDescriptor: PropertyDescriptor): PropertyDescriptor {
|
||||||
|
val oldContainingDeclaration = oldDescriptor.containingDeclaration
|
||||||
|
val memberOwner = descriptorSubstituteMap[oldContainingDeclaration] as ClassDescriptor
|
||||||
|
val newDescriptor = PropertyDescriptorImpl.create(
|
||||||
|
memberOwner,
|
||||||
|
oldDescriptor.annotations,
|
||||||
|
oldDescriptor.modality,
|
||||||
|
oldDescriptor.visibility,
|
||||||
|
oldDescriptor.isVar,
|
||||||
|
oldDescriptor.name,
|
||||||
|
oldDescriptor.kind,
|
||||||
|
oldDescriptor.source,
|
||||||
|
oldDescriptor.isLateInit,
|
||||||
|
oldDescriptor.isConst,
|
||||||
|
oldDescriptor.isHeader,
|
||||||
|
oldDescriptor.isImpl,
|
||||||
|
oldDescriptor.isExternal,
|
||||||
|
oldDescriptor.isDelegated)
|
||||||
|
|
||||||
|
newDescriptor.setType(
|
||||||
|
oldDescriptor.type,
|
||||||
|
oldDescriptor.typeParameters,
|
||||||
|
memberOwner.thisAsReceiverParameter,
|
||||||
|
oldDescriptor.extensionReceiverParameter?.type)
|
||||||
|
|
||||||
|
newDescriptor.initialize(
|
||||||
|
oldDescriptor.getter?.let { copyPropertyGetterDescriptor(it, newDescriptor) },
|
||||||
|
oldDescriptor.setter?.let { copyPropertySetterDescriptor(it, newDescriptor) })
|
||||||
|
|
||||||
|
newDescriptor.overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
||||||
|
|
||||||
|
return newDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun copyPropertyGetterDescriptor(oldDescriptor: PropertyGetterDescriptor, newPropertyDescriptor: PropertyDescriptor)
|
||||||
|
: PropertyGetterDescriptorImpl {
|
||||||
|
|
||||||
|
return PropertyGetterDescriptorImpl(
|
||||||
|
newPropertyDescriptor,
|
||||||
|
oldDescriptor.annotations,
|
||||||
|
oldDescriptor.modality,
|
||||||
|
oldDescriptor.visibility,
|
||||||
|
oldDescriptor.isDefault,
|
||||||
|
oldDescriptor.isExternal,
|
||||||
|
oldDescriptor.isInline,
|
||||||
|
oldDescriptor.kind,
|
||||||
|
null,
|
||||||
|
oldDescriptor.source).apply {
|
||||||
|
initialize(oldDescriptor.returnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun copyPropertySetterDescriptor(oldDescriptor: PropertySetterDescriptor, newPropertyDescriptor: PropertyDescriptor)
|
||||||
|
: PropertySetterDescriptorImpl {
|
||||||
|
|
||||||
|
return PropertySetterDescriptorImpl(
|
||||||
|
newPropertyDescriptor,
|
||||||
|
oldDescriptor.annotations,
|
||||||
|
oldDescriptor.modality,
|
||||||
|
oldDescriptor.visibility,
|
||||||
|
oldDescriptor.isDefault,
|
||||||
|
oldDescriptor.isExternal,
|
||||||
|
oldDescriptor.isInline,
|
||||||
|
oldDescriptor.kind,
|
||||||
|
null,
|
||||||
|
oldDescriptor.source).apply {
|
||||||
|
initialize(copyValueParameters(oldDescriptor.valueParameters, this).single())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun copyClassDescriptor(oldDescriptor: ClassDescriptor): ClassDescriptorImpl {
|
private fun copyClassDescriptor(oldDescriptor: ClassDescriptor): ClassDescriptorImpl {
|
||||||
@@ -302,30 +399,139 @@ internal class DeepCopyIrTreeWithDescriptors(val targetFunction: IrFunction, typ
|
|||||||
|
|
||||||
//---------------------------------------------------------------------//
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitField(declaration: IrField): IrStatement {
|
||||||
|
declaration.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
val oldDescriptor = declaration.descriptor
|
||||||
|
val newDescriptor = descriptorSubstituteMap[oldDescriptor] as PropertyDescriptor
|
||||||
|
return IrFieldImpl(declaration.startOffset, declaration.endOffset, declaration.origin,
|
||||||
|
newDescriptor, declaration.initializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitProperty(declaration: IrProperty): IrStatement {
|
||||||
|
declaration.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
val oldDescriptor = declaration.descriptor
|
||||||
|
val newDescriptor = descriptorSubstituteMap[oldDescriptor] as PropertyDescriptor
|
||||||
|
return IrPropertyImpl(declaration.startOffset, declaration.endOffset, declaration.origin,
|
||||||
|
declaration.isDelegated, newDescriptor, declaration.backingField, declaration.getter, declaration.setter)
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitGetField(expression: IrGetField): IrExpression {
|
||||||
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
val oldDescriptor = expression.descriptor
|
||||||
|
val newDescriptor = descriptorSubstituteMap[oldDescriptor] ?: oldDescriptor
|
||||||
|
val oldSuperQualifier = expression.superQualifier
|
||||||
|
val newSuperQualifier = oldSuperQualifier?.let { (descriptorSubstituteMap[it] ?: it) as ClassDescriptor }
|
||||||
|
if (newDescriptor == oldDescriptor && newSuperQualifier == oldSuperQualifier) return expression
|
||||||
|
return IrGetFieldImpl(expression.startOffset, expression.endOffset, newDescriptor as PropertyDescriptor,
|
||||||
|
expression.receiver, expression.origin, newSuperQualifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitSetField(expression: IrSetField): IrExpression {
|
||||||
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
val oldDescriptor = expression.descriptor
|
||||||
|
val newDescriptor = descriptorSubstituteMap[oldDescriptor] ?: oldDescriptor
|
||||||
|
val oldSuperQualifier = expression.superQualifier
|
||||||
|
val newSuperQualifier = oldSuperQualifier?.let { (descriptorSubstituteMap[it] ?: it) as ClassDescriptor }
|
||||||
|
if (newDescriptor == oldDescriptor && newSuperQualifier == oldSuperQualifier) return expression
|
||||||
|
return IrSetFieldImpl(expression.startOffset, expression.endOffset, newDescriptor as PropertyDescriptor,
|
||||||
|
expression.receiver, expression.value, expression.origin, newSuperQualifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
|
||||||
val oldExpression = super.visitCall(expression) as IrCall
|
val oldExpression = super.visitCall(expression) as IrCall
|
||||||
if (oldExpression !is IrCallImpl) return oldExpression // TODO what other kinds of call can we meet?
|
|
||||||
|
|
||||||
|
return when (oldExpression) {
|
||||||
|
is IrCallImpl -> transformIrCallImpl(oldExpression)
|
||||||
|
is IrGetterCallImpl -> transformIrGetterCallImpl(oldExpression)
|
||||||
|
is IrSetterCallImpl -> transformIrSetterCallImpl(oldExpression)
|
||||||
|
else -> oldExpression
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformIrCallImpl(oldExpression: IrCallImpl): IrExpression {
|
||||||
val oldDescriptor = oldExpression.descriptor
|
val oldDescriptor = oldExpression.descriptor
|
||||||
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor.original,
|
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor.original,
|
||||||
oldDescriptor) as FunctionDescriptor
|
oldDescriptor) as FunctionDescriptor
|
||||||
|
|
||||||
val oldSuperQualifier = oldExpression.superQualifier
|
val oldSuperQualifier = oldExpression.superQualifier
|
||||||
var newSuperQualifier: ClassDescriptor? = oldSuperQualifier
|
val newSuperQualifier = oldSuperQualifier?.let { (descriptorSubstituteMap[it] ?: it) as ClassDescriptor }
|
||||||
if (newSuperQualifier != null) {
|
|
||||||
newSuperQualifier = descriptorSubstituteMap.getOrDefault(newSuperQualifier,
|
|
||||||
newSuperQualifier) as ClassDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
val newExpression = IrCallImpl(
|
val newExpression = IrCallImpl(
|
||||||
oldExpression.startOffset,
|
oldExpression.startOffset,
|
||||||
oldExpression.endOffset,
|
oldExpression.endOffset,
|
||||||
substituteType(oldExpression.type)!!,
|
substituteType(oldExpression.type)!!,
|
||||||
newDescriptor,
|
newDescriptor,
|
||||||
substituteTypeArguments(oldExpression.typeArguments),
|
substituteTypeArguments(oldExpression.typeArguments),
|
||||||
oldExpression.origin,
|
oldExpression.origin,
|
||||||
newSuperQualifier
|
newSuperQualifier
|
||||||
|
).apply {
|
||||||
|
oldExpression.descriptor.valueParameters.forEach {
|
||||||
|
val valueArgument = oldExpression.getValueArgument(it)
|
||||||
|
putValueArgument(it.index, valueArgument)
|
||||||
|
}
|
||||||
|
extensionReceiver = oldExpression.extensionReceiver
|
||||||
|
dispatchReceiver = oldExpression.dispatchReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
return newExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformIrGetterCallImpl(oldExpression: IrGetterCallImpl): IrExpression {
|
||||||
|
val oldDescriptor = oldExpression.descriptor
|
||||||
|
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor.original,
|
||||||
|
oldDescriptor) as FunctionDescriptor
|
||||||
|
|
||||||
|
val oldSuperQualifier = oldExpression.superQualifier
|
||||||
|
|
||||||
|
val newSuperQualifier = oldSuperQualifier?.let { (descriptorSubstituteMap[it] ?: it) as ClassDescriptor }
|
||||||
|
|
||||||
|
val newExpression = IrGetterCallImpl(
|
||||||
|
oldExpression.startOffset,
|
||||||
|
oldExpression.endOffset,
|
||||||
|
newDescriptor,
|
||||||
|
substituteTypeArguments(oldExpression.typeArguments),
|
||||||
|
oldExpression.origin,
|
||||||
|
newSuperQualifier
|
||||||
|
).apply {
|
||||||
|
oldExpression.descriptor.valueParameters.forEach {
|
||||||
|
val valueArgument = oldExpression.getValueArgument(it)
|
||||||
|
putValueArgument(it.index, valueArgument)
|
||||||
|
}
|
||||||
|
extensionReceiver = oldExpression.extensionReceiver
|
||||||
|
dispatchReceiver = oldExpression.dispatchReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
return newExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformIrSetterCallImpl(oldExpression: IrSetterCallImpl): IrExpression {
|
||||||
|
val oldDescriptor = oldExpression.descriptor
|
||||||
|
val newDescriptor = descriptorSubstituteMap.getOrDefault(oldDescriptor.original,
|
||||||
|
oldDescriptor) as FunctionDescriptor
|
||||||
|
|
||||||
|
val oldSuperQualifier = oldExpression.superQualifier
|
||||||
|
|
||||||
|
val newSuperQualifier = oldSuperQualifier?.let { (descriptorSubstituteMap[it] ?: it) as ClassDescriptor }
|
||||||
|
|
||||||
|
val newExpression = IrSetterCallImpl(
|
||||||
|
oldExpression.startOffset,
|
||||||
|
oldExpression.endOffset,
|
||||||
|
newDescriptor,
|
||||||
|
substituteTypeArguments(oldExpression.typeArguments),
|
||||||
|
oldExpression.origin,
|
||||||
|
newSuperQualifier
|
||||||
).apply {
|
).apply {
|
||||||
oldExpression.descriptor.valueParameters.forEach {
|
oldExpression.descriptor.valueParameters.forEach {
|
||||||
val valueArgument = oldExpression.getValueArgument(it)
|
val valueArgument = oldExpression.getValueArgument(it)
|
||||||
|
|||||||
Reference in New Issue
Block a user