No visitor with context needed to lookup for descriptors. Containing declaration must already be in descriptorSubstituteMap or to be left unchanged

This commit is contained in:
Konstantin Anisimov
2017-04-13 15:10:18 +07:00
committed by KonstantinAnisimov
parent 00a3dfc4b7
commit 6e7eff4c03
2 changed files with 58 additions and 56 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
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.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -41,7 +42,7 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable
internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr, internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: DeclarationDescriptor,
val context: Context) { val context: Context) {
private val descriptorSubstituteMap: MutableMap<DeclarationDescriptor, DeclarationDescriptor> = mutableMapOf() private val descriptorSubstituteMap: MutableMap<DeclarationDescriptor, DeclarationDescriptor> = mutableMapOf()
@@ -72,7 +73,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
inner class DescriptorCollector: IrElementVisitorVoidWithContext() { inner class DescriptorCollector: IrElementVisitorVoid {
override fun visitElement(element: IrElement) { override fun visitElement(element: IrElement) {
element.acceptChildren(this, null) element.acceptChildren(this, null)
@@ -80,14 +81,14 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
override fun visitClassNew(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.visitClassNew(declaration) super.visitClass(declaration)
val constructors = oldDescriptor.constructors.map { oldConstructorDescriptor -> val constructors = oldDescriptor.constructors.map { oldConstructorDescriptor ->
descriptorSubstituteMap[oldConstructorDescriptor] as ClassConstructorDescriptor descriptorSubstituteMap[oldConstructorDescriptor] as ClassConstructorDescriptor
@@ -112,51 +113,50 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
private fun copyPropertyOrField(oldDescriptor: PropertyDescriptor) { override fun visitProperty(declaration: IrProperty) {
val newDescriptor = copyPropertyDescriptor(oldDescriptor)
descriptorSubstituteMap[oldDescriptor] = newDescriptor
oldDescriptor.getter?.let {
descriptorSubstituteMap[it] = newDescriptor.getter!!
}
oldDescriptor.setter?.let {
descriptorSubstituteMap[it] = newDescriptor.setter!!
}
}
//---------------------------------------------------------------------//
override fun visitPropertyNew(declaration: IrProperty) {
copyPropertyOrField(declaration.descriptor) copyPropertyOrField(declaration.descriptor)
super.visitProperty(declaration)
super.visitPropertyNew(declaration)
} }
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
override fun visitFieldNew(declaration: IrField) { override fun visitField(declaration: IrField) {
val oldDescriptor = declaration.descriptor val oldDescriptor = declaration.descriptor
if (descriptorSubstituteMap[oldDescriptor] == null) { if (descriptorSubstituteMap[oldDescriptor] == null) {
// A field without a property or a field of a delegated property. copyPropertyOrField(oldDescriptor) // A field without a property or a field of a delegated property.
copyPropertyOrField(oldDescriptor)
} }
super.visitField(declaration)
super.visitFieldNew(declaration)
} }
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
override fun visitFunctionNew(declaration: IrFunction) { override fun visitFunction(declaration: IrFunction) {
val oldDescriptor = declaration.descriptor val oldDescriptor = declaration.descriptor
if (oldDescriptor !is PropertyAccessorDescriptor) { // Property accessors are copied along with their property. if (oldDescriptor !is PropertyAccessorDescriptor) { // Property accessors are copied along with their property.
val newDescriptor = copyFunctionDescriptor(oldDescriptor) val newDescriptor = copyFunctionDescriptor(oldDescriptor)
descriptorSubstituteMap[oldDescriptor] = newDescriptor descriptorSubstituteMap[oldDescriptor] = newDescriptor
} }
super.visitFunction(declaration)
}
super.visitFunctionNew(declaration) //---------------------------------------------------------------------//
override fun visitVariable(declaration: IrVariable) {
val oldDescriptor = declaration.descriptor
val oldContainingDeclaration = oldDescriptor.containingDeclaration
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
val newDescriptor = IrTemporaryVariableDescriptorImpl(
containingDeclaration = newContainingDeclaration,
name = generateCopyName(oldDescriptor.name),
outType = substituteType(oldDescriptor.type)!!,
isMutable = oldDescriptor.isVar)
descriptorSubstituteMap[oldDescriptor] = newDescriptor
super.visitVariable(declaration)
} }
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
@@ -165,9 +165,9 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
val oldDescriptor = expression.descriptor as FunctionDescriptor val oldDescriptor = expression.descriptor as FunctionDescriptor
if (oldDescriptor is SimpleFunctionDescriptor) { if (oldDescriptor is SimpleFunctionDescriptor) {
val containingDeclaration = (targetScope.scope.scopeOwner as? CallableDescriptor) ?: oldDescriptor val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldDescriptor, oldDescriptor)
val newReturnType = substituteType(oldDescriptor.returnType)!! val newReturnType = substituteType(oldDescriptor.returnType)!!
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, containingDeclaration) val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, newContainingDeclaration as CallableDescriptor)
val newDescriptor = oldDescriptor val newDescriptor = oldDescriptor
.newCopyBuilder() .newCopyBuilder()
.setReturnType(newReturnType) .setReturnType(newReturnType)
@@ -180,21 +180,6 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
super.visitCall(expression) super.visitCall(expression)
} }
//---------------------------------------------------------------------//
override fun visitVariable(declaration: IrVariable) {
val oldDescriptor = declaration.descriptor
val newDescriptor = IrTemporaryVariableDescriptorImpl(
containingDeclaration = targetScope.scope.scopeOwner,
name = generateCopyName(oldDescriptor.name),
outType = substituteType(oldDescriptor.type)!!,
isMutable = oldDescriptor.isVar)
descriptorSubstituteMap[oldDescriptor] = newDescriptor
super.visitVariable(declaration)
}
//--- Copy descriptors ------------------------------------------------// //--- Copy descriptors ------------------------------------------------//
private fun generateCopyName(name: Name): Name { private fun generateCopyName(name: Name): Name {
@@ -219,8 +204,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
private fun copySimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor) : FunctionDescriptor { private fun copySimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor) : FunctionDescriptor {
val newContainingDeclaration = parentScope?.let { descriptorSubstituteMap[it.scope.scopeOwner] } ?: targetScope.scope.scopeOwner val oldContainingDeclaration = oldDescriptor.containingDeclaration
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
return SimpleFunctionDescriptorImpl.create( return SimpleFunctionDescriptorImpl.create(
/* containingDeclaration = */ newContainingDeclaration, /* containingDeclaration = */ newContainingDeclaration,
/* annotations = */ oldDescriptor.annotations, /* annotations = */ oldDescriptor.annotations,
@@ -230,7 +215,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
).apply { ).apply {
val oldDispatchReceiverParameter = oldDescriptor.dispatchReceiverParameter val oldDispatchReceiverParameter = oldDescriptor.dispatchReceiverParameter
val newDispatchReceiverParameter = oldDispatchReceiverParameter?.let { descriptorSubstituteMap[it] as ReceiverParameterDescriptor } val newDispatchReceiverParameter = oldDispatchReceiverParameter?.let { descriptorSubstituteMap.getOrDefault(it, it) as ReceiverParameterDescriptor }
val newTypeParameters = oldDescriptor.typeParameters // TODO substitute types val newTypeParameters = oldDescriptor.typeParameters // TODO substitute types
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, this) val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, this)
val newReceiverParameterType = substituteType(oldDescriptor.extensionReceiverParameter?.type) val newReceiverParameterType = substituteType(oldDescriptor.extensionReceiverParameter?.type)
@@ -254,9 +239,10 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
private fun copyConstructorDescriptor(oldDescriptor: ConstructorDescriptor) : FunctionDescriptor { private fun copyConstructorDescriptor(oldDescriptor: ConstructorDescriptor) : FunctionDescriptor {
val containingDeclaration = parentScope?.let { descriptorSubstituteMap[it.scope.scopeOwner] } as ClassDescriptor val oldContainingDeclaration = oldDescriptor.containingDeclaration
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
return ClassConstructorDescriptorImpl.create( return ClassConstructorDescriptorImpl.create(
/* containingDeclaration = */ containingDeclaration, /* containingDeclaration = */ newContainingDeclaration as ClassDescriptor,
/* annotations = */ oldDescriptor.annotations, /* annotations = */ oldDescriptor.annotations,
/* isPrimary = */ oldDescriptor.isPrimary, /* isPrimary = */ oldDescriptor.isPrimary,
/* source = */ oldDescriptor.source /* source = */ oldDescriptor.source
@@ -282,11 +268,26 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
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!!
}
}
//---------------------------------------------------------------------//
private fun copyPropertyDescriptor(oldDescriptor: PropertyDescriptor): PropertyDescriptor { private fun copyPropertyDescriptor(oldDescriptor: PropertyDescriptor): PropertyDescriptor {
val memberOwner = currentClass?.let { descriptorSubstituteMap[it.scope.scopeOwner] } as ClassDescriptor val oldContainingDeclaration = oldDescriptor.containingDeclaration
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration) as ClassDescriptor
return PropertyDescriptorImpl.create( return PropertyDescriptorImpl.create(
/* containingDeclaration = */ memberOwner, /* containingDeclaration = */ newContainingDeclaration,
/* annotations = */ oldDescriptor.annotations, /* annotations = */ oldDescriptor.annotations,
/* modality = */ oldDescriptor.modality, /* modality = */ oldDescriptor.modality,
/* visibility = */ oldDescriptor.visibility, /* visibility = */ oldDescriptor.visibility,
@@ -305,7 +306,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
setType( setType(
/* outType = */ oldDescriptor.type, /* outType = */ oldDescriptor.type,
/* typeParameters = */ oldDescriptor.typeParameters, /* typeParameters = */ oldDescriptor.typeParameters,
/* dispatchReceiverParameter = */ memberOwner.thisAsReceiverParameter, /* dispatchReceiverParameter = */ newContainingDeclaration.thisAsReceiverParameter,
/* receiverType = */ oldDescriptor.extensionReceiverParameter?.type) /* receiverType = */ oldDescriptor.extensionReceiverParameter?.type)
initialize( initialize(
@@ -362,7 +363,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
val oldSuperClass = oldDescriptor.getSuperClassOrAny() val oldSuperClass = oldDescriptor.getSuperClassOrAny()
val newSuperClass = descriptorSubstituteMap.getOrDefault(oldSuperClass, oldSuperClass) as ClassDescriptor val newSuperClass = descriptorSubstituteMap.getOrDefault(oldSuperClass, oldSuperClass) as ClassDescriptor
val newContainingDeclaration = parentScope?.let { descriptorSubstituteMap[it.scope.scopeOwner] } ?: targetScope.scope.scopeOwner val oldContainingDeclaration = oldDescriptor.containingDeclaration
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
val newName = if (DescriptorUtils.isAnonymousObject(oldDescriptor)) // Anonymous objects are identified by their name. val newName = if (DescriptorUtils.isAnonymousObject(oldDescriptor)) // Anonymous objects are identified by their name.
oldDescriptor.name // We need to preserve it for LocalDeclarationsLowering. oldDescriptor.name // We need to preserve it for LocalDeclarationsLowering.
else else
@@ -95,7 +95,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
private class Inliner(val currentScope: ScopeWithIr, val context: Context) { private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
val copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope, context) // Create DeepCopy for current scope. val copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope.scope.scopeOwner, context) // Create DeepCopy for current scope.
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//