backend: implement copying IR tree with variable declarations
This commit is contained in:
committed by
SvyatoslavScherbina
parent
6e17507cde
commit
62d5f69ef0
+59
@@ -0,0 +1,59 @@
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
||||
|
||||
/**
|
||||
* Copies IR tree with descriptors of all declarations inside;
|
||||
* updates the references to these declarations.
|
||||
*/
|
||||
open class DeepCopyIrTreeWithDeclarations : DeepCopyIrTree() {
|
||||
|
||||
private fun DeclarationDescriptor.notSupported(): Nothing = TODO("${this}")
|
||||
|
||||
override fun mapModuleDescriptor(descriptor: ModuleDescriptor) = descriptor.notSupported()
|
||||
override fun mapPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor) = descriptor.notSupported()
|
||||
override fun mapClassDeclaration(descriptor: ClassDescriptor) = descriptor.notSupported()
|
||||
override fun mapTypeAliasDeclaration(descriptor: TypeAliasDescriptor) = descriptor.notSupported()
|
||||
override fun mapFunctionDeclaration(descriptor: FunctionDescriptor) = descriptor.notSupported()
|
||||
override fun mapConstructorDeclaration(descriptor: ClassConstructorDescriptor) = descriptor.notSupported()
|
||||
override fun mapPropertyDeclaration(descriptor: PropertyDescriptor) = descriptor.notSupported()
|
||||
override fun mapLocalPropertyDeclaration(descriptor: VariableDescriptorWithAccessors) = descriptor.notSupported()
|
||||
override fun mapEnumEntryDeclaration(descriptor: ClassDescriptor) = descriptor.notSupported()
|
||||
|
||||
val copiedVariables = mutableMapOf<VariableDescriptor, VariableDescriptor>()
|
||||
|
||||
override fun mapVariableDeclaration(descriptor: VariableDescriptor): VariableDescriptor {
|
||||
// TODO: how to ensure that the variable is not visible from outside of the transformed IR?
|
||||
|
||||
if (descriptor is VariableDescriptorWithAccessors && (descriptor.getter != null || descriptor.setter != null)) {
|
||||
TODO("$descriptor with accessors")
|
||||
}
|
||||
|
||||
val newDescriptor = LocalVariableDescriptor(
|
||||
/* containingDeclaration = */ descriptor.containingDeclaration,
|
||||
/* annotations = */ descriptor.annotations,
|
||||
/* name = */ descriptor.name,
|
||||
/* type = */ descriptor.type,
|
||||
/* mutable = */ descriptor.isVar,
|
||||
/* isDelegated = */ false,
|
||||
/* source = */ descriptor.source
|
||||
)
|
||||
|
||||
assert (descriptor !in copiedVariables)
|
||||
copiedVariables[descriptor] = newDescriptor
|
||||
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
// Note: the reference to a variable can be traversed only after the declaration of that variable,
|
||||
// so it is correct to map only references whose descriptors have copies.
|
||||
// However such approach can be incorrect when copying functions, classes etc.
|
||||
|
||||
override fun mapValueReference(descriptor: ValueDescriptor) =
|
||||
copiedVariables[descriptor] ?: descriptor
|
||||
|
||||
override fun mapVariableReference(descriptor: VariableDescriptor) =
|
||||
copiedVariables[descriptor] ?: descriptor
|
||||
}
|
||||
Reference in New Issue
Block a user